diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-11 02:14:04 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-01-11 02:14:04 +0100 |
commit | 65d722bb0d0e822db014a742da4c9c2c111131f0 (patch) | |
tree | 2d4d1841cdd04dd1aca55194c9a9ab33b683c92d /networking/ntpd.c | |
parent | 12628b77970b46290ed75ecae55afe65297b3e35 (diff) | |
download | busybox-w32-65d722bb0d0e822db014a742da4c9c2c111131f0.tar.gz busybox-w32-65d722bb0d0e822db014a742da4c9c2c111131f0.tar.bz2 busybox-w32-65d722bb0d0e822db014a742da4c9c2c111131f0.zip |
ntpd: explain algorithm
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/ntpd.c')
-rw-r--r-- | networking/ntpd.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c index 092c444d4..e52d20c01 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -46,8 +46,34 @@ | |||
46 | #define MAX_VERBOSE 2 | 46 | #define MAX_VERBOSE 2 |
47 | 47 | ||
48 | 48 | ||
49 | /* High-level description of the algorithm: | ||
50 | * | ||
51 | * We start running with very small poll_exp, BURSTPOLL, | ||
52 | * in order to quickly accumulate INITIAL_SAMLPES datapoints | ||
53 | * for each peer. Then, time is stepped if the offset is larger | ||
54 | * than STEP_THRESHOLD, otherwise it isn't; anyway, we enlarge | ||
55 | * poll_exp to MINPOLL and enter frequency measurement step: | ||
56 | * we collect new datapoints but ignore them for WATCH_THRESHOLD | ||
57 | * seconds. After WATCH_THRESHOLD seconds we look at accumulated | ||
58 | * offset and estimate frequency drift. | ||
59 | * | ||
60 | * After this, we enter "steady state": we collect a datapoint, | ||
61 | * we select the best peer, if this datapoint is not a new one | ||
62 | * (IOW: if this datapoint isn't for selected peer), sleep | ||
63 | * and collect another one; otherwise, use its offset to update | ||
64 | * frequency drift, if offset is somewhat large, reduce poll_exp, | ||
65 | * otherwise increase poll_exp. | ||
66 | * | ||
67 | * If offset is larger than STEP_THRESHOLD, which shouldn't normally | ||
68 | * happen, we assume that something "bad" happened (computer | ||
69 | * was hibernated, someone set totally wrong date, etc), | ||
70 | * then the time is stepped, all datapoints are discarded, | ||
71 | * and we go back to steady state. | ||
72 | */ | ||
73 | |||
49 | #define RETRY_INTERVAL 5 /* on error, retry in N secs */ | 74 | #define RETRY_INTERVAL 5 /* on error, retry in N secs */ |
50 | #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ | 75 | #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ |
76 | #define INITIAL_SAMLPES 4 /* how many samples do we want for init */ | ||
51 | 77 | ||
52 | /* Clock discipline parameters and constants */ | 78 | /* Clock discipline parameters and constants */ |
53 | #define STEP_THRESHOLD 0.128 /* step threshold (s) */ | 79 | #define STEP_THRESHOLD 0.128 /* step threshold (s) */ |
@@ -75,8 +101,9 @@ | |||
75 | * we grow a counter: += MINPOLL. When it goes over POLLADJ_LIMIT, | 101 | * we grow a counter: += MINPOLL. When it goes over POLLADJ_LIMIT, |
76 | * we poll_exp++. If offset isn't small, counter -= poll_exp*2, | 102 | * we poll_exp++. If offset isn't small, counter -= poll_exp*2, |
77 | * and when it goes below -POLLADJ_LIMIT, we poll_exp-- | 103 | * and when it goes below -POLLADJ_LIMIT, we poll_exp-- |
104 | * (bumped from 30 to 36 since otherwise I often see poll_exp going *2* steps down) | ||
78 | */ | 105 | */ |
79 | #define POLLADJ_LIMIT 30 | 106 | #define POLLADJ_LIMIT 36 |
80 | /* If offset < POLLADJ_GATE * discipline_jitter, then we can increase | 107 | /* If offset < POLLADJ_GATE * discipline_jitter, then we can increase |
81 | * poll interval (we think we can't improve timekeeping | 108 | * poll interval (we think we can't improve timekeeping |
82 | * by staying at smaller poll). | 109 | * by staying at smaller poll). |
@@ -1555,6 +1582,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1555 | if (q->filter_offset < -POLLDOWN_OFFSET | 1582 | if (q->filter_offset < -POLLDOWN_OFFSET |
1556 | || q->filter_offset > POLLDOWN_OFFSET | 1583 | || q->filter_offset > POLLDOWN_OFFSET |
1557 | ) { | 1584 | ) { |
1585 | VERB3 bb_error_msg("offset:%f > POLLDOWN_OFFSET", q->filter_offset); | ||
1558 | goto poll_down; | 1586 | goto poll_down; |
1559 | } | 1587 | } |
1560 | } | 1588 | } |
@@ -1856,13 +1884,14 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
1856 | idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt); | 1884 | idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt); |
1857 | pfd = xzalloc(sizeof(pfd[0]) * cnt); | 1885 | pfd = xzalloc(sizeof(pfd[0]) * cnt); |
1858 | 1886 | ||
1859 | /* Countdown: we never sync before we sent 5 packets to each peer | 1887 | /* Countdown: we never sync before we sent INITIAL_SAMLPES+1 |
1888 | * packets to each peer. | ||
1860 | * NB: if some peer is not responding, we may end up sending | 1889 | * NB: if some peer is not responding, we may end up sending |
1861 | * fewer packets to it and more to other peers. | 1890 | * fewer packets to it and more to other peers. |
1862 | * NB2: sync usually happens using 5-1=4 packets, since last reply | 1891 | * NB2: sync usually happens using INITIAL_SAMLPES packets, |
1863 | * does not come back instantaneously. | 1892 | * since last reply does not come back instantaneously. |
1864 | */ | 1893 | */ |
1865 | cnt = G.peer_cnt * 5; | 1894 | cnt = G.peer_cnt * (INITIAL_SAMLPES + 1); |
1866 | 1895 | ||
1867 | while (!bb_got_signal) { | 1896 | while (!bb_got_signal) { |
1868 | llist_t *item; | 1897 | llist_t *item; |