summaryrefslogtreecommitdiff
path: root/hwclock
diff options
context:
space:
mode:
authorPeter Tyser <ptyser@xes-inc.com>2010-12-29 16:25:43 -0600
committerKarel Zak <kzak@redhat.com>2010-12-31 00:31:30 +0100
commit5606df53d3997e3495d78f6ae6b9dd45c46861a2 (patch)
treef01c96e32472373a099610bdd31752bc9bc2092b /hwclock
parent3d6e5c355d10dcd9d6336331c96935013ffcd3b1 (diff)
downloadutil-linux-old-5606df53d3997e3495d78f6ae6b9dd45c46861a2.tar.gz
hwclock: allow setting of RTC when it contains invalid data
In some cases the date/time stored in an RTC can be corrupted, eg due to loss of power, before its been initially set, etc. When this occurs the RTC_RD_TIME ioctl can fail since the Linux kernel determines that the RTC contains invalid data. Currently, when setting an RTC using hwclock, hwclock performs a number of RTC_RD_TIME ioctls before setting the RTC. When one of these ioctls fails, hwclock bombs out and the corrupted RTC data can't be overwritten. Thus once an RTC is corrupted, it can't be fixed via hwclock*. To work around the above issue we can make hwclock not exit when a RTC_RD_TIME failure occurs during the process of setting the RTC. This allows the RTC to be set even when it contains an invalid value, although it is not synchronized to a clock tick before it is set. * 'hwclock --utc --noadjfile --set --date="11/23/10 17:19:00' currently works to fix a corrupted RTC, but a user couldn't determine this without digging through the source code. Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Diffstat (limited to 'hwclock')
-rw-r--r--hwclock/hwclock.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/hwclock/hwclock.c b/hwclock/hwclock.c
index 21a89c4e..279b672f 100644
--- a/hwclock/hwclock.c
+++ b/hwclock/hwclock.c
@@ -1180,12 +1180,24 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
if (show || adjust || hctosys || (!noadjfile && !systz && !predict)) {
/* data from HW-clock are required */
rc = synchronize_to_clock_tick();
- if (rc && rc != 2) /* 2= synchronization timeout */
+
+ /* 2 = synchronization timeout. We don't error out if the user is
+ attempting to set the RTC - the RTC could be functioning but
+ contain invalid time data so we still want to allow a user to set
+ the RTC time.
+ */
+
+ if (rc && rc != 2 && !set && !systohc)
return EX_IOERR;
gettimeofday(&read_time, NULL);
- rc = read_hardware_clock(universal, &hclock_valid, &hclocktime);
- if (rc)
- return EX_IOERR;
+
+ /* If we can't synchronize to a clock tick, we likely can't read
+ from the RTC so don't bother reading it again. */
+ if (!rc) {
+ rc = read_hardware_clock(universal, &hclock_valid, &hclocktime);
+ if (rc && !set && !systohc)
+ return EX_IOERR;
+ }
}
if (show) {