[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