[LEAPSECS] JD & MJD, UT1 & UTC

Zefram zefram at fysh.org
Wed Jan 4 06:56:53 EST 2017


Martin Burnicki wrote:
>Yes, but the advantage of a nonnormalized tv_nsec field is that it can
>be used with "legacy" structures

A non-normalised tm_sec has that advantage too.

>On the other hand, this may break existing applications which aren't
>aware that the number in tv_nsec can exceed 1000000000, so those might
>display strange timestamps. ;-)

Funny you should say that.  Just yesterday I noticed a problem with the
adjtimex(8) tool on my Debian system:

$ /sbin/adjtimex -p
         mode: 0
       offset: -436678
    frequency: 5752562
     maxerror: 214936
     esterror: 4374
       status: 8193
time_constant: 10
    precision: 1
    tolerance: 32768000
         tick: 9999
     raw time:  1483529963s 29863426us = 1483529963.29863426

Observe that the "raw time" field shows a fractional part in the tens
of millions of microseconds, amounting to nearly thirty seconds into
this second.  That's a highly non-normalised struct timeval.  Where the
tool tries to display the structure as a single scalar, the output is
inconsistent with the structure, treating the `microsecond' unit as if it
were instead 1e-8 s.  That part of the output arises from using a simple
"%d.%06d" printf format, with the latter field being overflowed by the
out-of-range microseconds value.

What's actually going on is that the tv_usec field isn't being used to
store a count of microseconds, but a count of *nano*seconds.  There's a
status flag STA_NANO, which is the 8192 part of the 8193 `status'
value, which indicates to sufficiently aware users of adjtimex(2) that
the time.tv_usec and offset fields are in nanoseconds rather than the
usual microseconds.  I've previously seen this flag on FreeBSD, so *my*
adjtimex(2)-using code handles it, but it was news to me that Linux has
adopted it.  Also news to the author of adjtimex(8), apparently.

I have to say, this is a bad way to futz with resolution of the system
call.  Unaware callers just go wrong, as seen above.  There's nothing
that signals that the flag bit can't just be ignored if not understood.
The resolution should have been specified by the caller, in the
mode-selection field.  Yes, it would mean kernel code to translate
between resolutions, but the kernel already has backcompat code for
many syscalls.  This would be milder than a lot of the backcompat code
that's already there.

-zefram


More information about the LEAPSECS mailing list