Yo All! Greg is not on devel@ntpsec, and asked me to cross post this for him.
See below. RGDS GARY --------------------------------------------------------------------------- Gary E. Miller Rellim 109 NW Wilmington Ave., Suite E, Bend, OR 97703 g...@rellim.com Tel:+1 541 382 8588 Veritas liberabit vos. -- Quid est veritas? "If you can't measure it, you can't improve it." - Lord Kelvin Begin forwarded message: Date: Fri, 13 Jan 2023 07:11:49 -0500 From: Greg Troxel <g...@lexort.com> To: "Gary E. Miller" <g...@rellim.com> Cc: gpsd dev <gpsd-...@nongnu.org>, <devel@ntpsec.org> Subject: Re: ✘64-bit time_t on glibc 2.34 and up "Gary E. Miller" <g...@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 :-)
To reduce spam only list members may post to this list. If you think that your messages are being rejected in error please contact devel-ow...@ntpsec.org.
--- Begin Message ---"Gary E. Miller" <g...@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 :-)
--- End Message ---
-------------------- End of forwarded message -------------------- -- Greg Troxel <g...@lexort.com>
pgpKOeOntFMh2.pgp
Description: OpenPGP digital signature
_______________________________________________ devel mailing list devel@ntpsec.org https://lists.ntpsec.org/mailman/listinfo/devel