From a4465d0d4c63c2021b0ba4788e93006e84aafb58 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Nov 2017 01:47:38 +0900 Subject: [PATCH] timesync: make poll interval configurable This adds PollIntervalMinSec= and PollIntervalMaxSec= to timesyncd.conf Closes #7262. --- man/timesyncd.conf.xml | 13 ++++++++++++- src/timesync/timesyncd-conf.c | 26 +++++++++++++++++++++----- src/timesync/timesyncd-gperf.gperf | 2 ++ src/timesync/timesyncd-manager.c | 29 ++++++++++++----------------- src/timesync/timesyncd-manager.h | 10 ++++++++++ src/timesync/timesyncd.conf.in | 2 ++ 6 files changed, 59 insertions(+), 23 deletions(-) diff --git a/man/timesyncd.conf.xml b/man/timesyncd.conf.xml index eb78d7b..d68d9bd 100644 --- a/man/timesyncd.conf.xml +++ b/man/timesyncd.conf.xml @@ -103,10 +103,21 @@ RootDistanceMaxSec= - Maximum acceptable root distance in seconds. + Maximum acceptable root distance. Takes a time value (in seconds). Defaults to 5 seconds. + + PollIntervalMinSec= + PollIntervalMaxSec= + The minimum and maximum poll intervals for NTP messages. + Each setting takes a time value (in seconds). + PollIntervalMinSec= must not be smaller than 16 seconds. + PollIntervalMaxSec= must be larger than PollIntervalMinSec=. + PollIntervalMinSec= defaults to 32 seconds, and + PollIntervalMaxSec= defaults to 2048 seconds. + + diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c index f394d0a..b62e20c 100644 --- a/src/timesync/timesyncd-conf.c +++ b/src/timesync/timesyncd-conf.c @@ -106,11 +106,27 @@ int config_parse_servers( } int manager_parse_config_file(Manager *m) { + int r; + assert(m); - return config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf", - CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"), - "Time\0", - config_item_perf_lookup, timesyncd_gperf_lookup, - false, m); + r = config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf", + CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"), + "Time\0", + config_item_perf_lookup, timesyncd_gperf_lookup, + false, m); + if (r < 0) + return r; + + if (m->poll_interval_min_usec < 16 * USEC_PER_SEC) { + log_warning("Invalid PollIntervalMinSec=. Using default value."); + m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC; + } + + if (m->poll_interval_max_usec < m->poll_interval_min_usec) { + log_warning("PollIntervalMaxSec= is smaller than PollIntervalMinSec=. Using default value."); + m->poll_interval_max_usec = MAX(NTP_POLL_INTERVAL_MAX_USEC, m->poll_interval_min_usec * 32); + } + + return r; } diff --git a/src/timesync/timesyncd-gperf.gperf b/src/timesync/timesyncd-gperf.gperf index 65fae9f..e8ef585 100644 --- a/src/timesync/timesyncd-gperf.gperf +++ b/src/timesync/timesyncd-gperf.gperf @@ -18,3 +18,5 @@ Time.NTP, config_parse_servers, SERVER_SYSTEM, 0 Time.Servers, config_parse_servers, SERVER_SYSTEM, 0 Time.FallbackNTP, config_parse_servers, SERVER_FALLBACK, 0 Time.RootDistanceMaxSec, config_parse_sec, 0, offsetof(Manager, max_root_distance_usec) +Time.PollIntervalMinSec, config_parse_sec, 0, offsetof(Manager, poll_interval_min_usec) +Time.PollIntervalMaxSec, config_parse_sec, 0, offsetof(Manager, poll_interval_max_usec) diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c index e58d819..dad460f 100644 --- a/src/timesync/timesyncd-manager.c +++ b/src/timesync/timesyncd-manager.c @@ -56,15 +56,8 @@ #define NTP_ACCURACY_SEC 0.2 /* - * "A client MUST NOT under any conditions use a poll interval less - * than 15 seconds." - */ -#define NTP_POLL_INTERVAL_MIN_SEC 32 -#define NTP_POLL_INTERVAL_MAX_SEC 2048 - -/* * Maximum delta in seconds which the system clock is gradually adjusted - * (slew) to approach the network time. Deltas larger that this are set by + * (slewed) to approach the network time. Deltas larger that this are set by * letting the system time jump. The kernel's limit for adjtime is 0.5s. */ #define NTP_MAX_ADJUST 0.4 @@ -80,7 +73,7 @@ #define NTP_FIELD_MODE(f) ((f) & 7) #define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m)) -/* Maximum acceptable root distance in microseconds. */ +/* Default of maximum acceptable root distance in microseconds. */ #define NTP_MAX_ROOT_DISTANCE (5 * USEC_PER_SEC) /* Maximum number of missed replies before selecting another source. */ @@ -204,10 +197,10 @@ static int manager_send_request(Manager *m) { /* re-arm timer with increasing timeout, in case the packets never arrive back */ if (m->retry_interval > 0) { - if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC) + if (m->retry_interval < m->poll_interval_max_usec) m->retry_interval *= 2; } else - m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC; + m->retry_interval = m->poll_interval_min_usec; r = manager_arm_timer(m, m->retry_interval); if (r < 0) @@ -446,27 +439,27 @@ static void manager_adjust_poll(Manager *m, double offset, bool spike) { assert(m); if (m->poll_resync) { - m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC; + m->poll_interval_usec = m->poll_interval_min_usec; m->poll_resync = false; return; } /* set to minimal poll interval */ if (!spike && fabs(offset) > NTP_ACCURACY_SEC) { - m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC; + m->poll_interval_usec = m->poll_interval_min_usec; return; } /* increase polling interval */ if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) { - if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC) + if (m->poll_interval_usec < m->poll_interval_max_usec) m->poll_interval_usec *= 2; return; } /* decrease polling interval */ if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) { - if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC) + if (m->poll_interval_usec > m->poll_interval_min_usec) m->poll_interval_usec /= 2; return; } @@ -743,7 +736,7 @@ static int manager_begin(Manager *m) { m->good = false; m->missed_replies = NTP_MAX_MISSED_REPLIES; if (m->poll_interval_usec == 0) - m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC; + m->poll_interval_usec = m->poll_interval_min_usec; server_address_pretty(m->current_server_address, &pretty); log_debug("Connecting to time server %s (%s).", strna(pretty), m->current_server_name->string); @@ -921,7 +914,7 @@ int manager_connect(Manager *m) { m->exhausted_servers = true; /* Increase the polling interval */ - if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC) + if (m->poll_interval_usec < m->poll_interval_max_usec) m->poll_interval_usec *= 2; return 0; @@ -1125,6 +1118,8 @@ int manager_new(Manager **ret) { return -ENOMEM; m->max_root_distance_usec = NTP_MAX_ROOT_DISTANCE; + m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC; + m->poll_interval_max_usec = NTP_POLL_INTERVAL_MAX_USEC; m->server_socket = m->clock_watch_fd = -1; diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h index 7550e82..d371f21 100644 --- a/src/timesync/timesyncd-manager.h +++ b/src/timesync/timesyncd-manager.h @@ -25,11 +25,19 @@ #include "list.h" #include "ratelimit.h" +#include "time-util.h" typedef struct Manager Manager; #include "timesyncd-server.h" +/* + * "A client MUST NOT under any conditions use a poll interval less + * than 15 seconds." + */ +#define NTP_POLL_INTERVAL_MIN_USEC (32 * USEC_PER_SEC) +#define NTP_POLL_INTERVAL_MAX_USEC (2048 * USEC_PER_SEC) + struct Manager { sd_event *event; sd_resolve *resolve; @@ -67,6 +75,8 @@ struct Manager { /* poll timer */ sd_event_source *event_timer; usec_t poll_interval_usec; + usec_t poll_interval_min_usec; + usec_t poll_interval_max_usec; bool poll_resync; /* history data */ diff --git a/src/timesync/timesyncd.conf.in b/src/timesync/timesyncd.conf.in index 2b3c476..f91c034 100644 --- a/src/timesync/timesyncd.conf.in +++ b/src/timesync/timesyncd.conf.in @@ -15,3 +15,5 @@ #NTP= #FallbackNTP=@NTP_SERVERS@ #RootDistanceMaxSec=5 +#PollIntervalMinSec=32 +#PollIntervalMaxSec=2048 -- 2.7.4