aboutsummaryrefslogtreecommitdiff
path: root/networking/ntpd.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-01-11 01:31:59 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-11 01:31:59 +0100
commit12628b77970b46290ed75ecae55afe65297b3e35 (patch)
tree4c2da785709fb5f8d0a19d6573d5ad7efc7ed1a8 /networking/ntpd.c
parent725b5a387a392f6282756c649adf411e30535eb5 (diff)
downloadbusybox-w32-12628b77970b46290ed75ecae55afe65297b3e35.tar.gz
busybox-w32-12628b77970b46290ed75ecae55afe65297b3e35.tar.bz2
busybox-w32-12628b77970b46290ed75ecae55afe65297b3e35.zip
ntpd: expose more data to the script; more eagerly drop to lower poll
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@googlemail.com>
Diffstat (limited to 'networking/ntpd.c')
-rw-r--r--networking/ntpd.c72
1 files changed, 46 insertions, 26 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index c28d76891..092c444d4 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -49,24 +49,26 @@
49#define RETRY_INTERVAL 5 /* on error, retry in N secs */ 49#define RETRY_INTERVAL 5 /* on error, retry in N secs */
50#define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ 50#define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */
51 51
52#define FREQ_TOLERANCE 0.000015 /* % frequency tolerance (15 PPM) */
53#define BURSTPOLL 0
54#define MINPOLL 4 /* % minimum poll interval (6: 64 s) */
55#define MAXPOLL 12 /* % maximum poll interval (12: 1.1h, 17: 36.4h) (was 17) */
56#define MINDISP 0.01 /* % minimum dispersion (s) */
57#define MAXDISP 16 /* maximum dispersion (s) */
58#define MAXSTRAT 16 /* maximum stratum (infinity metric) */
59#define MAXDIST 1 /* % distance threshold (s) */
60#define MIN_SELECTED 1 /* % minimum intersection survivors */
61#define MIN_CLUSTERED 3 /* % minimum cluster survivors */
62
63#define MAXDRIFT 0.000500 /* frequency drift we can correct (500 PPM) */
64
65/* Clock discipline parameters and constants */ 52/* Clock discipline parameters and constants */
66#define STEP_THRESHOLD 0.128 /* step threshold (s) */ 53#define STEP_THRESHOLD 0.128 /* step threshold (s) */
67#define WATCH_THRESHOLD 150 /* stepout threshold (s). std ntpd uses 900 (11 mins (!)) */ 54#define WATCH_THRESHOLD 150 /* stepout threshold (s). std ntpd uses 900 (11 mins (!)) */
68/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ 55/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */
69#define PANIC_THRESHOLD 1000 /* panic threshold (s) */ 56//UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (s) */
57
58#define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */
59#define BURSTPOLL 0 /* initial poll */
60#define MINPOLL 4 /* minimum poll interval (6: 64 s) */
61#define BIGPOLL 10 /* drop to lower poll at any trouble (10: 17 min) */
62#define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h) (was 17) */
63#define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) /* actively lower poll when we see such big offsets */
64#define MINDISP 0.01 /* minimum dispersion (s) */
65#define MAXDISP 16 /* maximum dispersion (s) */
66#define MAXSTRAT 16 /* maximum stratum (infinity metric) */
67#define MAXDIST 1 /* distance threshold (s) */
68#define MIN_SELECTED 1 /* minimum intersection survivors */
69#define MIN_CLUSTERED 3 /* minimum cluster survivors */
70
71#define MAXDRIFT 0.000500 /* frequency drift we can correct (500 PPM) */
70 72
71/* Poll-adjust threshold. 73/* Poll-adjust threshold.
72 * When we see that offset is small enough compared to discipline jitter, 74 * When we see that offset is small enough compared to discipline jitter,
@@ -686,10 +688,10 @@ send_query_to_peer(peer_t *p)
686} 688}
687 689
688 690
689static void run_script(const char *action) 691static void run_script(const char *action, double offset)
690{ 692{
691 char *argv[3]; 693 char *argv[3];
692 char *env1, *env2, *env3; 694 char *env1, *env2, *env3, *env4;
693 695
694 if (!G.script_name) 696 if (!G.script_name)
695 return; 697 return;
@@ -706,9 +708,12 @@ static void run_script(const char *action)
706 putenv(env2); 708 putenv(env2);
707 env3 = xasprintf("%s=%u", "poll_interval", 1 << G.poll_exp); 709 env3 = xasprintf("%s=%u", "poll_interval", 1 << G.poll_exp);
708 putenv(env3); 710 putenv(env3);
711 env4 = xasprintf("%s=%f", "offset", offset);
712 putenv(env4);
709 /* Other items of potential interest: selected peer, 713 /* Other items of potential interest: selected peer,
710 * rootdelay, reftime, rootdisp, refid, ntp_status, 714 * rootdelay, reftime, rootdisp, refid, ntp_status,
711 * last_update_offset, last_update_recv_time, discipline_jitter 715 * last_update_offset, last_update_recv_time, discipline_jitter,
716 * how many peers have reachable_bits = 0?
712 */ 717 */
713 718
714 /* Don't want to wait: it may run hwclock --systohc, and that 719 /* Don't want to wait: it may run hwclock --systohc, and that
@@ -719,9 +724,11 @@ static void run_script(const char *action)
719 unsetenv("stratum"); 724 unsetenv("stratum");
720 unsetenv("freq_drift_ppm"); 725 unsetenv("freq_drift_ppm");
721 unsetenv("poll_interval"); 726 unsetenv("poll_interval");
727 unsetenv("offset");
722 free(env1); 728 free(env1);
723 free(env2); 729 free(env2);
724 free(env3); 730 free(env3);
731 free(env4);
725 732
726 G.last_script_run = G.cur_time; 733 G.last_script_run = G.cur_time;
727} 734}
@@ -1095,10 +1102,14 @@ update_local_clock(peer_t *p)
1095 1102
1096 abs_offset = fabs(offset); 1103 abs_offset = fabs(offset);
1097 1104
1105#if 0
1106 /* If needed, -S script can detect this by looking at $offset
1107 * env var and kill parent */
1098 /* If the offset is too large, give up and go home */ 1108 /* If the offset is too large, give up and go home */
1099 if (abs_offset > PANIC_THRESHOLD) { 1109 if (abs_offset > PANIC_THRESHOLD) {
1100 bb_error_msg_and_die("offset %f far too big, exiting", offset); 1110 bb_error_msg_and_die("offset %f far too big, exiting", offset);
1101 } 1111 }
1112#endif
1102 1113
1103 /* If this is an old update, for instance as the result 1114 /* If this is an old update, for instance as the result
1104 * of a system peer change, avoid it. We never use 1115 * of a system peer change, avoid it. We never use
@@ -1185,7 +1196,7 @@ update_local_clock(peer_t *p)
1185 G.poll_exp = MINPOLL; 1196 G.poll_exp = MINPOLL;
1186 G.stratum = MAXSTRAT; 1197 G.stratum = MAXSTRAT;
1187 1198
1188 run_script("step"); 1199 run_script("step", offset);
1189 1200
1190 if (G.discipline_state == STATE_NSET) { 1201 if (G.discipline_state == STATE_NSET) {
1191 set_new_values(STATE_FREQ, /*offset:*/ 0, recv_time); 1202 set_new_values(STATE_FREQ, /*offset:*/ 0, recv_time);
@@ -1274,7 +1285,7 @@ update_local_clock(peer_t *p)
1274 } 1285 }
1275 if (G.stratum != p->lastpkt_stratum + 1) { 1286 if (G.stratum != p->lastpkt_stratum + 1) {
1276 G.stratum = p->lastpkt_stratum + 1; 1287 G.stratum = p->lastpkt_stratum + 1;
1277 run_script("stratum"); 1288 run_script("stratum", offset);
1278 } 1289 }
1279 } 1290 }
1280 1291
@@ -1371,10 +1382,8 @@ update_local_clock(peer_t *p)
1371 tmx.freq, tmx.offset, tmx.constant, tmx.status); 1382 tmx.freq, tmx.offset, tmx.constant, tmx.status);
1372 } 1383 }
1373#endif 1384#endif
1374 if (G.kernel_freq_drift != tmx.freq / 65536) { 1385 G.kernel_freq_drift = tmx.freq / 65536;
1375 G.kernel_freq_drift = tmx.freq / 65536; 1386 VERB2 bb_error_msg("update offset:%f, clock drift:%ld ppm", G.last_update_offset, G.kernel_freq_drift);
1376 VERB2 bb_error_msg("kernel clock drift: %ld ppm", G.kernel_freq_drift);
1377 }
1378 1387
1379 return 1; /* "ok to increase poll interval" */ 1388 return 1; /* "ok to increase poll interval" */
1380} 1389}
@@ -1538,9 +1547,19 @@ recv_and_process_peer_pkt(peer_t *p)
1538 rc = -1; 1547 rc = -1;
1539 if (q) { 1548 if (q) {
1540 rc = 0; 1549 rc = 0;
1541 if (!(option_mask32 & OPT_w)) 1550 if (!(option_mask32 & OPT_w)) {
1542 rc = update_local_clock(q); 1551 rc = update_local_clock(q);
1552 /* If drift is dangerously large, immediately
1553 * drop poll interval one step down.
1554 */
1555 if (q->filter_offset < -POLLDOWN_OFFSET
1556 || q->filter_offset > POLLDOWN_OFFSET
1557 ) {
1558 goto poll_down;
1559 }
1560 }
1543 } 1561 }
1562 /* else: no peer selected, rc = -1: we want to poll more often */
1544 1563
1545 if (rc != 0) { 1564 if (rc != 0) {
1546 /* Adjust the poll interval by comparing the current offset 1565 /* Adjust the poll interval by comparing the current offset
@@ -1572,7 +1591,8 @@ recv_and_process_peer_pkt(peer_t *p)
1572 } 1591 }
1573 } else { 1592 } else {
1574 G.polladj_count -= G.poll_exp * 2; 1593 G.polladj_count -= G.poll_exp * 2;
1575 if (G.polladj_count < -POLLADJ_LIMIT) { 1594 if (G.polladj_count < -POLLADJ_LIMIT || G.poll_exp >= BIGPOLL) {
1595 poll_down:
1576 G.polladj_count = 0; 1596 G.polladj_count = 0;
1577 if (G.poll_exp > MINPOLL) { 1597 if (G.poll_exp > MINPOLL) {
1578 llist_t *item; 1598 llist_t *item;
@@ -1910,7 +1930,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
1910 && G.cur_time - G.last_script_run > 11*60 1930 && G.cur_time - G.last_script_run > 11*60
1911 ) { 1931 ) {
1912 /* Useful for updating battery-backed RTC and such */ 1932 /* Useful for updating battery-backed RTC and such */
1913 run_script("periodic"); 1933 run_script("periodic", G.last_update_offset);
1914 gettime1900d(); /* sets G.cur_time */ 1934 gettime1900d(); /* sets G.cur_time */
1915 } 1935 }
1916 continue; 1936 continue;