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