From: Harlan Stenn Date: Thu, 9 Apr 2009 08:44:58 +0000 (-0400) Subject: Mitigation and PPS cleanup from Dave Mills X-Git-Tag: NTP_4_2_5P162~1^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9010238356711fdfb63e434e5fa4a7ed98adcce6;p=thirdparty%2Fntp.git Mitigation and PPS cleanup from Dave Mills bk: 49ddb58auevn_N0PfnmIgoVl-tUVzw --- diff --git a/ChangeLog b/ChangeLog index 91466ac2c..948635e94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,10 @@ +* Mitigation and PPS cleanup from Dave Mills. (4.2.5p161) 2009/03/31 Released by Harlan Stenn * Documentation updates from Dave Mills. (4.2.5p160) 2009/03/30 Released by Harlan Stenn -* Include (4.2.4p7) +* [Bug 1141] refclock_report missing braces cause spurious "peer event: + clock clk_unspec" log entries +* Include (4.2.4p7-RC1) (4.2.5p159) 2009/03/28 Released by Harlan Stenn * "bias" changes from Dave Mills. (4.2.5p158) 2009/01/30 Released by Harlan Stenn @@ -211,8 +214,6 @@ --- (4.2.4p7-RC1) 2009/03/30 Released by Harlan Stenn -* [Bug 1141] refclock_report missing braces cause spurious "peer event: - clock clk_unspec" log entries * [Bug 873] Windows serial refclock proper TTY line discipline emulation * [Bug 1117] Deferred interface binding under Windows works only correctly if FORCE_DNSRETRY is defined diff --git a/include/ntpd.h b/include/ntpd.h index 345c7661c..b61bcad09 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -352,6 +352,7 @@ extern u_long last_time; /* time of last clock update (s) */ extern double last_offset; /* last clock offset (s) */ extern u_char allan_xpt; /* Allan intercept (log2 s) */ extern double clock_jitter; /* clock jitter (s) */ +extern double sys_offset; /* system offset (s) */ extern double sys_jitter; /* system jitter (s) */ /* ntp_monitor.c */ @@ -390,8 +391,6 @@ extern double sys_rootdisp; /* dispersion to primary source */ extern u_int32 sys_refid; /* reference id */ extern l_fp sys_reftime; /* last update time */ extern struct peer *sys_peer; /* current peer */ -extern struct peer *sys_pps; /* current PPS peer */ -extern struct peer *sys_prefer; /* cherished peer */ /* * Nonspecified system state variables. diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index dd5162da0..afca118c1 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -280,12 +280,8 @@ local_clock( * is most effective if the delays are highly assymetric and * clockhopping is avoided and the clock frequency wander is * relatively small. - * - * Note either there is no prefer peer or this update is from - * the prefer peer. */ - if (sys_huffpuff != NULL && (sys_prefer == NULL || sys_prefer == - peer)) { + if (sys_huffpuff != NULL) { if (peer->delay < sys_huffpuff[sys_huffptr]) sys_huffpuff[sys_huffptr] = peer->delay; if (peer->delay < sys_mindly) @@ -675,7 +671,7 @@ local_clock( #ifdef DEBUG if (debug) printf( - "local_clock: offset %.9f jit %.6f freq %.3f stab %.3f poll %d\n", + "local_clock: offset %.9f jit %.9f freq %.3f stab %.3f poll %d\n", clock_offset, clock_jitter, drift_comp * 1e6, clock_stability * 1e6, sys_poll); #endif /* DEBUG */ diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 17173a623..7fae54144 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -59,8 +59,6 @@ double sys_rootdisp; /* dispersion to primary source */ u_int32 sys_refid; /* reference id (network byte order) */ l_fp sys_reftime; /* last update time */ struct peer *sys_peer; /* current peer */ -struct peer *sys_pps; /* PPS peer */ -struct peer *sys_prefer; /* prefer peer */ /* * Rate controls. Leaky buckets are used to throttle the packet @@ -79,7 +77,7 @@ int sys_bclient; /* broadcast client enable */ double sys_bdelay; /* broadcast client default delay */ int sys_authenticate; /* requre authentication for config */ l_fp sys_authdelay; /* authentication delay */ -static double sys_offset; /* current local clock offset */ +double sys_offset; /* current local clock offset */ double sys_mindisp = MINDISPERSE; /* min disp increment (s) */ double sys_maxdist = MAXDISTANCE; /* selection threshold */ double sys_jitter; /* system jitter */ @@ -1459,7 +1457,6 @@ process_packet( LFPTOD(&ci, t34); p_offset = t34; } - p_del = peer->delay; /* * When calibration is complete and the clock is @@ -1470,14 +1467,11 @@ process_packet( */ if (peer->cast_flags & MDF_BCLNT) { peer->cast_flags &= ~MDF_BCLNT; - peer->bias = peer->offset - p_offset; -#ifdef DEBUG - if (debug) - printf( - "packet: bias %f uoffset %f boffset %f\n", - peer->bias, peer->offset, p_offset); -#endif + peer->delay = (peer->offset - p_offset) * 2; } + p_del = peer->delay; + p_offset += p_del / 2; + /* * Basic mode, otherwise known as the old fashioned way. @@ -1603,19 +1597,22 @@ clock_update( ) { double dtemp; - u_long epoch; l_fp now; #ifdef HAVE_LIBSCF_H char *fmri; #endif /* HAVE_LIBSCF_H */ /* - * There must be a system peer at this point. If we just changed - * the system peer, but have a newer sample from the old one, - * wait until newer data are available. Note that the root - * dispersion is updated even if the offset has already been - * processed. + * Update the remaining system state variables. */ + sys_peer = peer; + sys_epoch = peer->epoch; + sys_stratum = min(peer->stratum + 1, STRATUM_UNSPEC); + if (peer->stratum == STRATUM_REFCLOCK || + peer->stratum == STRATUM_UNSPEC) + sys_refid = peer->refid; + else + sys_refid = addr2refid(&peer->srcadr); dtemp = sys_jitter + fabs(sys_offset) + peer->disp + clock_phi * (current_time - peer->update); #ifdef REFCLOCK @@ -1627,18 +1624,16 @@ clock_update( dtemp = sys_mindisp; #endif /* REFCLOCK */ sys_rootdisp = dtemp + peer->rootdisp; - if (peer->epoch <= sys_epoch) - return; - - epoch = peer->epoch - sys_epoch; + sys_rootdelay = peer->delay + peer->rootdelay; + sys_reftime = peer->dst; + #ifdef DEBUG if (debug) printf( "clock_update: at %lu sample %lu associd %d\n", current_time, peer->epoch, peer->associd); #endif - sys_epoch = peer->epoch; - switch (local_clock(peer, epoch, sys_offset)) { + switch (local_clock(peer, peer->epoch, sys_offset)) { /* * Clock exceeds panic threshold. Life as we know it ends. @@ -1699,9 +1694,6 @@ clock_update( crypto_update(); #endif /* OPENSSL */ } - sys_stratum = min(peer->stratum + 1, STRATUM_UNSPEC); - sys_rootdelay = peer->delay + peer->rootdelay; - sys_reftime = peer->dst; /* * If the leapseconds values are from file or network @@ -2174,10 +2166,16 @@ clock_select(void) double high, low; double seljitter; double synch[NTP_MAXASSOC], error[NTP_MAXASSOC]; + double orphdist = 1e10;; struct peer *osys_peer = NULL; + struct peer *sys_prefer = NULL; /* prefer peer */ + struct peer *typesystem = NULL; + struct peer *typeorphan = NULL; +#ifdef REFCLOCK struct peer *typeacts = NULL; struct peer *typelocal = NULL; - struct peer *typesystem = NULL; + struct peer *typepps = NULL; +#endif /* REFCLOCK */ static int list_alloc = 0; static struct endpoint *endpoint = NULL; @@ -2192,9 +2190,6 @@ clock_select(void) * enough to handle all associations. */ osys_peer = sys_peer; - sys_peer = NULL; - sys_pps = NULL; - sys_prefer = NULL; osurv = sys_survivors; sys_survivors = 0; #ifdef LOCKCLOCK @@ -2246,26 +2241,42 @@ clock_select(void) if (peer_unfit(peer)) continue; -#ifdef REFCLOCK /* - * Don't allow the local clock or modem drivers - * in the kitchen at this point. Do that later, - * but only if nobody else is around. These guys - * are all configured, so we never throw them - * away. + * If this is an orphan, choose the one with + * the least distance. */ - if (peer->refclktype == REFCLK_LOCALCLOCK -#if defined(VMS) && defined(VMS_LOCALUNIT) - /* wjm: VMS_LOCALUNIT taken seriously */ - && REFCLOCKUNIT(&peer->srcadr) != - VMS_LOCALUNIT -#endif /* VMS && VMS_LOCALUNIT */ - ) { - typelocal = peer; + if (peer->stratum == sys_orphan) { + double ftemp; + + ftemp = addr2refid(&peer->srcadr); + if (ftemp < orphdist) { + typeorphan = peer; + orphdist = ftemp; + } continue; } - if (peer->refclktype == REFCLK_ACTS) { - typeacts = peer; +#ifdef REFCLOCK + /* + * The following are special cases. We deal + * with them later. + */ + switch (peer->refclktype) { + case REFCLK_LOCALCLOCK: + if (typelocal == NULL && + !(peer->flags & FLAG_PREFER)) + typelocal = peer; + continue; + + case REFCLK_ATOM_PPS: + if (typepps == NULL && + !(peer->flags & FLAG_PREFER)) + typepps = peer; + continue; + + case REFCLK_ACTS: + if (typeacts == NULL && + !(peer->flags & FLAG_PREFER)) + typeacts = peer; continue; } #endif /* REFCLOCK */ @@ -2411,13 +2422,12 @@ clock_select(void) continue; /* - * The order metric is formed from the stratum times - * max distance (1.) plus the root distance. It strongly - * favors the lowest stratum, but a higher stratum peer - * can capture the clock if the low stratum dominant - * hasn't been heard for awhile. + * The metric is the scaled root distance plus the peer + * stratum. For compliance with the specification, both + * values are multiplied by the select threshold. */ - d = root_distance(peer) + peer->stratum * sys_maxdist; + d = (root_distance(peer) / sys_maxdist + + peer->stratum) * sys_maxdist; if (j >= NTP_MAXASSOC) { if (d >= synch[j - 1]) continue; @@ -2440,39 +2450,40 @@ clock_select(void) nlist = j; /* - * If no survivors remain at this point, check if the local - * clock or modem drivers have been found. If so, nominate one - * of them as the only survivor. Otherwise, give up and leave - * the island to the rats. + * If no survivors remain at this point, check if the modem + * driver, orphan server or local driver have been found. If + * so, nominate the first one found as the only survivor. + * Otherwise, give up and leave the island to the rats. */ if (nlist == 0) { error[0] = 0; synch[0] = 0; + if (typeorphan != NULL) { + peer_list[0] = typeorphan; + nlist = 1; + } +#ifdef REFCLOCK if (typeacts != NULL) { peer_list[0] = typeacts; nlist = 1; } else if (typelocal != NULL) { peer_list[0] = typelocal; nlist = 1; - } else { - if (osys_peer != NULL) - report_event(EVNT_NOPEER, NULL, NULL); } +#endif /* REFCLOCK */ } /* - * We can only trust the survivors if the number of candidates - * sys_minsane is at least the number required to detect and - * cast out one falsticker. For the Byzantine agreement - * algorithm used here, that number is 4; however, the default - * sys_minsane is 1 to speed initial synchronization. Careful - * operators will tinker a higher value and use at least that - * number of synchronization sources. + * Mark the candidates at this point as truechimers. */ - for (i = 0; i < nlist; i++) + for (i = 0; i < nlist; i++) { peer_list[i]->status = CTL_PST_SEL_SELCAND; - if (nlist < sys_minsane) - return; +#ifdef DEBUG + if (debug > 1) + printf("select: survivor %s %f\n", + stoa(&peer_list[i]->srcadr), synch[i]); +#endif + } /* * Now, vote outlyers off the island by select jitter weighted @@ -2505,8 +2516,11 @@ clock_select(void) } } f = max(f, LOGTOD(sys_precision)); - if (nlist <= sys_minclock || f <= d || - peer_list[k]->flags & (FLAG_TRUE | FLAG_PREFER)) { + if (nlist <= sys_minsane || nlist <= sys_minclock) { + break; + + } else if (f <= d || peer_list[k]->flags & + (FLAG_TRUE | FLAG_PREFER)) { seljitter = f; break; } @@ -2554,104 +2568,103 @@ clock_select(void) j = i; if (peer->flags & FLAG_PREFER) sys_prefer = peer; -#ifdef REFCLOCK - if (peer->refclktype == REFCLK_ATOM_PPS) - sys_pps = peer; -#endif /* REFCLOCK */ } /* * Anticlockhop provisions. Ordinarily, use the first survivor - * on the list. However, if the previous system peer is on the - * list but not first, use it if the synchronization distance is - * not greater than the accumulation over the last sys_maxhop - * poll intervals. - */ - if (synch[j] < synch[0] + sys_mindisp + ULOGTOD(sys_poll) * - sys_maxhop * clock_phi) - typesystem = peer_list[j]; - else - typesystem = peer_list[0]; + * on the survivor list, if there is one, and if there are + * least sys_minsane survivors. Othersie, there are no + * survivors. However, if the previous system peer is on the + * list but not first, use it if the synchronization distance + * is not greater than the accumulation over the last + * sys_maxhop * poll intervals. Do this only if there are at + * least one kitten in the litter. + */ + if (nlist > 0 && nlist >= sys_minsane) { + if (synch[j] < synch[0] + sys_mindisp + + ULOGTOD(sys_poll) * sys_maxhop * clock_phi) + typesystem = peer_list[j]; + else + typesystem = peer_list[0]; + } /* - * Mitigation rules of the game. There are several types of - * peers that can be selected here: (1) orphan, (2) prefer peer - * (flag FLAG_PREFER) (3) pps peers (type REFCLK_ATOM_PPS), (4) - * the existing system peer, if any, and (5) the head of the - * survivor list. + * Mitigation rules of the game. We have the pick of the + * litter in typesystem if any survivors are left. If + * there is a prefer peer, use its offset and jitter. + * Otherwise, use the combined offset and jitter of all kitters. */ - if (typesystem->stratum == sys_orphan) { - sys_peer = typesystem; - sys_peer->status = CTL_PST_SEL_SYSPEER; - sys_offset = sys_peer->offset; - sys_refid = addr2refid(&sys_peer->srcadr); - sys_jitter = LOGTOD(sys_precision); + if (typesystem != NULL) { + if (sys_prefer == NULL) { + typesystem->status = CTL_PST_SEL_SYSPEER; + clock_combine(peer_list, sys_survivors); + sys_jitter = SQRT(SQUARE(typesystem->jitter) + + SQUARE(sys_jitter) + SQUARE(seljitter)); + } else { + typesystem = sys_prefer; + typesystem->status = CTL_PST_SEL_SYSPEER; + sys_offset = typesystem->offset; + sys_jitter = typesystem->jitter; + } #ifdef DEBUG - if (debug > 2) - printf("select: orphan offset %.6f\n", - sys_offset); + if (debug) + printf("select: combine offset %.9f jitter %.9f\n", + sys_offset, sys_jitter); #endif - } else if (sys_prefer) { + } +#ifdef REFCLOCK + /* + * If a PPS driver is lit and the combined offset is less than + * 0.4 s, select the driver as the PPS peer and use its offset + * and jitter. + */ + if (typepps != NULL && fabs(sys_offset < 0.4)) { + struct refclockproc *pp; /* - * If a pps peer is present, choose it; otherwise, - * choose the prefer peer. + * If flag1 is dim, PPS is enabled only if the prefer + * peer has survived the intersection algorithm and + * numbers the seconds. Otherwise, some other means + * must be provided to number the seconds. */ - if (sys_pps) { - sys_peer = sys_pps; - sys_peer->status = CTL_PST_SEL_PPS; - sys_offset = sys_peer->offset; -#ifdef DEBUG - if (debug > 2) - printf("select: pps offset %.6f\n", - sys_offset); -#endif - } else { - sys_peer = sys_prefer; - sys_peer->status = CTL_PST_SEL_SYSPEER; - sys_offset = sys_peer->offset; -#ifdef DEBUG - if (debug > 2) - printf("select: prefer offset %.6f\n", - sys_offset); -#endif - } - if (sys_peer->stratum == STRATUM_REFCLOCK || - sys_peer->stratum == STRATUM_UNSPEC) - sys_refid = sys_peer->refid; - else - sys_refid = addr2refid(&sys_peer->srcadr); - sys_jitter = sys_peer->jitter; - } else { + pp = typepps->procptr; + if (!(pp->sloppyclockflag & CLK_FLAG1) && sys_prefer == + NULL) + return; - /* - * Otherwise, choose the anticlockhopper. - */ - sys_peer = typesystem; - sys_peer->status = CTL_PST_SEL_SYSPEER; - clock_combine(peer_list, sys_survivors); - if (sys_peer->stratum == STRATUM_REFCLOCK || - sys_peer->stratum == STRATUM_UNSPEC) - sys_refid = sys_peer->refid; - else - sys_refid = addr2refid(&sys_peer->srcadr); - sys_jitter = SQRT(SQUARE(sys_peer->jitter) + - SQUARE(sys_jitter) + SQUARE(seljitter)); + typesystem = typepps; + typesystem->status = CTL_PST_SEL_PPS; + sys_offset = typesystem->offset; + sys_jitter = typesystem->jitter; #ifdef DEBUG - if (debug > 2) - printf("select: combine offset %.6f\n", - sys_offset); + if (debug) + printf("select: pps offset %.9f jitter %.9f\n", + sys_offset, sys_jitter); #endif } +#endif /* REFCLOCK */ /* - * We have found the alpha male. + * If there are no survivors at this point, there is no + * system peer. If so and this is an old update, keep the + * current statistics, but do not update the clock. */ - sys_peer->flags |= FLAG_SYSPEER; - if (osys_peer != sys_peer) { - report_event(PEVNT_NEWPEER, sys_peer, NULL); + if (typesystem == NULL) { + if (osys_peer != NULL) + report_event(EVNT_NOPEER, NULL, NULL); + sys_peer = NULL; + return; } - clock_update(sys_peer); + if (typesystem->epoch <= sys_epoch) + return; + + /* + * We have found the alpha male. Wind the clock. + */ + if (osys_peer != typesystem) + report_event(PEVNT_NEWPEER, typesystem, NULL); + typesystem->flags |= FLAG_SYSPEER; + clock_update(typesystem); } @@ -2691,13 +2704,10 @@ root_distance( /* * Careful squeak here. The value returned must be greater than * the minimum root dispersion in order to avoid clockhop with - * highly precise reference clocks. In orphan mode use the peer - * address to fool the mitigation algorithm. + * highly precise reference clocks. Note that the root distance + * cannot exceed the sys_maxdist, as this is the cutoff by the + * selection algorithm. */ - if (peer->stratum == sys_orphan) - return (addr2refid(&peer->srcadr) / FRAC * sys_maxdist / - 1.); - return ((peer->delay + peer->rootdelay) / 2 + peer->disp + peer->rootdisp + clock_phi * (current_time - peer->update) + peer->jitter); @@ -3448,7 +3458,6 @@ init_proto(void) sys_rootdisp = 0; L_CLR(&sys_reftime); sys_jitter = 0; - sys_peer = NULL; sys_precision = (s_char)default_get_precision(); get_systime(&dummy); sys_survivors = 0; diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index be3bfb051..94a428f28 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -332,13 +332,19 @@ timer(void) * reference ID the loopback address. */ if (sys_orphan < STRATUM_UNSPEC && sys_peer == NULL) { - if (sys_leap == LEAP_NOTINSYNC) + if (sys_leap == LEAP_NOTINSYNC) { sys_leap = LEAP_NOWARNING; +#ifdef OPENSSL + if (crypto_flags) + crypto_update(); +#endif /* OPENSSL */ + } sys_stratum = sys_orphan; if (sys_stratum > 1) sys_refid = htonl(LOOPBACKADR); else memcpy(&sys_refid, "LOOP", 4); + sys_offset = 0; sys_rootdelay = 0; sys_rootdisp = sys_mindisp; } diff --git a/ntpd/refclock_atom.c b/ntpd/refclock_atom.c index 980cc07fe..c3b278ca8 100644 --- a/ntpd/refclock_atom.c +++ b/ntpd/refclock_atom.c @@ -14,11 +14,12 @@ #include "ntp_refclock.h" #include "ntp_stdlib.h" -#if defined(REFCLOCK) && defined(CLOCK_ATOM) +/* + * This driver requires the PPSAPI interface (RFC 2783) + */ +#if defined(REFCLOCK) && defined(CLOCK_ATOM) && defined(HAVE_PPSAPI) -#ifdef HAVE_PPSAPI # include "ppsapi_timepps.h" -#endif /* HAVE_PPSAPI */ /* * This driver furnishes an interface for pulse-per-second (PPS) signals @@ -44,19 +45,6 @@ * the API with multiple PPS drivers and multiple handles per driver. If * the PPSAPI is normally implemented in the /usr/include/sys/timepps.h * header file and kernel support specific to each operating system. - * However, this driver can operate without this interface if means are - * proviced to call the pps_sample() routine from another driver. Please - * note; if the PPSAPI interface is present, it must be used. - * - * In many configurations a single port is used for the radio timecode - * and PPS signal. In order to provide for this configuration and others - * involving dedicated multiple serial/parallel ports, the driver first - * attempts to open the device /dev/pps%d, where %d is the unit number. - * If this fails, the driver attempts to open the device specified by - * the pps configuration command. If a port is to be shared, the pps - * command must be placed before the radio device(s) and the radio - * device(s) must be placed before the PPS driver(s) in the - * configuration file. * * This driver normally uses the PLL/FLL clock discipline implemented in * the ntpd code. Ordinarily, this is the most accurate means, as the @@ -67,29 +55,24 @@ * * Fudge Factors * - * If flag2 is dim (default), the on-time epoch is the assert edge of - * the PPS signal; if lit, the on-time epoch is the clear edge. If flag2 - * is lit, the assert edge is used; if flag3 is dim (default), the - * kernel PPS support is disabled; if lit it is enabled. The time1 - * parameter can be used to compensate for miscellaneous device driver - * and OS delays. + * If flag1 is dim (default) the PPS is active only if a prefer peer is + * preset; if lit the PPS is active as long as the system clock offset is + * synchronized and within 0.4 s. If flag2 is dim (default), the on-time + * epoch is the assert edge of the PPS signal; if lit, the on-time epoch + * is the clear edge. If flag3 is dim (default), the kernel PPS support + * is disabled; if lit it is enabled. The time1 parameter can be used to + * compensate for miscellaneous device driver and OS delays. */ /* * Interface definitions */ -#ifdef HAVE_PPSAPI #define DEVICE "/dev/pps%d" /* device name and unit */ -#endif /* HAVE_PPSAPI */ - #define PRECISION (-20) /* precision assumed (about 1 us) */ #define REFID "PPS\0" /* reference ID */ #define DESCRIPTION "PPS Clock Discipline" /* WRU */ #define NANOSECOND 1000000000 /* one second (ns) */ #define RANGEGATE 500000 /* range gate (ns) */ -static struct peer *pps_peer; /* atom driver for PPS sources */ - -#ifdef HAVE_PPSAPI /* * PPS unit control structure */ @@ -100,7 +83,6 @@ struct ppsunit { pps_info_t pps_info; /* last pps data */ pps_handle_t handle; /* pps handlebars */ }; -#endif /* HAVE_PPSAPI */ /* * Function prototypes @@ -108,37 +90,21 @@ struct ppsunit { static int atom_start (int, struct peer *); static void atom_poll (int, struct peer *); static void atom_shutdown (int, struct peer *); -#ifdef HAVE_PPSAPI -static void atom_control (int, struct refclockstat *, struct - refclockstat *, struct peer *); static void atom_timer (int, struct peer *); static int atom_ppsapi (struct peer *, int); -#endif /* HAVE_PPSAPI */ /* * Transfer vector */ -#ifdef HAVE_PPSAPI struct refclock refclock_atom = { atom_start, /* start up driver */ atom_shutdown, /* shut down driver */ atom_poll, /* transmit poll message */ - atom_control, /* fudge control */ + noentry, /* control (not used) */ noentry, /* initialize driver (not used) */ noentry, /* buginfo (not used) */ atom_timer, /* called once per second */ }; -#else /* HAVE_PPSAPI */ -struct refclock refclock_atom = { - atom_start, /* start up driver */ - atom_shutdown, /* shut down driver */ - atom_poll, /* transmit poll message */ - noentry, /* fudge control (not used) */ - noentry, /* initialize driver (not used) */ - noentry, /* buginfo (not used) */ - NOFLAGS /* not used */ -}; -#endif /* HAVE_PPPSAPI */ /* @@ -151,22 +117,18 @@ atom_start( ) { struct refclockproc *pp; -#ifdef HAVE_PPSAPI register struct ppsunit *up; char device[80]; int mode; -#endif /* HAVE_PPSAPI */ /* * Allocate and initialize unit structure */ - pps_peer = peer; pp = peer->procptr; peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; pp->stratum = STRATUM_UNSPEC; memcpy((char *)&pp->refid, REFID, 4); -#ifdef HAVE_PPSAPI up = emalloc(sizeof(struct ppsunit)); memset(up, 0, sizeof(struct ppsunit)); pp->unitptr = (caddr_t)up; @@ -191,18 +153,11 @@ atom_start( "refclock_atom: time_pps_create failed: %m"); return (0); } - - /* - * If the mode is nonzero, use that for the time_pps_setparams() - * mode; otherwise, PPS_CAPTUREASSERT. - */ - mode = peer->ttl; - if (mode == 0) + if (pp->sloppyclockflag & CLK_FLAG2) + mode = PPS_CAPTURECLEAR; + else mode = PPS_CAPTUREASSERT; return (atom_ppsapi(peer, mode)); -#else /* HAVE_PPSAPI */ - return (1); -#endif /* HAVE_PPSAPI */ } @@ -220,45 +175,14 @@ atom_shutdown( pp = peer->procptr; up = (struct ppsunit *)pp->unitptr; -#ifdef HAVE_PPSAPI if (up->fddev > 0) close(up->fddev); if (up->handle != 0) time_pps_destroy(up->handle); -#endif /* HAVE_PPSAPI */ - if (pps_peer == peer) - pps_peer = NULL; free(up); } -#ifdef HAVE_PPSAPI -/* - * atom_control - fudge control - */ -static void -atom_control( - int unit, /* unit (not used */ - struct refclockstat *in, /* input parameters (not uded) */ - struct refclockstat *out, /* output parameters (not used) */ - struct peer *peer /* peer structure pointer */ - ) -{ - struct refclockproc *pp; - int mode; - - pp = peer->procptr; - if (peer->ttl != 0) /* all legal modes must be nonzero */ - return; - - if (pp->sloppyclockflag & CLK_FLAG2) - mode = PPS_CAPTURECLEAR; - else - mode = PPS_CAPTUREASSERT; - atom_ppsapi(peer, mode); -} - - /* * Initialize PPSAPI */ @@ -315,10 +239,9 @@ atom_ppsapi( /* * atom_timer - called once per second * - * This routine is called once per second when the PPSAPI interface is - * present. It snatches the PPS timestamp from the kernel and saves the - * sign-extended fraction in a circular buffer for processing at the - * next poll event. + * This routine is called once per second. It snatches the PPS + * timestamp from the kernel and saves the sign-extended fraction in + * a circular buffer for processing at the next poll event. */ static void atom_timer( @@ -416,49 +339,6 @@ atom_timer( #endif return; } -#endif /* HAVE_PPSAPI */ - - -/* - * pps_sample - receive PPS data from some other clock driver - * - * This routine is called once per second when the external clock driver - * processes PPS information. It processes the PPS timestamp and saves - * the sign-extended fraction in a circular buffer for processing at the - * next poll event. This works only for a single PPS device. - * - * The routine should be used by another configured driver ONLY when - * this driver is configured as well and the PPSAPI is NOT in use. - */ -int -pps_sample( - l_fp *offset /* PPS offset */ - ) -{ - register struct peer *peer; - struct refclockproc *pp; - l_fp lftmp; - double doffset; - - peer = pps_peer; - if (peer == NULL) - return (1); - - pp = peer->procptr; - - /* - * Convert the timeval to l_fp and save for billboards. Sign- - * extend the fraction and stash in the buffer. No harm is done - * if previous data are overwritten. If the discipline comes bum - * or the data grow stale, just forget it. - */ - pp->lastrec = *offset; - L_CLR(&lftmp); - L_ADDF(&lftmp, pp->lastrec.l_f); - LFPTOD(&lftmp, doffset); - SAMPLE(-doffset + pp->fudgetime1); - return (0); -} /* @@ -473,46 +353,20 @@ atom_poll( struct refclockproc *pp; pp = peer->procptr; pp->polls++; - - /* - * Valid time is returned only if the prefer peer has survived - * the intersection algorithm and within 0.4 s of local time - * and not too long ago. This ensures the PPS time is within - * 0.5 s of the local time and the seconds numbering is - * unambiguous. Note that the leap bits, stratum and refid are - * set from the prefer peer, unless overriden by a fudge - * command. - */ - pps_enable = 0; + if (pp->sloppyclockflag & CLK_FLAG3) + pps_enable = 1; + else + pps_enable = 0; if (pp->codeproc == pp->coderecv) { refclock_report(peer, CEVNT_TIMEOUT); return; - - } else if (sys_prefer == NULL) { - pp->codeproc = pp->coderecv; + } + if (sys_leap == LEAP_NOTINSYNC) return; - } else if (fabs(sys_prefer->offset) >= 0.4) { - pp->codeproc = pp->coderecv; - return; - } - if (pp->sloppyclockflag & CLK_FLAG3) - pps_enable = 1; - pp->leap = sys_prefer->leap; - if (pp->stratum >= STRATUM_UNSPEC) - peer->stratum = sys_prefer->stratum; - else - peer->stratum = pp->stratum; pp->lastref = pp->lastrec; refclock_receive(peer); } #else int refclock_atom_bs; -int -pps_sample( - l_fp *offset /* PPS offset */ - ) -{ - return (1); -} #endif /* REFCLOCK */ diff --git a/ntpd/refclock_conf.c b/ntpd/refclock_conf.c index dc29d1e79..c046d012d 100644 --- a/ntpd/refclock_conf.c +++ b/ntpd/refclock_conf.c @@ -138,7 +138,7 @@ extern struct refclock refclock_nmea; #define refclock_nmea refclock_none #endif -#ifdef CLOCK_ATOM +#if defined (CLOCK_ATOM) && defined(HAVE_PPSAPI) extern struct refclock refclock_atom; #else #define refclock_atom refclock_none diff --git a/ntpd/refclock_local.c b/ntpd/refclock_local.c index ffc052c0a..1776b8af9 100644 --- a/ntpd/refclock_local.c +++ b/ntpd/refclock_local.c @@ -24,17 +24,20 @@ /* * This is a hack to allow a machine to use its own system clock as a * reference clock, i.e., to free-run using no outside clock discipline - * source. This is useful if you want to use NTP in an isolated - * environment with no radio clock or NIST modem available. Pick a - * machine that you figure has a good clock oscillator and configure it - * with this driver. Set the clock using the best means available, like + * source. Note that the clock selection algorithm will not select this + * driver unless all other sources of synchronization have been lost. + * This is useful if you want to use NTP in an isolated environment + * with no radio clock or NIST modem available. Pick a machine that you + * figure has a good clock oscillator and configure it with this + * driver. Set the clock using the best means available, like * eyeball-and-wristwatch. Then, point all the other machines at this * one or use broadcast (not multicast) mode to distribute time. * * Another application for this driver is if you want to use a * particular server's clock as the clock of last resort when all other * normal synchronization sources have gone away. This is especially - * useful if that server has an ovenized oscillator. + * useful if that server has an ovenized oscillator. However, the + * preferred was to do this is using orphan mode. See the documentation. * * A third application for this driver is when an external discipline * source is available, such as the NIST "lockclock" program, which @@ -50,31 +53,17 @@ * oscillator. In extreme cases, this can cause clients to exceed the * 128-ms slew window and drop off the NTP subnet. * - * THis driver includes provisions to telegraph synchronization state - * and related variables by means of kernel variables with specially - * modified kernels. This is done using the ntp_adjtime() syscall. - * In the cases where another protocol or device synchronizes the local - * host, the data given to the kernel can be slurped up by this driver - * and distributed to clients by ordinary NTP messaging. - * - * In the default mode the behavior of the clock selection algorithm is - * modified when this driver is in use. The algorithm is designed so - * that this driver will never be selected unless no other discipline - * source is available. - * * Fudge Factors * - * The stratum for this driver set at 5 by default, but it can be - * changed by the fudge command and/or the ntpdc utility. The reference - * ID is 127.0.0.1 by default, but can be changed using the same - * mechanism. + * If fudge flag1 is lit, the leap second bit is set in the peer + * status word. It should be set early in the day of a leap second + * event and set dark on the day after the event. * - * This driver provides a mechanism to trim the local clock in both time - * and frequency, as well as a way to manipulate the leap bits. The - * fudge time1 parameter adjusts the time, in seconds, and the fudge - * time2 parameter adjusts the frequency, in ppm. The fudge time1 - * parameter is additive; that is, it adds an increment to the current - * time. The fudge time2 parameter directly sets the frequency. + * Note the fudge time1 and time2 have been deprecated. The fudge time1 + * was intended to apply a bias offset. This can be done using the Unix + * date command. The fudge time2 was intended to apply a bias frequency. + * This can be done using the frequency file and/or the freq + * configuration command. */ /* * Local interface definitions @@ -203,12 +192,8 @@ local_poll( * time1 (s) and a continuous frequency adjustment using fudge * time 2 (ppm). */ - get_systime(&pp->lastrec); - pp->fudgetime1 += pp->fudgetime2 * 1e-6 * (current_time - - poll_time); poll_time = current_time; - refclock_process_offset(pp, pp->lastrec, pp->lastrec, - pp->fudgetime1); + refclock_process_offset(pp, pp->lastrec, pp->lastrec, 0); /* * If another process is disciplining the system clock, we set @@ -248,7 +233,6 @@ local_poll( #endif /* KERNEL_PLL LOCKCLOCK */ pp->lastref = pp->lastrec; refclock_receive(peer); - pp->fudgetime1 = 0; } #else int refclock_local_bs;