Package: util-linux
Version: 2.13.1.1-1
Severity: normal
Tags: patch

Hi,

when comparing with or setting the hardware clock hwclock should pay
attention to an ongoing correction. If the outstanding correction of the
system clock is more than a second, hwclock may calculate a wrong drift
of the hardware clock.

Bye, Jörg.

-- System Information:
Debian Release: unstable/experimental
  APT prefers unstable
  APT policy: (900, 'unstable'), (700, 'experimental')
Architecture: powerpc (ppc)

Kernel: Linux 2.6.29
Locale: LANG=C, LC_CTYPE=C (charmap=UTF-8) (ignored: LC_ALL set to de_DE.UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages util-linux depends on:
ii  libc6                  2.9-12            GNU C Library: Shared libraries
ii  libncurses5            5.7+20090510-1    shared libraries for terminal hand
ii  libselinux1            2.0.71-1          SELinux shared libraries
ii  libslang2              2.1.4-3           The S-Lang programming library - r
ii  libuuid1               1.41.5-1          universally unique id library
ii  lsb-base               3.2-22            Linux Standard Base 3.2 init scrip
ii  tzdata                 2009g-1           time zone and daylight-saving time
ii  zlib1g                 1:1.2.3.3.dfsg-13 compression library - runtime

util-linux recommends no packages.

Versions of packages util-linux suggests:
ii  dosfstools                    3.0.2-1    utilities for making and checking 
ii  kbd                           1.15-1     Linux console font and keytable ut
pn  util-linux-locales            <none>     (no description available)

-- no debconf information
--- hwclock.c+  2009-05-16 18:49:20.931695536 +0200
+++ hwclock.c   2009-05-16 19:49:42.411706841 +0200
@@ -490,6 +490,26 @@
 }
 
 
+static int
+gettimeofday_with_adjtime(struct timeval *tv, struct timezone *tz) {
+  struct timeval ongoing_correction;
+
+  const int rc = gettimeofday(tv, tz);
+  if (rc)
+      return rc;
+
+  if ( !adjtime(NULL, &ongoing_correction) ) {
+    tv->tv_sec += ongoing_correction.tv_sec;
+    tv->tv_usec += ongoing_correction.tv_usec;
+    if (tv->tv_usec >= 1000000) {
+      ++tv->tv_sec;
+      tv->tv_usec -= 1000000;
+    }
+  }
+
+  return rc;
+}
+
 
 static void
 set_hardware_clock_exact(const time_t sethwtime,
@@ -519,7 +539,7 @@
   struct timeval beginsystime, nowsystime;
 
  time_resync:
-  gettimeofday(&beginsystime, NULL);
+  gettimeofday_with_adjtime(&beginsystime, NULL);
   newhwtime = sethwtime + (int) time_diff(beginsystime, refsystime) + 1;
   if (debug)
     printf(_("Time elapsed since reference time has been %.6f seconds.\n"
@@ -534,7 +554,7 @@
    */
   do {
          float tdiff;
-         gettimeofday(&nowsystime, NULL);
+         gettimeofday_with_adjtime(&nowsystime, NULL);
          tdiff = time_diff(nowsystime, beginsystime);
          if (tdiff < 0)
                  goto time_resync;     /* probably time was reset */
@@ -1092,7 +1112,7 @@
              Defined only if hclock_valid is true.
              */
 
-        gettimeofday(&read_time, NULL);
+        gettimeofday_with_adjtime(&read_time, NULL);
         read_hardware_clock(universal, &hclock_valid, &hclocktime);
 
         if (show) {
@@ -1112,7 +1132,7 @@
              time, so we set it with reference to the most recent
              whole seconds time.
              */
-          gettimeofday(&nowtime, NULL);
+          gettimeofday_with_adjtime(&nowtime, NULL);
           reftime.tv_sec = nowtime.tv_sec;
           reftime.tv_usec = 0;
 
@@ -1315,7 +1335,7 @@
        char *date_opt;
 
        /* Remember what time we were invoked */
-       gettimeofday(&startup_time, NULL);
+       gettimeofday_with_adjtime(&startup_time, NULL);
 
 #ifdef HAVE_LIBAUDIT
        hwaudit_fd = audit_open();

Attachment: signature.asc
Description: Digital signature http://en.wikipedia.org/wiki/OpenPGP

Reply via email to