Package: adjtimex Version: 1.22-1 Severity: normal Tags: patch Hello,
Some adjtimex operations, like --compare and --adjust, do fail in the absence of the /etc/adjtime file. The documentation then suggests to create a zero adjfile containing a single "0.0 0 0.0" line. However there are situations where this file can't be created. And even if it can, it would be simpler to assume: No adjfile, RTC doesn't drift. The attached zero-adjfile.2.patch does automatically assume zero RTC drift when there is no /etc/adjtime. The README usage is rewritten accordingly, and updated. The Russian README.ru stays untouched. Additionally come attached 2 small cosmetic patches: - 1-7-weekdays.patch - interrupt-info.patch Alain.
adjtimex.c: In case of absence of /etc/adjtime, do not fail, and do not force users to manually create it with 0.0 content. Instead, proceed assuming zero values (meaning RTC does not drift). Also replace redundant code by a call to get_cmos_adjustment(). README: Rewrite USAGE paragraph. Remove point about creating zero adjfile. Document new behaviour without adjfile. Remove reference to the long outdated clock(8). Update URL for hwclock(8). Signed-off-by: Alain Guibert <[EMAIL PROTECTED]> diff -prud adjtimex-1.22.orig/README adjtimex-1.22/README --- adjtimex-1.22.orig/README Mon Sep 5 19:55:31 2005 +++ adjtimex-1.22/README Fri Oct 5 17:34:29 2007 @@ -54,13 +54,13 @@ change the time. USAGE -Create /etc/adjtime, which is used by clock(8) and hwclock(8) to -correct for systematic error in the RTC. Set it up as explained in -the man page for each program. clock is included (along with a lot of -other useful utilities) in Rik Faith's collection: -sunsite.unc.edu:pub/Linux/system/Misc/util-linux-1.10.tar.gz If your -RTC is already accurate enough to suit you, just create a file -/etc/adjtime containing as the first and only line: '0.0 0 0.0'. +The file /etc/adjtime is used to correct for systematic error in the +RTC. Set it up as explained in the man page for hwclock(8). Otherwise, +without /etc/adjtime, adjtimex assumes that the RTC is already perfect. +The latest version of hwclock(8) from Bryan Henderson can be found at +<URL:http://giraffe-data.com/software/about_hwclock.html>. An older +version is included (along with a lot of other useful utilities) in the +util-linux collection. I'll explain the manual procedure first. diff -prud adjtimex-1.22.orig/adjtimex.c adjtimex-1.22/adjtimex.c --- adjtimex-1.22.orig/adjtimex.c Fri Oct 5 11:50:27 2007 +++ adjtimex-1.22/adjtimex.c Fri Oct 5 16:39:16 2007 @@ -813,12 +813,9 @@ compare() { struct timex txc; time_t cmos_time; - time_t last_time; double cmos_sec, system_sec, dif, dif_prev = 0.; - FILE *adj; - double factor; + struct cmos_adj *pca = get_cmos_adjustment(); double cmos_adjustment; - double not_adjusted; int loops = 0; extern char *optarg; int wrote_to_log = 0; @@ -827,19 +824,6 @@ compare() probe_time(&hz, &tick_min, &tick_mid, &tick_max, &maxfreq); - - /* Read adjustment parameters first */ - if ((adj = fopen (ADJPATH, "r")) == NULL) - { - perror (ADJPATH); - exit (2); - } - if (fscanf (adj, "%lf %ld %lf", &factor, &last_time, ¬_adjusted) < 0) - { - perror (ADJPATH); - exit (2); - } - fclose (adj); #ifdef DEBUG /* cmos clock last adjusted at Tue Aug 26 11:43:57 1997 (= 872610237) @@ -849,17 +833,17 @@ cmos clock last adjusted at Tue Aug 26 1 struct tm bdt; if (universal) { - bdt = *gmtime(&last_time); + bdt = *gmtime(&pca->ca_adj_time); (void)mkgmtime(&bdt); /* set tzname */ } else { - bdt = *localtime(&last_time); + bdt = *localtime(&pca->ca_adj_time); (void)mktime(&bdt); /* set tzname */ } printf ("cmos clock last adjusted %.24s %s " "(= %ld)\n", - ctime(&last_time), tzname[tm.tm_isdst?1:0], (long) last_time); + ctime(&pca->ca_adj_time), tzname[tm.tm_isdst?1:0], (long) pca->ca_adj_time); } #endif @@ -900,22 +884,22 @@ cmos clock last adjusted at Tue Aug 26 1 printf (" current cmos time %.24s %s (= %ld)\n", asctime(&tm), tzname[tm.tm_isdst?1:0], (long) cmos_time); #endif - cmos_adjustment = ((double) (cmos_time - last_time)) - * factor / SECONDSPERDAY - + not_adjusted; + cmos_adjustment = ((double) (cmos_time - pca->ca_adj_time)) + * pca->ca_factor / SECONDSPERDAY + + pca->ca_remainder; cmos_sec = cmos_time + cmos_adjustment; #ifdef DEBUG printf ( " time since last adjustment %10.6f days (= %9d sec)\n", - (int) (cmos_time - last_time) / (double)SECONDSPERDAY, - (int) (cmos_time - last_time)); + (int) (cmos_time - pca->ca_adj_time) / (double)SECONDSPERDAY, + (int) (cmos_time - pca->ca_adj_time)); printf ( " factor %10.6f sec/day\n", - factor); + pca->ca_factor); printf ( " adjustment %10.6f + %7.6f = %7.6f sec\n", - ((double) (cmos_time - last_time))*factor/SECONDSPERDAY, - not_adjusted, cmos_adjustment); + ((double) (cmos_time - pca->ca_adj_time))*pca->ca_factor/SECONDSPERDAY, + pca->ca_remainder, cmos_adjustment); #endif dif = system_sec - cmos_sec; @@ -1388,26 +1372,31 @@ int valid_cmos_rate(double ftime_cmos, d return undisturbed_cmos; } + +/* + * Read informations from /etc/adjtime file. + * If file doesn't exist, return default zero values. + */ static struct cmos_adj *get_cmos_adjustment() { FILE *adj; static struct cmos_adj ca; - if ((adj = fopen (ADJPATH, "r")) == NULL) - { - perror (ADJPATH); - exit (2); - } - if (fscanf (adj, "%lf %ld %lf", - &ca.ca_factor, - &ca.ca_adj_time, - &ca.ca_remainder) < 0) + + ca.ca_factor = ca.ca_adj_time = ca.ca_remainder = 0; + if ((adj = fopen (ADJPATH, "r")) != NULL) { - perror (ADJPATH); - exit (2); + if (fscanf (adj, "%lf %ld %lf", + &ca.ca_factor, + &ca.ca_adj_time, + &ca.ca_remainder) < 0) + { + perror (ADJPATH); + exit (2); + } + fclose (adj); } - fclose (adj); #ifdef DEBUG - printf ("CMOS clock was last adjusted %s", ctime(&ca.ca_adj_time)); + printf ("CMOS clock was last adjusted %s\n", ctime(&ca.ca_adj_time)); #endif return &ca; }
The day-of-week value in the RTC free cycles from 1 to 7. This number is not synced with other RTC date values, but is only simply incremented at midnight. The day meant is in the eye of the reader, which nearly always just ignores the value. Most common assumption is that 1 means Sunday. Signed-off-by: Alain Guibert <[EMAIL PROTECTED]> diff -prud adjtimex-1.22.orig/adjtimex.c adjtimex-1.22/adjtimex.c --- adjtimex-1.22.orig/adjtimex.c Fri Oct 5 11:50:27 2007 +++ adjtimex-1.22/adjtimex.c Fri Oct 5 19:48:11 2007 @@ -685,8 +685,8 @@ cmos_read_time (time_t *cmos_timep, doub } while (tm.tm_sec != cmos_read_bcd (0)); - tm.tm_mon--; /* DOS uses 1 base */ - tm.tm_wday -= 3; /* DOS uses 3 - 9 for week days */ + tm.tm_mon--; /* RTC uses 1 base */ + tm.tm_wday -= 1; /* RTC uses 1 - 7 for week days, 1 for Sunday */ if ((tm.tm_year += (epoch - 1900)) <= 69) tm.tm_year += 100;
rename dummy to interrupt_info now that this read() value is actually used. Signed-off-by: Alain Guibert <[EMAIL PROTECTED]> diff -prud adjtimex-1.22.orig/adjtimex.c adjtimex-1.22/adjtimex.c --- adjtimex-1.22.orig/adjtimex.c Fri Oct 5 11:50:27 2007 +++ adjtimex-1.22/adjtimex.c Fri Oct 5 19:48:11 2007 @@ -641,11 +641,11 @@ cmos_read_time (time_t *cmos_timep, doub busy_wait(&now); } { - unsigned long dummy; + unsigned long interrupt_info; int type, count; do { - rc = read(cmos_fd, &dummy, sizeof(dummy)); + rc = read(cmos_fd, &interrupt_info, sizeof(interrupt_info)); gettimeofday(&now, NULL); if (rc == -1) @@ -653,8 +653,8 @@ cmos_read_time (time_t *cmos_timep, doub perror("read() from /dev/rtc to wait for clock tick failed"); exit(1); } - type = (int)(dummy&0xff); - count = (int)(dummy>>8); + type = (int)(interrupt_info & 0xff); + count = (int)(interrupt_info >> 8); } while ((type==0)||(count>1)); /* The low-order byte holds the interrupt type. The first read may succeed immediately, but in that case the byte is zero, so we