Re: [Bug 212265] New: clock_gettime(CLOCK_TAI, ...) should return an error when TAI has not been configured

From: Thomas Gleixner
Date: Fri Mar 26 2021 - 07:14:42 EST


Daphne,

On Sat, Mar 13 2021 at 17:44, bugzilla-daemon wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=212265

I'm leaving the text from the BZ entry untrimmed so everyone on Cc is on
the same page.

> In order for CLOCK_TAI to function properly, a program (usually ntpd)
> has to use the adjtimex family of system calls in order to tell the
> kernel what the difference is between TAI and UTC. ntpd will do this
> as long as it has been configured with a leap seconds file.
>
> Unfortunately, although the majority of distributions ship with a leap
> second file from the zoneinfo database, many or most of them (I have
> Arch here) do not configure ntpd to know about it, so ntpd does not
> set things up properly for CLOCK_TAI to work. Calling
> clock_gettime(CLOCK_TAI, ...) produces the same result as
> clock_gettime(CLOCK_REALTIME, ...), yielding UTC instead of the
> requested TAI.
>
> The result is that CLOCK_TAI, which one would usually wish to use to
> improve the correctness of a program’s date and time handling,
> produces utterly incorrect behaviours on the vast majority of boxes,
> unless the system administrator is conscientious enough to configure.

Yes, that's unfortunate, but pretty much historical behaviour and I fear
it's not really documented either.

> I would like to suggest that clock_gettime(CLOCK_TAI, ...) and friends
> should return an error (EINVAL? ENOTSUP?) when it would return the
> same as CLOCK_REALTIME, so that programs can detect when it’s not been
> set up correctly and either tell users to go and set up their leap
> second data file properly,

That would be a user visible change and might hit existing user space by
surprise, so that's not a necessarily a good option.

Of course it could be argued that a given kernel can return -ENOTSUP or
whatever is appropriate for any CLOCK id, but that really needs some
deep thoughts and analysis vs. eventual disruption.

> or try to improvise TAI on top of UTC using (at the cost of not being
> able to be accurate during leap seconds themselves), or both.

The problem with TAI is that the number of leapseconds which need to be
accounted for at a given date/time, i.e. when the machine boots, looks
simple but leap seconds are not predictable due to the non-linear
behaviour of earth rotation.

So we'd need to have an up-to-date leap seconds table:

https://www.ietf.org/timezones/data/leap-seconds.list

which is not rocket science, but there is this little spoilsport in that
file:

File expires on: 28 December 2021

and the kernel on it's own has no way to check for and retrieve an
up-to-date version. That's why it is delegated to user space.

No idea though why this is not enabled by default in distros when NTP is
on. Of course I did not notice because I had that entry in my
ntpd/chrony configs forever since we started to hack on it.

> A workaround for programs which want to detect when CLOCK_TAI is wrong is to
> try to detect when it hasn't been set up properly by getting both CLOCK_TAI and
> CLOCK_REALTIME and falling back to trying to emulate TAI on top of time_t when
> the difference between the tv_sec value is ≤ 1 second (not = 0, because it
> could happen that the first clock was checked at .00001 seconds before a whole
> second and the latter one at .00001 seconds after the whole second). But even
> that has edge cases — putting similar logic in the kernel could make it work
> correctly all the time.

adjtimex()/ntp_timex() allows you to read out tai_offset race
free. Whether that's a good answer is a different question.

My initial takeaway is that at least the documentation sucks.

I hope the NTP/TAI wizards have some more insight/opinions on this.

Thanks,

tglx