]> git.ipfire.org Git - thirdparty/util-linux.git/commit
hwclock: fix RTC read logic
authorJ William Piggott <elseifthen@gmx.com>
Sun, 30 Jul 2017 00:33:41 +0000 (20:33 -0400)
committerJ William Piggott <elseifthen@gmx.com>
Fri, 4 Aug 2017 12:53:44 +0000 (08:53 -0400)
commitee723d23524d8e170aae030bb7579b4fae5599df
tree5bb5a552b1c2161c0f2ec31ad8ec9904ccfdea0b
parenta218e2a83fb6c64103b0b33e233db019bede44e2
hwclock: fix RTC read logic

Over the past decade a few commits for a corner case problem
have left the RTC read branch in a bad place.

The problem was: when a corrupted RTC could not be read, then
it also could not be reset, because hwclock would error out
due to the RTC read failure.

2.15-rc1 commit 3b96a7a Aug  9 2008
2.19-rc1 commit 5606df5 Dec 29 2010
2.23-rc1 commit ab8f402 Mar 21 2013

The first fix was to ignore a synchronization timeout only for
the busywait branch.

Two and a half years later a commit describing the same problem
took a little more heavy-handed approach by ignoring all
synchronization failures and the RTC read after it, for both of
the RTC set functions.

Because the previous fix also ignored the select() branch timeout
it caused a bogus warning. The chosen workaround for that was to
only print the select() timeout message in debug mode (this is
reverted by another patch).

The problem with these fixes is that we cannot just ignore the
synchronization timeout like that, because then the drift
correction operations will be invalid. The original logic was
correct; we must exit when synchronization fails.

Another problem is that now there are statements between the
timing-critical synchronize-read-timestamp trio (which were
also in the wrong order, but that part of the problem goes
back further in history).

The solution is to skip the RTC read block completely for the
RTC set functions when not also using the --update-drift
option. If we are updating the drift correction factor during
a set function then we must synchronize and read the RTC.
Otherwise reading the RTC is not needed. Anyone trying to set
a corrupt RTC should not be using --update-drift, because the
resulting drift correction factor would be invalid.

Using this approach has the added benefit of significantly
reducing system shutdown time when not using --update-drift:

time ./hwclock --test --systohc; time ./hwclock-master --test --systohc
Test mode: clock was not changed

real    0m0.072s
user    0m0.066s
sys     0m0.003s
Test mode: clock was not changed

real    0m1.000s
user    0m0.169s
sys     0m0.005s

I've see differences as high as 1.518 seconds.

Signed-off-by: J William Piggott <elseifthen@gmx.com>
sys-utils/hwclock.c