Re: New kernel interface for sys_tz and timewarp?

Arnd Bergmann
2019-08-14T08:31:52Z

On Wed, Aug 14, 2019 at 2:06 AM Theodore Y. Ts'o <tytso@mit.edu> wrote:
> On Tue, Aug 13, 2019 at 10:30:34AM -0700, Linus Torvalds wrote:
> >
> > I suspect the only actual _valid_ use in the kernel for a time zone
> > setting is likely for RTC clock setting, but even that isn't really
> > "global", as much as "per RTC".
>
> As I recall (and I may or may not have been original for the original
> sys_tz; it was many years ago, and my memories of 1992 are a bit
> fuzzy) the only reason why we added it was because x86 systems that
> were dual-booting with Windows had a RTC which ticked localtime, and
> originally, the system time was fetched from the RTC in early boot,
> and then when the timezone was set, the time would be warped so it
> would be correct.

I think this was the case from 1992 to commit 84e345e4e209 ("time,
Fix setting of hardware clock in NTP code") in 2013, when we started
taking the time warp into account during the periodic sync_cmos_clock()
call from kernel/time/ntp.c.

> Trying to use this for anything else is probably a bad idea, and in a
> world where we can have initrd's and reading the RTC gets done by
> userspace as opposed to kernel, it probably doesn't make any sence to
> keep it.

As Alexandre keeps pointing out, we really ought to do this from user
space, but in systemd today still relies on the kernel setting the
initial time using CONFIG_RTC_HCTOSYS, but this breaks e.g.
when the rtc driver itself is a loadable module.

From what I understand it would be easy for systemd to sync the
rtc to system time at boot and let distros disable CONFIG_RTC_HCTOSYS,
but it still has to do the initial settimeofday(NULL, tz) call to
ensure the correct offset is used for sync_hw_clock() in case
CONFIG_GENERIC_CMOS_UPDATE or CONFIG_RTC_SYSTOHC
are set (which they tend to be at the moment).

In the long run, a distro can decide to avoid this all, once these
bits come together:

- glibc stops passing the caller timezone argument to the kernel
- the distro kernel disables CONFIG_RTC_HCTOSYS,
CONFIG_RTC_SYSTOHC and CONFIG_GENERIC_CMOS_UPDATE
- systemd reads the RTC at boot and sets the system
time according to the configuration in /etc/localtime and /etc/adjtime
- systemd, ntp or something else in user space takes care of the periodic
rtc update, again taking configuration into account.

When someone mixes today's glibc/systemd/kernel with other
components past that migration, things can go wrong somewhat
annoying but non-fatal ways:
- Users that dual-boot with windows may have to force Windows
to set the RTC to UTC mode rather than setting Linux to
localtime.
- if neither the kernel not user space do the periodic RTC update,
it may be out of sync and cause a larger time jump after the
next boot time ntp synchronization

Creating a kernel interface for systemd to see or contol how the
11-minute update is done in the kernel would help part of that
transition.

Arnd