[PATCH] Clock Adjustment Considered Harmful

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



          === Clock Adjustment Considered Harmful ===

Clock adjustment at the time of boot is of rather dubious value.
With no synchronization source, writing the RTC can only increase
its entropy. The one possible benefit is that the BIOS may then
show the corrected "date". (I use quotes here since BIOS has no
notion of TZ or DST. Ahh the sophistication!) Multiboot setups
further complicate the matters. So. Let us put a stop to this
obsessive compulsive clock poking voodoo.

Let us save time and maintain accuracy by correcting the hctosys
operation. One may specify --noadjfile if that really is wanted.
The --adjust motion could be deprecated, or it could combine with
--hctosys. It could take an argument of minimum correction worth
writing back. Another worthwhile option would be --quick. This
would do away with syncing to tick boundary, trading precision for
faster operation.

This patch:
- compensate for drift when setting the system clock from rtc.

Signed-off-by: Kalev Soikonen <ksop@xxxxxx>
---
 hwclock/hwclock.c |   50 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/hwclock/hwclock.c b/hwclock/hwclock.c
index b249d10..bfc01d7 100644
--- a/hwclock/hwclock.c
+++ b/hwclock/hwclock.c
@@ -680,9 +680,23 @@ interpret_date_string(const char *date_o
 
 
 
+/*
 static int
-set_system_clock(const bool hclock_valid, const time_t newtime,
-                 const bool testing) {
+calc_adjustment2(const struct adjtime *adjtime_p, const time_t systime,
+                 struct timeval *ret) { ... }
+*/
+static void
+calculate_adjustment(const double factor,
+                     const time_t last_time,
+                     const double not_adjusted,
+                     const time_t systime,
+                     int *adjustment_p,
+                     double *retro_p);
+
+
+static int
+set_system_clock(const struct adjtime *adjtime_p, const bool hclock_valid,
+                 const time_t newtime, const bool testing) {
 /*----------------------------------------------------------------------------
    Set the System Clock to time 'newtime'.
 
@@ -712,6 +726,22 @@ set_system_clock(const bool hclock_valid
     tv.tv_sec = newtime;
     tv.tv_usec = 0;
 
+    if (adjtime_p->last_adj_time == 0) {
+      if (debug)
+	printf(_("Last adjustment time is undetermined, "
+	       "drift correction not possible.\n"));
+    } else {
+      int adjustment;
+      double fraction;
+      calculate_adjustment(adjtime_p->drift_factor,
+			   adjtime_p->last_adj_time,
+			   adjtime_p->not_adjusted,
+			   newtime,
+			   &adjustment, &fraction);
+      tv.tv_sec += adjustment;
+      tv.tv_usec = fraction * 1E6;
+    }
+
     broken = localtime(&newtime);
 #ifdef HAVE_TM_GMTOFF
     minuteswest = -broken->tm_gmtoff/60;		/* GNU extension */
@@ -983,6 +1013,7 @@ do_adjustment(struct adjtime *adjtime_p,
     adjtime_p->not_adjusted = 0;
     adjtime_p->dirty = TRUE;
   } else if (adjtime_p->last_adj_time == 0) {
+    /* ??? this printf */
     if (debug)
       printf("Not setting clock because last adjustment time is zero, "
 	     "so history is bad.");
@@ -1062,14 +1093,19 @@ manipulate_clock(const bool show, const 
     if (no_auth)
 	  return EX_NOPERM;
 
-    if (!noadjfile && (adjust || set || systohc || (!utc && !local_opt))) {
+    /* provide all defaults here? */
+    adjtime.last_adj_time = 0;
+    adjtime.dirty = FALSE;
+
+    /* Simple (!noadjfile) would be neat. Show operation could report
+       drift factor, estimated drift, offset to sys. time, etc.
+       */
+    if (!noadjfile && (!show || (!utc && !local_opt))) {
       rc = read_adjtime(&adjtime);
-      if (rc)
+      if (rc && (!hctosys || (!utc && !local_opt)))
 	      return rc;
     } else {
       /* A little trick to avoid reading the file if we don't have to */
-      adjtime.dirty = FALSE;
-      rc = 0;
     }
 
     {
@@ -1135,7 +1171,7 @@ manipulate_clock(const bool show, const 
             adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
                                 hclocktime, (double) read_time.tv_usec / 1E6);
         } else if (hctosys) {
-          rc = set_system_clock(hclock_valid, hclocktime, testing);
+          rc = set_system_clock(&adjtime, hclock_valid, hclocktime, testing);
           if (rc) {
             printf(_("Unable to set system clock.\n"));
 	    return rc;
-- 
1.4.2.1

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux