[git commit master] ntpd: expose more data to the script; more eagerly drop to lower poll

Denys Vlasenko vda.linux at googlemail.com
Mon Jan 11 00:31:59 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=12628b77970b46290ed75ecae55afe65297b3e35
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
run_script                                           340     395     +55
recv_and_process_peer_pkt                            817     869     +52
passwd_main                                         1027    1058     +31
ntpd_main                                            845     855     +10
update_local_clock                                   853     823     -30
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 148/-30)           Total: 118 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/ntpd.c |   72 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 46 insertions(+), 26 deletions(-)

diff --git a/networking/ntpd.c b/networking/ntpd.c
index c28d768..092c444 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -49,24 +49,26 @@
 #define RETRY_INTERVAL  5       /* on error, retry in N secs */
 #define RESPONSE_INTERVAL 15    /* wait for reply up to N secs */
 
-#define FREQ_TOLERANCE  0.000015 /* % frequency tolerance (15 PPM) */
-#define BURSTPOLL       0
-#define MINPOLL         4       /* % minimum poll interval (6: 64 s) */
-#define MAXPOLL         12      /* % maximum poll interval (12: 1.1h, 17: 36.4h) (was 17) */
-#define MINDISP         0.01    /* % minimum dispersion (s) */
-#define MAXDISP         16      /* maximum dispersion (s) */
-#define MAXSTRAT        16      /* maximum stratum (infinity metric) */
-#define MAXDIST         1       /* % distance threshold (s) */
-#define MIN_SELECTED    1       /* % minimum intersection survivors */
-#define MIN_CLUSTERED   3       /* % minimum cluster survivors */
-
-#define MAXDRIFT        0.000500 /* frequency drift we can correct (500 PPM) */
-
 /* Clock discipline parameters and constants */
 #define STEP_THRESHOLD  0.128   /* step threshold (s) */
 #define WATCH_THRESHOLD 150     /* stepout threshold (s). std ntpd uses 900 (11 mins (!)) */
 /* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */
-#define PANIC_THRESHOLD 1000    /* panic threshold (s) */
+//UNUSED: #define PANIC_THRESHOLD 1000    /* panic threshold (s) */
+
+#define FREQ_TOLERANCE  0.000015 /* frequency tolerance (15 PPM) */
+#define BURSTPOLL       0	/* initial poll */
+#define MINPOLL         4       /* minimum poll interval (6: 64 s) */
+#define BIGPOLL         10      /* drop to lower poll at any trouble (10: 17 min) */
+#define MAXPOLL         12      /* maximum poll interval (12: 1.1h, 17: 36.4h) (was 17) */
+#define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) /* actively lower poll when we see such big offsets */
+#define MINDISP         0.01    /* minimum dispersion (s) */
+#define MAXDISP         16      /* maximum dispersion (s) */
+#define MAXSTRAT        16      /* maximum stratum (infinity metric) */
+#define MAXDIST         1       /* distance threshold (s) */
+#define MIN_SELECTED    1       /* minimum intersection survivors */
+#define MIN_CLUSTERED   3       /* minimum cluster survivors */
+
+#define MAXDRIFT        0.000500 /* frequency drift we can correct (500 PPM) */
 
 /* Poll-adjust threshold.
  * When we see that offset is small enough compared to discipline jitter,
@@ -686,10 +688,10 @@ send_query_to_peer(peer_t *p)
 }
 
 
-static void run_script(const char *action)
+static void run_script(const char *action, double offset)
 {
 	char *argv[3];
-	char *env1, *env2, *env3;
+	char *env1, *env2, *env3, *env4;
 
 	if (!G.script_name)
 		return;
@@ -706,9 +708,12 @@ static void run_script(const char *action)
 	putenv(env2);
 	env3 = xasprintf("%s=%u", "poll_interval", 1 << G.poll_exp);
 	putenv(env3);
+	env4 = xasprintf("%s=%f", "offset", offset);
+	putenv(env4);
 	/* Other items of potential interest: selected peer,
 	 * rootdelay, reftime, rootdisp, refid, ntp_status,
-	 * last_update_offset, last_update_recv_time, discipline_jitter
+	 * last_update_offset, last_update_recv_time, discipline_jitter,
+	 * how many peers have reachable_bits = 0?
 	 */
 
 	/* Don't want to wait: it may run hwclock --systohc, and that
@@ -719,9 +724,11 @@ static void run_script(const char *action)
 	unsetenv("stratum");
 	unsetenv("freq_drift_ppm");
 	unsetenv("poll_interval");
+	unsetenv("offset");
 	free(env1);
 	free(env2);
 	free(env3);
+	free(env4);
 
 	G.last_script_run = G.cur_time;
 }
@@ -1095,10 +1102,14 @@ update_local_clock(peer_t *p)
 
 	abs_offset = fabs(offset);
 
+#if 0
+	/* If needed, -S script can detect this by looking at $offset
+	 * env var and kill parent */
 	/* If the offset is too large, give up and go home */
 	if (abs_offset > PANIC_THRESHOLD) {
 		bb_error_msg_and_die("offset %f far too big, exiting", offset);
 	}
+#endif
 
 	/* If this is an old update, for instance as the result
 	 * of a system peer change, avoid it. We never use
@@ -1185,7 +1196,7 @@ update_local_clock(peer_t *p)
 		G.poll_exp = MINPOLL;
 		G.stratum = MAXSTRAT;
 
-		run_script("step");
+		run_script("step", offset);
 
 		if (G.discipline_state == STATE_NSET) {
 			set_new_values(STATE_FREQ, /*offset:*/ 0, recv_time);
@@ -1274,7 +1285,7 @@ update_local_clock(peer_t *p)
 		}
 		if (G.stratum != p->lastpkt_stratum + 1) {
 			G.stratum = p->lastpkt_stratum + 1;
-			run_script("stratum");
+			run_script("stratum", offset);
 		}
 	}
 
@@ -1371,10 +1382,8 @@ update_local_clock(peer_t *p)
 				tmx.freq, tmx.offset, tmx.constant, tmx.status);
 	}
 #endif
-	if (G.kernel_freq_drift != tmx.freq / 65536) {
-		G.kernel_freq_drift = tmx.freq / 65536;
-		VERB2 bb_error_msg("kernel clock drift: %ld ppm", G.kernel_freq_drift);
-	}
+	G.kernel_freq_drift = tmx.freq / 65536;
+	VERB2 bb_error_msg("update offset:%f, clock drift:%ld ppm", G.last_update_offset, G.kernel_freq_drift);
 
 	return 1; /* "ok to increase poll interval" */
 }
@@ -1538,9 +1547,19 @@ recv_and_process_peer_pkt(peer_t *p)
 	rc = -1;
 	if (q) {
 		rc = 0;
-		if (!(option_mask32 & OPT_w))
+		if (!(option_mask32 & OPT_w)) {
 			rc = update_local_clock(q);
+			/* If drift is dangerously large, immediately
+			 * drop poll interval one step down.
+			 */
+			if (q->filter_offset < -POLLDOWN_OFFSET
+			 || q->filter_offset > POLLDOWN_OFFSET
+			) {
+				goto poll_down;
+			}
+		}
 	}
+	/* else: no peer selected, rc = -1: we want to poll more often */
 
 	if (rc != 0) {
 		/* Adjust the poll interval by comparing the current offset
@@ -1572,7 +1591,8 @@ recv_and_process_peer_pkt(peer_t *p)
 			}
 		} else {
 			G.polladj_count -= G.poll_exp * 2;
-			if (G.polladj_count < -POLLADJ_LIMIT) {
+			if (G.polladj_count < -POLLADJ_LIMIT || G.poll_exp >= BIGPOLL) {
+ poll_down:
 				G.polladj_count = 0;
 				if (G.poll_exp > MINPOLL) {
 					llist_t *item;
@@ -1910,7 +1930,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
 			 && G.cur_time - G.last_script_run > 11*60
 			) {
 				/* Useful for updating battery-backed RTC and such */
-				run_script("periodic");
+				run_script("periodic", G.last_update_offset);
 				gettime1900d(); /* sets G.cur_time */
 			}
 			continue;
-- 
1.6.3.3



More information about the busybox-cvs mailing list