[arch-dev-public] [testing] util-linux heads-up

Dave Reisner d at falconindy.com
Mon Sep 10 06:56:18 EDT 2012


On Sep 10, 2012 3:48 AM, "Lukas Jirkovsky" <l.jirkovsky at gmail.com> wrote:
>
> On 8 September 2012 15:33, Dave Reisner <d at falconindy.com> wrote:
> >
> > One last bug about hwclock [1] is still outstanding, but I'm not able to
> > reproduce it. I'm still unconvinced of whether it's a legit bug in
> > hwclock or just something we need to fix in initscripts, but I've
> > forwarded the bug onto the util-linux ML to see if I can get input from
> > elsewhere.
> >
> > Cheers,
> > Dave
> >
> > [1] https://bugs.archlinux.org/task/31416
> >
>
> Falconindy, you're going to kill me.

Yup.

Today I realized that I unset
> HARDWARECLOCK in rc.conf yesterday, which made it look like it works
> due to the use of hwclock daemon. Instead the hwclock wasn't run
> during startup at all. So the problem is still here.
>
> This time, however, I have a fix for that. It works, although I'm not
> sure whether it's a correct fix.

Its not.

There's some strange problem with
> "hwclock --systz" which looks like it doesn't set the time zone
> correctly, but it can be fixed by using "hwclock --hctosys" instead
> (see attached patch).
>
> I just found out about the --debug switch to hwclock at it does print
> some interesting info (the output is at the end of this email). Note
> the "Calling settimeofday" output, especially the "tz.tz_minuteswest".
> This is completely utterly wrong according to "man 2 settimeofday":
>
>     Under  Linux  there  are  some peculiar "warp clock"
>     semantics associated with the settimeofday() system
>     call if on the very first call (after booting) that has a
>     non-NULL tz argument, the tv argument is NULL and
>     the tz_minuteswest field is nonzero.  (The tz_dsttime
>     field should be zero for this case.)  In such a case it is
>     assumed that the CMOS clock is on local time, and that
>     it has to be incremented by this amount to get  UTC
>     system  time. No doubt it is a bad idea to use this feature.
>
> I have CMOS clock set to UTC. However, according to the documentation
> the hwclock causes system to think it uses local time. If I set
> tz_minuteswest in that call to zero manually, the error during mount
> disappears. However the "date" output is still incorrect. So I tried
> to change the settimeofday call according to the documentation. I
> other words, I forced tz_minuteswest to 0 in all calls in hwclock.c.
> And (surprisingly) it fixed this problem.

Very surprising that it does anything at all. I've asked upstream about
this and I've started looking at what the kernel does. I'm starting to
wonder if calling hwclock with --systz is ever a good idea when the user
wants to use the hwclock in UTC.

Here's what I think:

If UTC: do nothing. Do absolutely nothing at all. The hwclock maintains
itself from the bios clock and user land tools read TZ from /etc/localtime
or the environment. Everything should just work. Should...

If localtime: call hwclock --systz. This is the _one_ chance you get to do
any sort of warp adjustment and it must be done on the very first call of
settimeofday().

I don't believe calling hwclock with --hctosys is ever wanted on bootup.

Im on a bus right now and haven't tried this, so grain of salt and all
that. But, evidence points to this being the right thing to do.

>
> To sum, what I think happens here:
> prerequisites:
> * CMOS (hardware) time set to UTC
> * Time zone different from UTC, in my case its "Europe/Prague" (UTC + 2
hours)
>
> what is the problem:
> 1. hwclock calls settimeofday with tz_minuteswest = -120
> 2. due to tz_minuteswest being non-zero, kernel thinks the hardware
> clock is in local time and thus it sets its clock to UTC - 2 hours
> 3. a) the wrong kernel clock causes the "Superblock last write time is
> in the future." warnings.
>     b) and because kernel clock is UTC - 2, date shows "kernel time +
> 2" which resuts in showing the time for UTC-2+2, which is equal to UTC
> time.
>
> what should happen:
> 1. hwclock calls settimeofday with tz_minuteswest = 0
> 2. kernel knows the hardware clock is in UTC, and it sets its clock
> appropriately (ie to UTC)
> 3. now that the kernel clock is in UTC, date shows correctly UTC+2,
> ie. localtime
>
> Broken
> ---------
> # hwclock --utc --noadjfile
> Using /dev interface to clock.
> Assuming hardware clock is kept in UTC time.
> Waiting for clock tick...
> ...got clock tick
> Time read from Hardware Clock: 2012/09/10 06:19:46
> Hw clock time : 2012/09/10 06:19:46 = 1347257986 seconds since 1969
> Mon Sep 10 08:19:46 2012  -0.234800 seconds
>
> # date output
> Mon Sep 10 08:19:45 CEST 2012
>
> # hwclock --systz --debug
> hwclock from util-linux 2.22
> Last drift adjustment done at 1347212233 seconds after 1969
> Last calibration done at 1347212233 seconds after 1969
> Hardware clock is on UTC time
> Assuming hardware clock is kept in UTC time.
> Current system time: 1347257985 = 2012/09/10 06:19:45
> Calling settimeofday:
>         UTC: 2012/09/10 06:19:45
>         tv.tv_sec = 1347257985, tv.tv_usec = 784261
>         tz.tz_minuteswest = -120
>
> # date output
> Mon Sep 10 06:19:45 CEST 2012
>
> Working
> ----------
> #hwclock --utc --noadjfile
> Using /dev interface to clock.
> Assuming hardware clock is kept in UTC time.
> Waiting for clock tick...
> ...got clock tick
> Time read from Hardware Clock: 2012/09/10 06:22:24
> Hw clock time : 2012/09/10 06:22:24 = 1347258144 seconds since 1969
> Mon Sep 10 08:22:24 2012  -0.453554 seconds
>
> # date output
> Mon Sep 10 08:22:23 CEST 2012
>
> # hwclock --hctosys --debug
> hwclock from util-linux 2.22
> Using /dev interface to clock.
> Last drift adjustment done at 1347212233 seconds after 1969
> Last calibration done at 1347212233 seconds after 1969
> Hardware clock is on UTC time
> Assuming hardware clock is kept in UTC time.
> Waiting for clock tick...
> ...got clock tick
> Time read from Hardware Clock: 2012/09/10 06:22:25
> Hw clock time : 2012/09/10 06:22:25 = 1347258145 seconds since 1969
> Calling settimeofday:
>         tv.tv_sec = 1347258145, tv.tv_usec = 0
>         tz.tz_minuteswest = -120
>
> # date
> Mon Sep 10 08:22:25 CEST 2012
>
>
> /me hides
>
> Lukas


More information about the arch-dev-public mailing list