From: Harlan Stenn Date: Wed, 27 Jun 2007 06:15:24 +0000 (-0400) Subject: More leapsecond table file fixes from Dave Mills X-Git-Tag: NTP_4_2_5P56~2^2^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f581a86f9168a705bb9fe000657630d0da0f8987;p=thirdparty%2Fntp.git More leapsecond table file fixes from Dave Mills bk: 4682007cjtpYRIAInWDmt2ShnkYLJQ --- diff --git a/ChangeLog b/ChangeLog index c2703fae8..3043d11b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,9 @@ +* more leap second infrastructure fixes from Dave Mills. * [Bug 858] recent leapfile changes broke non-OpenSSL builds. * Use emalloc() instead of malloc() in refclock_datum.c (Calysto). * Start using 'design by contract' assertions. * [Bug 767] Fast sync to refclocks wanted. * Allow null driftfile. -* leap second infrastructure fixes from Dave Mills. * Use YYERROR_VERBOSE for the new parser, and fix related BUILT_SOURCES. * [Bug 629] changes to ensure broadcast works including on wildcard addresses * [Bug 853] get_node() must return a pointer to maximally-aligned memory. diff --git a/include/ntpd.h b/include/ntpd.h index 579f75b93..1a76d92ba 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -183,6 +183,7 @@ extern void process_packet (struct peer *, struct pkt *); extern void clock_select (void); extern void kod_proto (void); extern u_long leap_ins; +extern u_long leap_expire; extern u_long leap_sec; /* diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index ef7d73fed..1627d6528 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -3746,6 +3746,7 @@ crypto_tai( FILE *str; /* file handle */ char buf[NTP_MAXSTRLEN]; /* file line buffer */ u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */ + u_long expire; /* NTP time when file expires */ int offset; /* offset at leap (s) */ char filename[MAXFILENAME]; /* name of leapseconds file */ char linkname[MAXFILENAME]; /* file link (for filestamp) */ @@ -3796,7 +3797,8 @@ crypto_tai( * must equal the initial insertion of ten seconds on 1 January * 1972 plus one second for each succeeding insertion. */ - i = 0; + i = TAI_1972; + expire = 0; while (i < MAX_LEAP) { dp = fgets(buf, NTP_MAXSTRLEN - 1, str); if (dp == NULL) @@ -3805,13 +3807,19 @@ crypto_tai( if (strlen(buf) < 1) continue; - if (*buf == '#') - continue; + if (buf[0] == '#') { + if (buf[1] == '@') { + if (sscanf(&buf[2], "%lu", &expire) != + 1) + break; + } + } + continue; if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2) continue; - if (i != offset - TAI_1972) + if (i != offset) break; i++; @@ -3834,9 +3842,13 @@ crypto_tai( tai_leap.ptr = (u_char *)ptr; for (j = 0; j < i; j++) *ptr++ = htonl(leapsec[j]); + sys_tai = offset; + leap_ins = leapsec[--j]; + leap_expire = expire; crypto_flags |= CRYPTO_FLAG_TAI; - sprintf(statstr, "%s fs %u leap %u len %u", cp, fstamp, - leapsec[--j], len); + sprintf(statstr, + "%s fs %u leap %lu tai %d expire %lu len %u", cp, + fstamp, leap_ins, sys_tai, leap_expire, len); record_crypto_stats(NULL, statstr); #ifdef DEBUG if (debug) diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index a1b5f8ab0..da17e3b1c 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -67,6 +67,7 @@ double sys_jitter; /* system jitter (s) */ static int sys_hopper; /* anticlockhop counter */ static int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */ u_long leap_ins; /* seconds at next leap */ +u_long leap_expire; /* seconds leapfile expires */ u_long leap_sec; /* leap countdown */ static int leap_next; /* leap consensus */ static int leap_sw; /* leap is from file */ @@ -1314,9 +1315,7 @@ clock_update(void) * Clock was slewed. Update the system stratum, leap bits, root * delay, root dispersion, reference ID and reference time. * Except for reference clocks, the minimum dispersion increment - * is not less than sys_mindisp. If a leap is anticipated, read - * the system clock because the time now might not be the time - * at the last offset measurement. + * is not less than sys_mindisp. */ case 1: sys_stratum = min(sys_peer->stratum + 1, @@ -1324,49 +1323,54 @@ clock_update(void) sys_reftime = sys_peer->rec; /* - * If no leap is scheduled and the leap is triggered - * from the leapseconds file, schedule a leap for the - * last entry in the file, but only if it is in the - * future. If triggered by upstream server leap bits and - * the number of bits is at least the sanity threshold, - * schedule a leap for the end of the current month. - * - * If the kernel code is available and enabled, pass the - * current TAI offset to the kernel. Note, if the leap - * hasn't been taken yet, decrement the offset. + * If a leapseconds file is not present or expired and + * the number of upstream server leap bits is at least + * the sanity threshold, schedule a leap for the end of + * the current month. */ get_systime(&now); - if (leap_sec == 0) { - if (leap_ins > now.l_ui) { - if (leap_sw == 0) { + if (now.l_ui > leap_expire) { + if (leap_next >= sys_minsane) { + if (!leap_sw) { leap_sw++; - sys_tai--; + leap_sec = leap_month(now.l_ui); msyslog(LOG_NOTICE, - "TAI offset %d s", sys_tai); -#ifdef KERNEL_PLL - if (pll_control && kern_enable) - loop_config(LOOP_LEAP, - 0); -#endif /* KERNEL_PLL */ + "leap second armed %lu s", + leap_sec); } - if (leap_ins - now.l_ui < 28 * 86400) - leap_sec = leap_ins - now.l_ui; - } else if (leap_next >= sys_minsane) { - leap_sec = leap_month(now.l_ui); + } else { + leap_sw = 0; + leap_sec = 0; } - if (leap_sec > 0) - msyslog(LOG_NOTICE, - "leap second armed %lu s", - leap_sec); - /* - * If the leap was not triggered from the leapsecond - * file, cancel the leap if the server leap bits grow - * dim. + * If a leapseconds file is present and not expired and + * a future leap is scheduled, decrement the TAI offset. + * If the kernel code is available and enabled, pass the + * TAI offset to the kernel. If less than 28 days remain + * to the leap, schedule a leap when the leapseconds + * counter expires. */ - } else if (!leap_sw && leap_next < sys_minsane) { - leap_sec = 0; + } else if (leap_sec == 0) { + if (leap_ins > now.l_ui) { + if (leap_ins - now.l_ui < 28 * 86400) { + leap_sec = leap_ins - now.l_ui; + msyslog(LOG_NOTICE, + "leap second armed %lu s", + leap_sec); + } + if (!leap_sw) + sys_tai--; + } + if (!leap_sw) { + leap_sw++; + msyslog(LOG_NOTICE, + "TAI offset %d s", sys_tai); +#ifdef KERNEL_PLL + if (pll_control && kern_enable) + loop_config(LOOP_LEAP, 0); +#endif /* KERNEL_PLL */ + } } /* diff --git a/ntpd/ntp_util.c b/ntpd/ntp_util.c index 397bbe2aa..40d52fe26 100644 --- a/ntpd/ntp_util.c +++ b/ntpd/ntp_util.c @@ -757,12 +757,14 @@ leap_file( FILE *str; /* file handle */ char buf[NTP_MAXSTRLEN]; /* file line buffer */ u_long leapsec; /* NTP time at leap */ + u_long expire; /* NTP time when file expires */ int offset; /* TAI offset at leap (s) */ char filename[MAXFILENAME]; /* name of leapseconds file */ char *dp; int i; NTP_REQUIRE(cp != NULL); + /* * Open the file and discard comment lines. If the first * character of the file name is not '/', prepend the keys @@ -786,6 +788,7 @@ leap_file( * insertion. */ i = TAI_1972; + expire = 0; while (i < MAX_TAI) { dp = fgets(buf, NTP_MAXSTRLEN - 1, str); if (dp == NULL) @@ -794,8 +797,14 @@ leap_file( if (strlen(buf) < 1) continue; - if (*buf == '#') - continue; + if (buf[0] == '#') { + if (buf[1] == '@') { + if (sscanf(&buf[2], "%lu", &expire) != + 1) + break; + } + } + continue; if (sscanf(buf, "%lu %d", &leapsec, &offset) != 2) continue; @@ -806,13 +815,14 @@ leap_file( } fclose(str); if (dp != NULL) { - msyslog(LOG_INFO, "leapseconds format error from %s", - cp); + msyslog(LOG_INFO, "leapseconds %s error", cp); } else { sys_tai = offset; leap_ins = leapsec; - msyslog(LOG_INFO, "TAI offset %d s at %lu from %s", - sys_tai, leap_ins, cp); + leap_expire = expire; + msyslog(LOG_INFO, + "TAI offset %d s at %lu file %s expire %lu", + sys_tai, leap_ins, cp, leap_expire); } }