On 9 Jul, 2012, at 08:51 , Zefram wrote: > Nero Imhard wrote: >> Is that really the Unix way? I always thought that "proper" >> implementations didn't step back, but paused the time for a second at >> :59:59 (while still having subsequent calls of gettimeofday return >> increasing values by adding microseconds as needed).
A very long time ago (more than a quarter century) BSD Unix kernels had code in the kernel's time-reading logic which would record the time returned each time the clock was read, and which would ensure that a subsequent call to get the time would return a time at least one microsecond later than that returned previously. This code existed to cover up flaws in how the system extrapolated times between clock interrupts and in the implementation of adjtime(2), which otherwise would cause the clock to return times that did not always move forward. The original ntpd implementation running on those systems handled leap seconds by attempting to set the clock back one second, as close to :00:00 as it could arrange, by a call to settimeofday(2). settimeofday(2) had the side effect of resetting the internal variable holding the last time returned, so the backward time step the leap was implemented with was visible to time consumers. When they moved the leap second support into the kernel with the RFC 1305 interface, however, they apparently did the one second step back without resetting the internal variable, with the result that the step back was not as visible to consumers and the time returned to system calls would get stuck somewhere between 59:59 and 00:00 (depending on the time the last clock read before the leap had returned) for at least part of the second. Doing this, and documenting it as working that way, effectively turned a slightly tacky hack around a constrained and flawed clock implementation into a feature. I would hope most systems have not retained this behavior. Modern computers have much better hardware time sources, allowing an implementation to avoid the flaws that prompted the original hack, and demanding that time-reading system calls write the time returned into a shared variable is a distinctly SMP-unfriendly way to implement a function which otherwise could be done read-only and lock-free. > POSIX implies that the :59:60 second appears identical to the :00:00 > second; i.e., the clock steps back at the end of the leap second. > The NTP model (and practice of some implementations) says that the clock > should step back at the start of the leap second, making the :59:60 > second appear identical to the :59:59 second. In either case, if you > look only at the integer seconds portion of the clock then you could > interpret it as "paused", in that you get the same time_t value for a > period of two seconds rather than the usual one, while the time_t value > monotonically increased throughout. But if you look at the microseconds > from gettimeofday, you see the microseconds values [0,1000000) occur > twice in succession, depicting a repeat of a second rather than a pause > or an extra-long second. ntpd (with the ntp_adjtime(2) system call implemented) did indeed cause the system clock to pause, both the seconds and microseconds, during a leap second. Prof. Mills's most recent book, which is only a few years old, still documents it as working this way, though there is enough wrong with doing this that many systems may not do that any more (I hope). As ntpd essentially takes kernel timestamps and shoves them into packets, this behavior was also detectable by ntpd neighbors The unfortunate thing about the latter is that since ntpd the implementation was a little sleazy and ambiguous about what happened during a leap second, NTP, the on-the-wire protocol definition, was made similarly ambiguous. This did not have to be (as I realized when working through what was necessary to use standard NTP to keep non-POSIX "right" kernel time synchronized). While NTP-on-the-wire might replay the :59:59 timestamps over you can disambiguate which of these you are getting by noting that timestamps from the first time through :59:59 will have the leap second warning set while the timestamps from the second time through (i.e. the :59:60 timestamps) won't. The only defect with this is that there are actually two timestamps in each packet which require disambiguation, but only one leap second warning bit, so while you can determine with certainty which :59:59 one of the timestamps came from you still have to guess at the other. With a little bit more care in defining the protocol this could have been fixed. Dennis Ferguson _______________________________________________ LEAPSECS mailing list [email protected] http://six.pairlist.net/mailman/listinfo/leapsecs
