gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ✘64-bit time_t on glibc 2.34 and up


From: Greg Troxel
Subject: Re: ✘64-bit time_t on glibc 2.34 and up
Date: Fri, 13 Jan 2023 07:11:49 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (berkeley-unix)

"Gary E. Miller" <gem@rellim.com> writes:

> Recent glibc (2.34 and up) and recent Linux kernels, allow 64 bit
> time_t on 32-bit Linux without much work.

Interesting to hear; I had assumed time_t on Linux was changed long ago
to int64_t.

> Extracted from include/ntpshm.h:
>
> struct shmTime
> {
>     int mode;
>     volatile int count;
>     time_t clockTimeStampSec;
>     int clockTimeStampUSec;
>     time_t receiveTimeStampSec;
>     int receiveTimeStampUSec;
>     int leap;                   // not leapsecond offset, a notification code
>     int precision;              // log(2) of source jitter
>     int nsamples;               // not used
>     volatile int valid;
>     unsigned        clockTimeStampNSec;     // Unsigned ns timestamps
>     unsigned        receiveTimeStampNSec;   // Unsigned ns timestamps
>     int             dummy[8];
> };
>
> Note the struct size depends on the size of an int, and the size of time_t.

Does Linux version syscalls?  In NetBSD, we change the codepoints when
the ABI changes, and there is kernel code to implement the old codepoint
(but no header support) so old binaries still work.  I think Solaris
does this too.

> This is no problem for newer musl on 32-bits. An int is 32-bits and
> time_t is 64.  Assuming all clients use the same version musl.
>
> This is a problem for glibc on 32 bits. And int is 32-bits, but time_t
> is a compile time option (32 or 64 bits).

I don't really follow "compile time option".  The size of time_t is part
of the kernel ABI.

Is it specified separately in the kernel sources and in whatever sources
lead to sys/types.h?  Or does the kernel use sys/types.h?   The headers
in sys are semantically part of the kernel, regardless of how they are
sliced up in packaging/maintenance.

shmTime is simply using time_t, so it inherits the definition of time_t
from the compilation environment.  POSIX says that <sys/time.h> is
required to define time_t:

  https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_time.h.html

so I think gpsd has to just assume that's true, and if there's a system
where the kernel size for time_t doesn't match the installed header,
that just needs to be fixed.

> How does ntpd know what size time_t to use? And thus know the size of
> shmTime?  How do we know portably, preserving backwards and forwards
> compatibility?

It builds against the installed headers and just uses time_t.

Of course binaries are not portable across systems with different
choices for time_t.  Those are different ABIs.

> In hindsight, maybe shmTime should have started with a 1 char version
> field,or magic field.  But, no such luck.

Probably time_t should have just been changed to int64_t, no option, and
syscalls should have been versioned so old binaries work :-)

It is true that e.g. on NetBSD a gpsd and an ntpd that were compiled on
opposite sides of the time_t type change (2012) will not interoperate.

> Options (for 32-bit only):
>
> 1.  Do nothing, stick with 32-bit time_t. Fail in 2038.

How do you "stick with it" if sys/time.h changes on systems configured
for int64_t?

> 2.  Allow 64-bit time_t and let incompatible ntpd fail.

How do you "allow"?

> 3.  Add run time options to gpsd and ntpd to specify time_t size.

That's crazy.

> 4.  gpsd and ntpd always use 64-bit time_t going forward.  Admin needs
> to mix and match.

How can you use a type different from what the kernel is using?

> 5.  1st process to open SHM(0) wins, the other process checks the size
> to know the contents.

That seems messy.

> 6.  Create a new way to pass time from gpsd to ntpd and chronyd.




> Also note, chrony sockets have a similar problem:
>
> #define SOCK_MAGIC 0x534f434b
> struct sock_sample {
>     struct timeval tv;
>     double offset;
>     int pulse;
>     int leap;       // notify that a leap second is upcoming
>     int _pad;
>     int magic;      // must be SOCK_MAGIC
> };
>
> Where timeval is:
>
> struct timeval {
>     time_t          tv_sec;
>     suseconds_t     tv_usec;
> };
> ```

Indeed, the int in ntpshm should be suseconds_t, but int is ok in
practice, on ILP32.  On IP16L32, it's not, but we aren't building for
PDP-11 any more :-)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]