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

Lukas Jirkovsky l.jirkovsky at gmail.com
Mon Sep 10 03:47:51 EDT 2012


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. 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. 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.

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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hwclock_fix.diff
Type: application/octet-stream
Size: 381 bytes
Desc: not available
URL: <http://mailman.archlinux.org/pipermail/arch-dev-public/attachments/20120910/716e7f04/attachment.obj>


More information about the arch-dev-public mailing list