[PATCH] ntpd: don't stay at short polling interval
Miroslav Lichvar
mlichvar at redhat.com
Wed Oct 1 13:51:30 UTC 2014
To avoid polling servers frequently slowly increase the interval up
to BIGPOLL when
- no replies are received from a peer
- no source can be selected
- peer claims to be unsynchronized (e.g. we are polling it too
frequently)
- recv() returns with an error (e.g. the host doesn't exist or is not
running an NTP service)
Signed-off-by: Miroslav Lichvar <mlichvar at redhat.com>
---
networking/ntpd.c | 37 ++++++++++++++++++++++++++++---------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/networking/ntpd.c b/networking/ntpd.c
index b2b2791..d8df125 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -1730,6 +1730,7 @@ recv_and_process_peer_pkt(peer_t *p)
datapoint_t *datapoint;
peer_t *q;
+ rc = 0;
offset = 0;
/* We can recvfrom here and check from.IP, but some multihomed
@@ -1744,9 +1745,8 @@ recv_and_process_peer_pkt(peer_t *p)
|| errno == ECONNREFUSED || errno == EADDRNOTAVAIL
|| errno == EAGAIN
) {
-//TODO: always do this?
- interval = poll_interval(RETRY_INTERVAL);
- goto set_next_and_ret;
+ rc = 1;
+ goto pick_normal_interval;
}
xfunc_die();
}
@@ -1778,6 +1778,7 @@ recv_and_process_peer_pkt(peer_t *p)
// "DENY", "RSTR" - peer does not like us at all
// "RATE" - peer is overloaded, reduce polling freq
bb_error_msg("reply from %s: peer is unsynced", p->p_dotted);
+ rc = 1;
goto pick_normal_interval;
}
@@ -1866,9 +1867,8 @@ recv_and_process_peer_pkt(peer_t *p)
/* Muck with statictics and update the clock */
filter_datapoints(p);
q = select_and_cluster();
- rc = -1;
+ rc = 1;
if (q) {
- rc = 0;
if (!(option_mask32 & OPT_w)) {
rc = update_local_clock(q);
/* If drift is dangerously large, immediately
@@ -1880,10 +1880,15 @@ recv_and_process_peer_pkt(peer_t *p)
rc = 0;
}
}
+ } else {
+ /* Keep increasing the polling interval when no source can be
+ * selected, but wait until the initial burst is complete.
+ */
+ if (!G.initial_poll_complete)
+ rc = 0;
}
- /* else: no peer selected, rc = -1: we want to poll more often */
- if (rc != 0) {
+ if (q && rc != 0) {
/* Adjust the poll interval by comparing the current offset
* with the clock jitter. If the offset is less than
* the clock jitter times a constant, then the averaging interval
@@ -1897,10 +1902,18 @@ recv_and_process_peer_pkt(peer_t *p)
} else {
adjust_poll(-G.poll_exp * 2);
}
+ rc = 0;
}
- /* Decide when to send new query for this peer */
+ /* Decide when to send new query for this peer. When recv() is failing,
+ * no peer can be selected or the peer is unsynchronized, slowly
+ * increase the polling interval up to BIGPOLL to not overload the peer
+ * or the network.
+ */
pick_normal_interval:
+ if (rc > 0 && G.poll_exp < BIGPOLL)
+ adjust_poll(POLLADJ_LIMIT / 8);
+
interval = poll_interval(INT_MAX);
if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) {
/* If we are synced, offsets are less than STEP_THRESHOLD,
@@ -1917,7 +1930,6 @@ recv_and_process_peer_pkt(peer_t *p)
interval = BIGOFF_INTERVAL;
}
- set_next_and_ret:
set_next(p, interval);
}
@@ -2252,6 +2264,13 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
/* Timed out waiting for reply */
close(p->p_fd);
p->p_fd = -1;
+
+ /* Slowly increase the polling interval up to BIGPOLL
+ * in case the network or the peer is overloaded.
+ */
+ if (G.poll_exp < BIGPOLL)
+ adjust_poll(POLLADJ_LIMIT / 8);
+
timeout = poll_interval(NOREPLY_INTERVAL);
bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us",
p->p_dotted, p->reachable_bits, timeout);
--
1.9.3
More information about the busybox
mailing list