[systemd] Update timesyncd with patches to avoid hitting NTP pool too often.
Michal Schmidt
michich at fedoraproject.org
Wed Sep 10 16:40:59 UTC 2014
commit d962ba812f59f7eda880206ba46f7c59719d91ce
Author: Michal Schmidt <mschmidt at redhat.com>
Date: Wed Sep 10 18:29:47 2014 +0200
Update timesyncd with patches to avoid hitting NTP pool too often.
0002-timesyncd-check-if-stratum-is-valid.patch | 27 ++++++
...imesyncd-fix-calculation-of-transmit-time.patch | 38 ++++++++
...syncd-get-kernel-timestamp-in-nanoseconds.patch | 66 ++++++++++++++
0005-timesyncd-check-root-distance.patch | 82 ++++++++++++++++++
...anager-don-t-clear-current_server_name-if.patch | 35 ++++++++
...-wait-before-reconnecting-to-first-server.patch | 88 +++++++++++++++++++
...emove-retry_timer-logic-which-is-covered-.patch | 59 +++++++++++++
...llow-two-missed-replies-before-reselectin.patch | 90 ++++++++++++++++++++
...on-t-reset-polling-interval-when-reselect.patch | 30 +++++++
...syncd-remove-retry_timer-logic-which-is-c.patch | 66 ++++++++++++++
systemd.spec | 17 ++++-
11 files changed, 597 insertions(+), 1 deletions(-)
---
diff --git a/0002-timesyncd-check-if-stratum-is-valid.patch b/0002-timesyncd-check-if-stratum-is-valid.patch
new file mode 100644
index 0000000..73194e3
--- /dev/null
+++ b/0002-timesyncd-check-if-stratum-is-valid.patch
@@ -0,0 +1,27 @@
+From df5380ac8abfc615b4baa0d001afe0e605d34d9b Mon Sep 17 00:00:00 2001
+From: Miroslav Lichvar <mlichvar at redhat.com>
+Date: Wed, 27 Aug 2014 16:47:17 +0200
+Subject: [PATCH 02/12] timesyncd: check if stratum is valid
+
+(cherry picked from commit 07610e108e2d3f046da683a3a69c4d5cccd2cf8e)
+---
+ src/timesync/timesyncd-manager.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index d80c72f..60f39c6 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -574,7 +574,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ return manager_connect(m);
+ }
+
+- if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
++ if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC ||
++ ntpmsg.stratum == 0 || ntpmsg.stratum >= 16) {
+ log_debug("Server is not synchronized. Disconnecting.");
+ return manager_connect(m);
+ }
+--
+2.1.0
+
diff --git a/0003-timesyncd-fix-calculation-of-transmit-time.patch b/0003-timesyncd-fix-calculation-of-transmit-time.patch
new file mode 100644
index 0000000..323616c
--- /dev/null
+++ b/0003-timesyncd-fix-calculation-of-transmit-time.patch
@@ -0,0 +1,38 @@
+From 6840db7f47122699d420a80c2e6b6a34c7818759 Mon Sep 17 00:00:00 2001
+From: Miroslav Lichvar <mlichvar at redhat.com>
+Date: Wed, 27 Aug 2014 16:47:18 +0200
+Subject: [PATCH 03/12] timesyncd: fix calculation of transmit time
+
+The kernel timestamp (recv_time) is made earlier than current time
+(now_ts), use the timestamp captured before sending packet directly.
+
+(cherry picked from commit 73c76e6330d31e1d04454fd7408dd56b4eedca9f)
+---
+ src/timesync/timesyncd-manager.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 60f39c6..3339606 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -500,7 +500,6 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ .msg_namelen = sizeof(server_addr),
+ };
+ struct cmsghdr *cmsg;
+- struct timespec now_ts;
+ struct timeval *recv_time;
+ ssize_t len;
+ double origin, receive, trans, dest;
+@@ -613,8 +612,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ * The round-trip delay, d, and system clock offset, t, are defined as:
+ * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
+ */
+- assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0);
+- origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
++ origin = ts_to_d(&m->trans_time) + OFFSET_1900_1970;
+ receive = ntp_ts_to_d(&ntpmsg.recv_time);
+ trans = ntp_ts_to_d(&ntpmsg.trans_time);
+ dest = tv_to_d(recv_time) + OFFSET_1900_1970;
+--
+2.1.0
+
diff --git a/0004-timesyncd-get-kernel-timestamp-in-nanoseconds.patch b/0004-timesyncd-get-kernel-timestamp-in-nanoseconds.patch
new file mode 100644
index 0000000..53e59d3
--- /dev/null
+++ b/0004-timesyncd-get-kernel-timestamp-in-nanoseconds.patch
@@ -0,0 +1,66 @@
+From 6ec4258a64383467322da227adfe4780a4777f3a Mon Sep 17 00:00:00 2001
+From: Miroslav Lichvar <mlichvar at redhat.com>
+Date: Wed, 27 Aug 2014 16:47:19 +0200
+Subject: [PATCH 04/12] timesyncd: get kernel timestamp in nanoseconds
+
+(cherry picked from commit 487a36821ea214a73e1d0dcbd6d84123b50d1135)
+---
+ src/timesync/timesyncd-manager.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 3339606..2b0580c 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -136,10 +136,6 @@ static double ts_to_d(const struct timespec *ts) {
+ return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
+ }
+
+-static double tv_to_d(const struct timeval *tv) {
+- return tv->tv_sec + (1.0e-6 * tv->tv_usec);
+-}
+-
+ static double square(double d) {
+ return d * d;
+ }
+@@ -500,7 +496,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ .msg_namelen = sizeof(server_addr),
+ };
+ struct cmsghdr *cmsg;
+- struct timeval *recv_time;
++ struct timespec *recv_time;
+ ssize_t len;
+ double origin, receive, trans, dest;
+ double delay, offset;
+@@ -543,8 +539,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ continue;
+
+ switch (cmsg->cmsg_type) {
+- case SCM_TIMESTAMP:
+- recv_time = (struct timeval *) CMSG_DATA(cmsg);
++ case SCM_TIMESTAMPNS:
++ recv_time = (struct timespec *) CMSG_DATA(cmsg);
+ break;
+ }
+ }
+@@ -615,7 +611,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ origin = ts_to_d(&m->trans_time) + OFFSET_1900_1970;
+ receive = ntp_ts_to_d(&ntpmsg.recv_time);
+ trans = ntp_ts_to_d(&ntpmsg.trans_time);
+- dest = tv_to_d(recv_time) + OFFSET_1900_1970;
++ dest = ts_to_d(recv_time) + OFFSET_1900_1970;
+
+ offset = ((receive - origin) + (trans - dest)) / 2;
+ delay = (dest - origin) - (trans - receive);
+@@ -697,7 +693,7 @@ static int manager_listen_setup(Manager *m) {
+ if (r < 0)
+ return -errno;
+
+- r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
++ r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMPNS, &on, sizeof(on));
+ if (r < 0)
+ return -errno;
+
+--
+2.1.0
+
diff --git a/0005-timesyncd-check-root-distance.patch b/0005-timesyncd-check-root-distance.patch
new file mode 100644
index 0000000..a850bc5
--- /dev/null
+++ b/0005-timesyncd-check-root-distance.patch
@@ -0,0 +1,82 @@
+From 60bfbd03ff57e6096b13c292ff33fd5570508a05 Mon Sep 17 00:00:00 2001
+From: Miroslav Lichvar <mlichvar at redhat.com>
+Date: Wed, 27 Aug 2014 16:47:20 +0200
+Subject: [PATCH 05/12] timesyncd: check root distance
+
+NTPv4 servers don't reply with unsynchronized status when they lost
+synchronization, they only keep increasing the root dispersion and it's
+up to the client to decide at which point they no longer consider it
+synchronized.
+
+Ignore replies with root distance over 5 seconds.
+
+(cherry picked from commit 3af0442c52090f34ae7a1c8e6b6587c540c06896)
+---
+ src/timesync/timesyncd-manager.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 2b0580c..9b8b7d3 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -89,6 +89,9 @@
+ #define NTP_FIELD_MODE(f) ((f) & 7)
+ #define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
+
++/* Maximum acceptable root distance in seconds. */
++#define NTP_MAX_ROOT_DISTANCE 5.0
++
+ /*
+ * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
+ * in seconds relative to 0h on 1 January 1900."
+@@ -128,6 +131,10 @@ struct ntp_msg {
+ static int manager_arm_timer(Manager *m, usec_t next);
+ static int manager_clock_watch_setup(Manager *m);
+
++static double ntp_ts_short_to_d(const struct ntp_ts_short *ts) {
++ return be16toh(ts->sec) + (be16toh(ts->frac) / 65536.0);
++}
++
+ static double ntp_ts_to_d(const struct ntp_ts *ts) {
+ return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
+ }
+@@ -500,6 +507,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ ssize_t len;
+ double origin, receive, trans, dest;
+ double delay, offset;
++ double root_distance;
+ bool spike;
+ int leap_sec;
+ int r;
+@@ -585,6 +593,12 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ return manager_connect(m);
+ }
+
++ root_distance = ntp_ts_short_to_d(&ntpmsg.root_delay) / 2 + ntp_ts_short_to_d(&ntpmsg.root_dispersion);
++ if (root_distance > NTP_MAX_ROOT_DISTANCE) {
++ log_debug("Server has too large root distance. Disconnecting.");
++ return manager_connect(m);
++ }
++
+ /* valid packet */
+ m->pending = false;
+ m->retry_interval = 0;
+@@ -626,6 +640,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ " mode : %u\n"
+ " stratum : %u\n"
+ " precision : %.6f sec (%d)\n"
++ " root distance: %.6f sec\n"
+ " reference : %.4s\n"
+ " origin : %.3f\n"
+ " receive : %.3f\n"
+@@ -641,6 +656,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ NTP_FIELD_MODE(ntpmsg.field),
+ ntpmsg.stratum,
+ exp2(ntpmsg.precision), ntpmsg.precision,
++ root_distance,
+ ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
+ origin - OFFSET_1900_1970,
+ receive - OFFSET_1900_1970,
+--
+2.1.0
+
diff --git a/0006-timesyncd-manager-don-t-clear-current_server_name-if.patch b/0006-timesyncd-manager-don-t-clear-current_server_name-if.patch
new file mode 100644
index 0000000..2c6700b
--- /dev/null
+++ b/0006-timesyncd-manager-don-t-clear-current_server_name-if.patch
@@ -0,0 +1,35 @@
+From 8573eb093a4ccd6e966b60a68236f403dbd67d56 Mon Sep 17 00:00:00 2001
+From: Steven Noonan <steven at uplinklabs.net>
+Date: Sat, 30 Aug 2014 05:58:06 -0700
+Subject: [PATCH 06/12] timesyncd-manager: don't clear current_server_name if
+ ServerAddress is NULL
+
+https://bugs.freedesktop.org/show_bug.cgi?id=83091
+
+[zj: add comment]
+
+(cherry picked from commit 20f8d3cf1be4ad76234ffb85eeae7f9892ee72cd)
+---
+ src/timesync/timesyncd-manager.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 9b8b7d3..696dd10 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -766,8 +766,11 @@ void manager_set_server_address(Manager *m, ServerAddress *a) {
+ if (m->current_server_address == a)
+ return;
+
+- m->current_server_name = a ? a->name : NULL;
+ m->current_server_address = a;
++ /* If a is NULL, we are just clearing the address, without
++ * changing the name. Keep the existing name in that case. */
++ if (a)
++ m->current_server_name = a->name;
+
+ manager_disconnect(m);
+
+--
+2.1.0
+
diff --git a/0007-timesyncd-wait-before-reconnecting-to-first-server.patch b/0007-timesyncd-wait-before-reconnecting-to-first-server.patch
new file mode 100644
index 0000000..8cdcf97
--- /dev/null
+++ b/0007-timesyncd-wait-before-reconnecting-to-first-server.patch
@@ -0,0 +1,88 @@
+From 6aa136216f2f78a840215e53ababeea7b65fc061 Mon Sep 17 00:00:00 2001
+From: Miroslav Lichvar <mlichvar at redhat.com>
+Date: Wed, 27 Aug 2014 16:47:24 +0200
+Subject: [PATCH 07/12] timesyncd: wait before reconnecting to first server
+
+When all servers are exhausted, wait for one poll interval before trying
+to connect again to the first server in the list. Also, keep increasing
+the polling interval to make sure a client not getting any valid replies
+will not send requests to any server more frequently than is allowed by
+the maximum polling interval.
+
+(cherry picked from commit 63463bf091949e0178b749016828ec400c106582)
+---
+ src/timesync/timesyncd-manager.c | 24 +++++++++++++++++++++++-
+ src/timesync/timesyncd-manager.h | 1 +
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 696dd10..b7b39ef 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -875,6 +875,7 @@ int manager_connect(Manager *m) {
+ manager_set_server_name(m, m->current_server_name->names_next);
+ else {
+ ServerName *f;
++ bool restart = true;
+
+ /* Our current server name list is exhausted,
+ * let's find the next one to iterate. First
+@@ -891,6 +892,8 @@ int manager_connect(Manager *m) {
+ f = m->link_servers;
+ if (!f)
+ f = m->system_servers;
++ else
++ restart = false;
+ }
+
+ if (!f)
+@@ -902,6 +905,25 @@ int manager_connect(Manager *m) {
+ return 0;
+ }
+
++ if (restart && !m->exhausted_servers && m->poll_interval_usec) {
++ log_debug("Waiting after exhausting servers.");
++ r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + m->poll_interval_usec, 0, manager_retry_connect, m);
++ if (r < 0) {
++ log_error("Failed to create retry timer: %s", strerror(-r));
++ return r;
++ }
++
++ m->exhausted_servers = true;
++
++ /* Increase the polling interval */
++ if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
++ m->poll_interval_usec *= 2;
++
++ return 0;
++ }
++
++ m->exhausted_servers = false;
++
+ manager_set_server_name(m, f);
+ }
+
+@@ -1042,7 +1064,7 @@ static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t re
+ online = network_is_online();
+
+ /* check if the client is currently connected */
+- connected = m->server_socket >= 0 || m->resolve_query;
++ connected = m->server_socket >= 0 || m->resolve_query || m->exhausted_servers;
+
+ if (connected && !online) {
+ log_info("No network connectivity, watching for changes.");
+diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
+index 2345bf8..bb3e509 100644
+--- a/src/timesync/timesyncd-manager.h
++++ b/src/timesync/timesyncd-manager.h
+@@ -41,6 +41,7 @@ struct Manager {
+ LIST_HEAD(ServerName, fallback_servers);
+
+ RateLimit ratelimit;
++ bool exhausted_servers;
+
+ /* network */
+ sd_event_source *network_event_source;
+--
+2.1.0
+
diff --git a/0008-timesyncd-remove-retry_timer-logic-which-is-covered-.patch b/0008-timesyncd-remove-retry_timer-logic-which-is-covered-.patch
new file mode 100644
index 0000000..9f5bea6
--- /dev/null
+++ b/0008-timesyncd-remove-retry_timer-logic-which-is-covered-.patch
@@ -0,0 +1,59 @@
+From aebe463f08041d5c38023b414153a79295a5457f Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay at vrfy.org>
+Date: Tue, 2 Sep 2014 14:27:00 +0200
+Subject: [PATCH 08/12] timesyncd: remove retry_timer logic which is covered by
+ the server timeout
+
+(cherry picked from commit 665c6a9eab46b0b253af6566ca9fc70c866b3fcd)
+---
+ src/timesync/timesyncd-manager.c | 14 --------------
+ src/timesync/timesyncd-manager.h | 1 -
+ 2 files changed, 15 deletions(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index b7b39ef..19a28f3 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -206,19 +206,6 @@ static int manager_send_request(Manager *m) {
+ return manager_connect(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)
+- m->retry_interval *= 2;
+- } else
+- m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+-
+- r = manager_arm_timer(m, m->retry_interval);
+- if (r < 0) {
+- log_error("Failed to rearm timer: %s", strerror(-r));
+- return r;
+- }
+-
+ r = sd_event_add_time(
+ m->event,
+ &m->event_timeout,
+@@ -601,7 +588,6 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+
+ /* valid packet */
+ m->pending = false;
+- m->retry_interval = 0;
+
+ /* announce leap seconds */
+ if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
+diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
+index bb3e509..0ac0e17 100644
+--- a/src/timesync/timesyncd-manager.h
++++ b/src/timesync/timesyncd-manager.h
+@@ -59,7 +59,6 @@ struct Manager {
+ /* last sent packet */
+ struct timespec trans_time_mon;
+ struct timespec trans_time;
+- usec_t retry_interval;
+ bool pending;
+
+ /* poll timer */
+--
+2.1.0
+
diff --git a/0009-timesyncd-allow-two-missed-replies-before-reselectin.patch b/0009-timesyncd-allow-two-missed-replies-before-reselectin.patch
new file mode 100644
index 0000000..5b76446
--- /dev/null
+++ b/0009-timesyncd-allow-two-missed-replies-before-reselectin.patch
@@ -0,0 +1,90 @@
+From e558311df376973727c9924c1416a2101e55673d Mon Sep 17 00:00:00 2001
+From: Miroslav Lichvar <mlichvar at redhat.com>
+Date: Tue, 2 Sep 2014 14:29:51 +0200
+Subject: [PATCH 09/12] timesyncd: allow two missed replies before reselecting
+ server
+
+After receiving a reply from the server, allow two missed replies before
+switching to another server to avoid unnecessary clock hopping when
+packets are getting lost in the network.
+
+(cherry picked from commit e8206972be6a7ebeb198cd0d400bc7a94a6a5fc5)
+---
+ src/timesync/timesyncd-manager.c | 27 ++++++++++++++++++---------
+ src/timesync/timesyncd-manager.h | 1 +
+ 2 files changed, 19 insertions(+), 9 deletions(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 19a28f3..a66852d 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -92,6 +92,9 @@
+ /* Maximum acceptable root distance in seconds. */
+ #define NTP_MAX_ROOT_DISTANCE 5.0
+
++/* Maximum number of missed replies before selecting another source. */
++#define NTP_MAX_MISSED_REPLIES 2
++
+ /*
+ * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
+ * in seconds relative to 0h on 1 January 1900."
+@@ -206,15 +209,18 @@ static int manager_send_request(Manager *m) {
+ return manager_connect(m);
+ }
+
+- r = sd_event_add_time(
+- m->event,
+- &m->event_timeout,
+- clock_boottime_or_monotonic(),
+- now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0,
+- manager_timeout, m);
+- if (r < 0) {
+- log_error("Failed to arm timeout timer: %s", strerror(-r));
+- return r;
++ m->missed_replies++;
++ if (m->missed_replies > NTP_MAX_MISSED_REPLIES) {
++ r = sd_event_add_time(
++ m->event,
++ &m->event_timeout,
++ clock_boottime_or_monotonic(),
++ now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0,
++ manager_timeout, m);
++ if (r < 0) {
++ log_error("Failed to arm timeout timer: %s", strerror(-r));
++ return r;
++ }
+ }
+
+ return 0;
+@@ -549,6 +555,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+ return 0;
+ }
+
++ m->missed_replies = 0;
++
+ /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
+ if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
+ be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
+@@ -712,6 +720,7 @@ static int manager_begin(Manager *m) {
+ assert_return(m->current_server_name, -EHOSTUNREACH);
+ assert_return(m->current_server_address, -EHOSTUNREACH);
+
++ m->missed_replies = NTP_MAX_MISSED_REPLIES;
+ m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+
+ server_address_pretty(m->current_server_address, &pretty);
+diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
+index 0ac0e17..8296d41 100644
+--- a/src/timesync/timesyncd-manager.h
++++ b/src/timesync/timesyncd-manager.h
+@@ -53,6 +53,7 @@ struct Manager {
+ ServerName *current_server_name;
+ ServerAddress *current_server_address;
+ int server_socket;
++ int missed_replies;
+ uint64_t packet_count;
+ sd_event_source *event_timeout;
+
+--
+2.1.0
+
diff --git a/0010-timesyncd-don-t-reset-polling-interval-when-reselect.patch b/0010-timesyncd-don-t-reset-polling-interval-when-reselect.patch
new file mode 100644
index 0000000..a16c58b
--- /dev/null
+++ b/0010-timesyncd-don-t-reset-polling-interval-when-reselect.patch
@@ -0,0 +1,30 @@
+From 0c4d8d57d2581ea8e90f5b22ac81b249b6b28671 Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay at vrfy.org>
+Date: Tue, 2 Sep 2014 14:33:59 +0200
+Subject: [PATCH 10/12] timesyncd: don't reset polling interval when
+ reselecting server
+
+Original patch from: Miroslav Lichvar <mlichvar at redhat.com>
+
+(cherry picked from commit 80cd2606b91ce2735a0609c6f964917cf12685aa)
+---
+ src/timesync/timesyncd-manager.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index a66852d..3261bc1 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -721,7 +721,8 @@ static int manager_begin(Manager *m) {
+ assert_return(m->current_server_address, -EHOSTUNREACH);
+
+ m->missed_replies = NTP_MAX_MISSED_REPLIES;
+- m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
++ if (m->poll_interval_usec == 0)
++ m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+
+ server_address_pretty(m->current_server_address, &pretty);
+ log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string);
+--
+2.1.0
+
diff --git a/0011-Revert-timesyncd-remove-retry_timer-logic-which-is-c.patch b/0011-Revert-timesyncd-remove-retry_timer-logic-which-is-c.patch
new file mode 100644
index 0000000..8a8d47c
--- /dev/null
+++ b/0011-Revert-timesyncd-remove-retry_timer-logic-which-is-c.patch
@@ -0,0 +1,66 @@
+From 1d282632e027281c81a97c2bf2d7a803553651dc Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay at vrfy.org>
+Date: Tue, 2 Sep 2014 15:28:56 +0200
+Subject: [PATCH 11/12] Revert "timesyncd: remove retry_timer logic which is
+ covered by the server timeout"
+
+This reverts commit 665c6a9eab46b0b253af6566ca9fc70c866b3fcd.
+
+On Tue, Sep 2, 2014 at 3:17 PM, Miroslav Lichvar <mlichvar at redhat.com> wrote:
+>
+> With the other patch allowing missed replies included it's now getting
+> stuck as there is no timer to send the 2nd and 3rd request.
+
+(cherry picked from commit ab4df227d466e881e4279821b5fc1563f0e7e933)
+---
+ src/timesync/timesyncd-manager.c | 14 ++++++++++++++
+ src/timesync/timesyncd-manager.h | 1 +
+ 2 files changed, 15 insertions(+)
+
+diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
+index 3261bc1..a5678cc 100644
+--- a/src/timesync/timesyncd-manager.c
++++ b/src/timesync/timesyncd-manager.c
+@@ -209,6 +209,19 @@ static int manager_send_request(Manager *m) {
+ return manager_connect(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)
++ m->retry_interval *= 2;
++ } else
++ m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
++
++ r = manager_arm_timer(m, m->retry_interval);
++ if (r < 0) {
++ log_error("Failed to rearm timer: %s", strerror(-r));
++ return r;
++ }
++
+ m->missed_replies++;
+ if (m->missed_replies > NTP_MAX_MISSED_REPLIES) {
+ r = sd_event_add_time(
+@@ -596,6 +609,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
+
+ /* valid packet */
+ m->pending = false;
++ m->retry_interval = 0;
+
+ /* announce leap seconds */
+ if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
+diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
+index 8296d41..c7efdc5 100644
+--- a/src/timesync/timesyncd-manager.h
++++ b/src/timesync/timesyncd-manager.h
+@@ -60,6 +60,7 @@ struct Manager {
+ /* last sent packet */
+ struct timespec trans_time_mon;
+ struct timespec trans_time;
++ usec_t retry_interval;
+ bool pending;
+
+ /* poll timer */
+--
+2.1.0
+
diff --git a/systemd.spec b/systemd.spec
index 08b41a5..87fde84 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -16,7 +16,7 @@
Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 216
-Release: 5%{?gitcommit:.git%{gitcommit}}%{?dist}
+Release: 6%{?gitcommit:.git%{gitcommit}}%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: A System and Service Manager
@@ -43,6 +43,18 @@ Source6: yum-protect-systemd.conf
# etc.
Patch0: 0001-resolved-Move-symlink-creation-from-tmpfiles-to-daem.patch
+# timesyncd patches from upstream to be nice to NTP pool
+Patch0002: 0002-timesyncd-check-if-stratum-is-valid.patch
+Patch0003: 0003-timesyncd-fix-calculation-of-transmit-time.patch
+Patch0004: 0004-timesyncd-get-kernel-timestamp-in-nanoseconds.patch
+Patch0005: 0005-timesyncd-check-root-distance.patch
+Patch0006: 0006-timesyncd-manager-don-t-clear-current_server_name-if.patch
+Patch0007: 0007-timesyncd-wait-before-reconnecting-to-first-server.patch
+Patch0008: 0008-timesyncd-remove-retry_timer-logic-which-is-covered-.patch
+Patch0009: 0009-timesyncd-allow-two-missed-replies-before-reselectin.patch
+Patch0010: 0010-timesyncd-don-t-reset-polling-interval-when-reselect.patch
+Patch0011: 0011-Revert-timesyncd-remove-retry_timer-logic-which-is-c.patch
+
# kernel-install patch for grubby, drop if grubby is obsolete
Patch1000: kernel-install-grubby.patch
@@ -802,6 +814,9 @@ getent passwd systemd-journal-upload >/dev/null 2>&1 || useradd -r -l -g systemd
%{_datadir}/systemd/gatewayd
%changelog
+* Wed Sep 10 2014 Michal Schmidt <mschmidt at redhat.com> - 216-6
+- Update timesyncd with patches to avoid hitting NTP pool too often.
+
* Tue Sep 09 2014 Michal Schmidt <mschmidt at redhat.com> - 216-5
- Use common CONFIGURE_OPTS for build2 and build3.
- Configure timesyncd with NTP servers from Fedora/RHEL vendor zone.
More information about the scm-commits
mailing list