[systemd/f21] Update timesyncd with patches to avoid hitting NTP pool too often

Michal Schmidt michich at fedoraproject.org
Wed Sep 10 18:54:12 UTC 2014


commit 5a725fc56f25cb522cc6e8267eabe312986d8c94
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Sep 10 20:19:29 2014 +0200

    Update timesyncd with patches to avoid hitting NTP pool too often

 0083-Added-arch-tuple-for-PPC64LE.patch            |    2 +-
 ...stem_create-do-not-try-to-create-root-if-.patch |    2 +-
 ...e-etc.service-ignore-return-code-of-daemo.patch |    2 +-
 0086-sd-event-add-support-for-CLOCK_BOOTTIME.patch |  172 ++++++++++++++++++++
 ...time-util-add-clock_boottime_or_monotonic.patch |   68 ++++++++
 ...syncd-always-use-CLOCK_BOOTTIME-if-we-can.patch |   80 +++++++++
 0089-timesyncd-check-if-stratum-is-valid.patch     |   29 ++++
 ...imesyncd-fix-calculation-of-transmit-time.patch |   40 +++++
 ...syncd-get-kernel-timestamp-in-nanoseconds.patch |   68 ++++++++
 0092-timesyncd-check-root-distance.patch           |   84 ++++++++++
 ...-wait-before-reconnecting-to-first-server.patch |   83 ++++++++++
 ...llow-two-missed-replies-before-reselectin.patch |   94 +++++++++++
 ...on-t-reset-polling-interval-when-reselect.patch |   32 ++++
 systemd.spec                                       |   15 ++-
 14 files changed, 767 insertions(+), 4 deletions(-)
---
diff --git a/0083-Added-arch-tuple-for-PPC64LE.patch b/0083-Added-arch-tuple-for-PPC64LE.patch
index c3116f3..e1ca8da 100644
--- a/0083-Added-arch-tuple-for-PPC64LE.patch
+++ b/0083-Added-arch-tuple-for-PPC64LE.patch
@@ -10,7 +10,7 @@ guys, that this is correct and provided the patch.
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/shared/architecture.h b/src/shared/architecture.h
-index 4821d5d..ee50ff4 100644
+index 4821d5d289..ee50ff4bab 100644
 --- a/src/shared/architecture.h
 +++ b/src/shared/architecture.h
 @@ -85,7 +85,7 @@ Architecture uname_architecture(void);
diff --git a/0084-base_filesystem_create-do-not-try-to-create-root-if-.patch b/0084-base_filesystem_create-do-not-try-to-create-root-if-.patch
index f441256..8788ed4 100644
--- a/0084-base_filesystem_create-do-not-try-to-create-root-if-.patch
+++ b/0084-base_filesystem_create-do-not-try-to-create-root-if-.patch
@@ -19,7 +19,7 @@ This patch checks for existance not only in the symlink case.
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
-index addd26c..ba8b829 100644
+index addd26ca39..ba8b829ab3 100644
 --- a/src/shared/base-filesystem.c
 +++ b/src/shared/base-filesystem.c
 @@ -62,13 +62,13 @@ int base_filesystem_create(const char *root) {
diff --git a/0085-initrd-parse-etc.service-ignore-return-code-of-daemo.patch b/0085-initrd-parse-etc.service-ignore-return-code-of-daemo.patch
index ba8385a..9890507 100644
--- a/0085-initrd-parse-etc.service-ignore-return-code-of-daemo.patch
+++ b/0085-initrd-parse-etc.service-ignore-return-code-of-daemo.patch
@@ -13,7 +13,7 @@ the initrd.
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/units/initrd-parse-etc.service.in b/units/initrd-parse-etc.service.in
-index c0b2543..42c059b 100644
+index c0b25430bc..42c059bbd2 100644
 --- a/units/initrd-parse-etc.service.in
 +++ b/units/initrd-parse-etc.service.in
 @@ -16,7 +16,7 @@ ConditionPathExists=/etc/initrd-release
diff --git a/0086-sd-event-add-support-for-CLOCK_BOOTTIME.patch b/0086-sd-event-add-support-for-CLOCK_BOOTTIME.patch
new file mode 100644
index 0000000..24460ee
--- /dev/null
+++ b/0086-sd-event-add-support-for-CLOCK_BOOTTIME.patch
@@ -0,0 +1,172 @@
+From df1b5312d9bc17853d51a37d01319164ed4e0dc5 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 20:34:09 +0200
+Subject: [PATCH] sd-event: add support for CLOCK_BOOTTIME
+
+Upstream commit:
+commit a854881616afbe4c4f55396d3fc2f922bbbe716b
+Author: Tom Gundersen <teg at jklm.no>
+Date:   Thu Jul 24 16:08:07 2014 +0200
+
+    sd-event: add support for CLOCK_BOOTTIME
+
+    This requires a very recent kernel (3.15), so care should be taken
+    when using this functionality.
+---
+ src/libsystemd/sd-event/sd-event.c | 35 +++++++++++++++++++++++++++++++----
+ 1 file changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
+index 53f1904d3d..ecab8f0a55 100644
+--- a/src/libsystemd/sd-event/sd-event.c
++++ b/src/libsystemd/sd-event/sd-event.c
+@@ -43,6 +43,7 @@
+ typedef enum EventSourceType {
+         SOURCE_IO,
+         SOURCE_TIME_REALTIME,
++        SOURCE_TIME_BOOTTIME,
+         SOURCE_TIME_MONOTONIC,
+         SOURCE_TIME_REALTIME_ALARM,
+         SOURCE_TIME_BOOTTIME_ALARM,
+@@ -56,7 +57,7 @@ typedef enum EventSourceType {
+         _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
+ } EventSourceType;
+ 
+-#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
++#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
+ 
+ struct sd_event_source {
+         unsigned n_ref;
+@@ -142,10 +143,11 @@ struct sd_event {
+         Prioq *pending;
+         Prioq *prepare;
+ 
+-        /* timerfd_create() only supports these four clocks so far. We
++        /* timerfd_create() only supports these five clocks so far. We
+          * can add support for more clocks when the kernel learns to
+          * deal with them, too. */
+         struct clock_data realtime;
++        struct clock_data boottime;
+         struct clock_data monotonic;
+         struct clock_data realtime_alarm;
+         struct clock_data boottime_alarm;
+@@ -377,6 +379,7 @@ static void event_free(sd_event *e) {
+         safe_close(e->watchdog_fd);
+ 
+         free_clock_data(&e->realtime);
++        free_clock_data(&e->boottime);
+         free_clock_data(&e->monotonic);
+         free_clock_data(&e->realtime_alarm);
+         free_clock_data(&e->boottime_alarm);
+@@ -403,8 +406,8 @@ _public_ int sd_event_new(sd_event** ret) {
+                 return -ENOMEM;
+ 
+         e->n_ref = 1;
+-        e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
+-        e->realtime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = (usec_t) -1;
++        e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
++        e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = (usec_t) -1;
+         e->original_pid = getpid();
+         e->perturb = (usec_t) -1;
+ 
+@@ -517,6 +520,9 @@ static clockid_t event_source_type_to_clock(EventSourceType t) {
+         case SOURCE_TIME_REALTIME:
+                 return CLOCK_REALTIME;
+ 
++        case SOURCE_TIME_BOOTTIME:
++                return CLOCK_BOOTTIME;
++
+         case SOURCE_TIME_MONOTONIC:
+                 return CLOCK_MONOTONIC;
+ 
+@@ -538,6 +544,9 @@ static EventSourceType clock_to_event_source_type(clockid_t clock) {
+         case CLOCK_REALTIME:
+                 return SOURCE_TIME_REALTIME;
+ 
++        case CLOCK_BOOTTIME:
++                return SOURCE_TIME_BOOTTIME;
++
+         case CLOCK_MONOTONIC:
+                 return SOURCE_TIME_MONOTONIC;
+ 
+@@ -560,6 +569,9 @@ static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) {
+         case SOURCE_TIME_REALTIME:
+                 return &e->realtime;
+ 
++        case SOURCE_TIME_BOOTTIME:
++                return &e->boottime;
++
+         case SOURCE_TIME_MONOTONIC:
+                 return &e->monotonic;
+ 
+@@ -593,6 +605,7 @@ static void source_disconnect(sd_event_source *s) {
+                 break;
+ 
+         case SOURCE_TIME_REALTIME:
++        case SOURCE_TIME_BOOTTIME:
+         case SOURCE_TIME_MONOTONIC:
+         case SOURCE_TIME_REALTIME_ALARM:
+         case SOURCE_TIME_BOOTTIME_ALARM: {
+@@ -1382,6 +1395,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
+                         break;
+ 
+                 case SOURCE_TIME_REALTIME:
++                case SOURCE_TIME_BOOTTIME:
+                 case SOURCE_TIME_MONOTONIC:
+                 case SOURCE_TIME_REALTIME_ALARM:
+                 case SOURCE_TIME_BOOTTIME_ALARM: {
+@@ -1444,6 +1458,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
+                         break;
+ 
+                 case SOURCE_TIME_REALTIME:
++                case SOURCE_TIME_BOOTTIME:
+                 case SOURCE_TIME_MONOTONIC:
+                 case SOURCE_TIME_REALTIME_ALARM:
+                 case SOURCE_TIME_BOOTTIME_ALARM: {
+@@ -2002,6 +2017,7 @@ static int source_dispatch(sd_event_source *s) {
+                 break;
+ 
+         case SOURCE_TIME_REALTIME:
++        case SOURCE_TIME_BOOTTIME:
+         case SOURCE_TIME_MONOTONIC:
+         case SOURCE_TIME_REALTIME_ALARM:
+         case SOURCE_TIME_BOOTTIME_ALARM:
+@@ -2202,6 +2218,10 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
+         if (r < 0)
+                 goto finish;
+ 
++        r = event_arm_timer(e, &e->boottime);
++        if (r < 0)
++                goto finish;
++
+         r = event_arm_timer(e, &e->monotonic);
+         if (r < 0)
+                 goto finish;
+@@ -2236,6 +2256,8 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
+ 
+                 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME))
+                         r = flush_timer(e, e->realtime.fd, ev_queue[i].events, &e->realtime.next);
++                else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_BOOTTIME))
++                        r = flush_timer(e, e->boottime.fd, ev_queue[i].events, &e->boottime.next);
+                 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_MONOTONIC))
+                         r = flush_timer(e, e->monotonic.fd, ev_queue[i].events, &e->monotonic.next);
+                 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME_ALARM))
+@@ -2261,6 +2283,10 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
+         if (r < 0)
+                 goto finish;
+ 
++        r = process_timer(e, e->timestamp_boottime, &e->boottime);
++        if (r < 0)
++                goto finish;
++
+         r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
+         if (r < 0)
+                 goto finish;
+@@ -2366,6 +2392,7 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
+                 *usec = e->timestamp.monotonic;
+                 break;
+ 
++        case CLOCK_BOOTTIME:
+         case CLOCK_BOOTTIME_ALARM:
+                 *usec = e->timestamp_boottime;
+                 break;
diff --git a/0087-time-util-add-clock_boottime_or_monotonic.patch b/0087-time-util-add-clock_boottime_or_monotonic.patch
new file mode 100644
index 0000000..a25ac14
--- /dev/null
+++ b/0087-time-util-add-clock_boottime_or_monotonic.patch
@@ -0,0 +1,68 @@
+From 9ec9316b80b531793d27aea177f13d33adef22e8 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 20:34:36 +0200
+Subject: [PATCH] time-util: add clock_boottime_or_monotonic
+
+Upstream commit:
+commit 77ff2de999b7ea6b1b4a3a218fbd9d62bb07cd54
+Author: Tom Gundersen <teg at jklm.no>
+Date:   Thu Jul 24 18:36:37 2014 +0200
+
+    time-util: add clock_boottime_or_monotonic
+
+    CLOCK_BOOTTIME is not supported by timerfd on older kernels, so for the time beeing,
+    use this helper instead which will fallback to CLOCK_MONOTONIC if CLOCK_BOOTTIME is
+    not supported.
+
+Conflicts:
+	src/shared/time-util.c
+	src/shared/time-util.h
+---
+ src/shared/time-util.c | 19 +++++++++++++++++++
+ src/shared/time-util.h |  2 ++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/src/shared/time-util.c b/src/shared/time-util.c
+index 8e5de77757..d5c5217004 100644
+--- a/src/shared/time-util.c
++++ b/src/shared/time-util.c
+@@ -22,6 +22,7 @@
+ #include <time.h>
+ #include <string.h>
+ #include <sys/timex.h>
++#include <sys/timerfd.h>
+ 
+ #include "util.h"
+ #include "time-util.h"
+@@ -826,3 +827,21 @@ bool ntp_synced(void) {
+ 
+         return true;
+ }
++
++clockid_t clock_boottime_or_monotonic(void) {
++        static clockid_t clock = -1;
++        int fd;
++
++        if (clock != -1)
++                return clock;
++
++        fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
++        if (fd < 0)
++                clock = CLOCK_MONOTONIC;
++        else {
++                safe_close(fd);
++                clock = CLOCK_BOOTTIME;
++        }
++
++        return clock;
++}
+diff --git a/src/shared/time-util.h b/src/shared/time-util.h
+index 34ba6c11be..ad9a4fd44b 100644
+--- a/src/shared/time-util.h
++++ b/src/shared/time-util.h
+@@ -95,3 +95,5 @@ int parse_sec(const char *t, usec_t *usec);
+ int parse_nsec(const char *t, nsec_t *nsec);
+ 
+ bool ntp_synced(void);
++
++clockid_t clock_boottime_or_monotonic(void);
diff --git a/0088-timesyncd-always-use-CLOCK_BOOTTIME-if-we-can.patch b/0088-timesyncd-always-use-CLOCK_BOOTTIME-if-we-can.patch
new file mode 100644
index 0000000..cc01382
--- /dev/null
+++ b/0088-timesyncd-always-use-CLOCK_BOOTTIME-if-we-can.patch
@@ -0,0 +1,80 @@
+From 908c733f6676b0154b669d116aad80851d97d024 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 20:34:38 +0200
+Subject: [PATCH] timesyncd: always use CLOCK_BOOTTIME if we can
+
+Upstream commit:
+commit 6a5c7b7e41a036bfdc2474b4583fcfdd358a6db6
+Author: Lennart Poettering <lennart at poettering.net>
+Date:   Sun Aug 10 23:40:48 2014 +0200
+
+    timesyncd: always use CLOCK_BOOTTIME if we can
+
+    After all we want to compare a monotonically increasing clock with the
+    remote clock, hence we shouldn't ignore system suspend periods.
+---
+ src/timesync/timesyncd.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index 19af9f9b61..efe95442a6 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -245,7 +245,7 @@ static int manager_send_request(Manager *m) {
+          * The actual value does not matter, We do not care about the correct
+          * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
+          */
+-        assert_se(clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon) >= 0);
++        assert_se(clock_gettime(clock_boottime_or_monotonic(), &m->trans_time_mon) >= 0);
+         assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
+         ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
+         ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
+@@ -277,8 +277,8 @@ static int manager_send_request(Manager *m) {
+         r = sd_event_add_time(
+                         m->event,
+                         &m->event_timeout,
+-                        CLOCK_MONOTONIC,
+-                        now(CLOCK_MONOTONIC) + TIMEOUT_USEC, 0,
++                        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));
+@@ -308,7 +308,7 @@ static int manager_arm_timer(Manager *m, usec_t next) {
+         }
+ 
+         if (m->event_timer) {
+-                r = sd_event_source_set_time(m->event_timer, now(CLOCK_MONOTONIC) + next);
++                r = sd_event_source_set_time(m->event_timer, now(clock_boottime_or_monotonic()) + next);
+                 if (r < 0)
+                         return r;
+ 
+@@ -318,8 +318,8 @@ static int manager_arm_timer(Manager *m, usec_t next) {
+         return sd_event_add_time(
+                         m->event,
+                         &m->event_timer,
+-                        CLOCK_MONOTONIC,
+-                        now(CLOCK_MONOTONIC) + next, 0,
++                        clock_boottime_or_monotonic(),
++                        now(clock_boottime_or_monotonic()) + next, 0,
+                         manager_timer, m);
+ }
+ 
+@@ -677,7 +677,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_MONOTONIC, &now_ts) >= 0);
++        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;
+         receive = ntp_ts_to_d(&ntpmsg.recv_time);
+         trans = ntp_ts_to_d(&ntpmsg.trans_time);
+@@ -904,7 +904,7 @@ static int manager_connect(Manager *m) {
+         if (!ratelimit_test(&m->ratelimit)) {
+                 log_debug("Slowing down attempts to contact servers.");
+ 
+-                r = sd_event_add_time(m->event, &m->event_retry, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + RETRY_USEC, 0, manager_retry, m);
++                r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + RETRY_USEC, 0, manager_retry, m);
+                 if (r < 0) {
+                         log_error("Failed to create retry timer: %s", strerror(-r));
+                         return r;
diff --git a/0089-timesyncd-check-if-stratum-is-valid.patch b/0089-timesyncd-check-if-stratum-is-valid.patch
new file mode 100644
index 0000000..6eeffec
--- /dev/null
+++ b/0089-timesyncd-check-if-stratum-is-valid.patch
@@ -0,0 +1,29 @@
+From e5ef9861f95f46b0b6462b7c4de62cd470ead17f Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:00:56 +0200
+Subject: [PATCH] timesyncd: check if stratum is valid
+
+Upstream commit:
+commit 07610e108e2d3f046da683a3a69c4d5cccd2cf8e
+Author: Miroslav Lichvar <mlichvar at redhat.com>
+Date:   Wed Aug 27 16:47:17 2014 +0200
+
+    timesyncd: check if stratum is valid
+---
+ src/timesync/timesyncd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index efe95442a6..dc00b2f1f3 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -639,7 +639,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);
+         }
diff --git a/0090-timesyncd-fix-calculation-of-transmit-time.patch b/0090-timesyncd-fix-calculation-of-transmit-time.patch
new file mode 100644
index 0000000..a55b4cb
--- /dev/null
+++ b/0090-timesyncd-fix-calculation-of-transmit-time.patch
@@ -0,0 +1,40 @@
+From 355043d3d3778d4516ab410c7da461d53f0de0a9 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:10:05 +0200
+Subject: [PATCH] timesyncd: fix calculation of transmit time
+
+Upstream commit:
+commit 73c76e6330d31e1d04454fd7408dd56b4eedca9f
+Author: Miroslav Lichvar <mlichvar at redhat.com>
+Date:   Wed Aug 27 16:47:18 2014 +0200
+
+    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.
+---
+ src/timesync/timesyncd.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index dc00b2f1f3..d123f0a3fc 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -565,7 +565,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;
+@@ -678,8 +677,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;
diff --git a/0091-timesyncd-get-kernel-timestamp-in-nanoseconds.patch b/0091-timesyncd-get-kernel-timestamp-in-nanoseconds.patch
new file mode 100644
index 0000000..8d4d159
--- /dev/null
+++ b/0091-timesyncd-get-kernel-timestamp-in-nanoseconds.patch
@@ -0,0 +1,68 @@
+From 1cdb867fa07aa9a1fa698dd4eb8fa26e145eecf1 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:12:50 +0200
+Subject: [PATCH] timesyncd: get kernel timestamp in nanoseconds
+
+Upstream commit:
+commit 487a36821ea214a73e1d0dcbd6d84123b50d1135
+Author: Miroslav Lichvar <mlichvar at redhat.com>
+Date:   Wed Aug 27 16:47:19 2014 +0200
+
+    timesyncd: get kernel timestamp in nanoseconds
+---
+ src/timesync/timesyncd.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index d123f0a3fc..436aeaea56 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -144,10 +144,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;
+ }
+@@ -565,7 +561,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;
+@@ -608,8 +604,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;
+                 }
+         }
+@@ -680,7 +676,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);
+@@ -762,7 +758,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;
+ 
diff --git a/0092-timesyncd-check-root-distance.patch b/0092-timesyncd-check-root-distance.patch
new file mode 100644
index 0000000..0b34b6b
--- /dev/null
+++ b/0092-timesyncd-check-root-distance.patch
@@ -0,0 +1,84 @@
+From c5b5c6b8cbf326031ef2de87a2268ecb10a3a44c Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:13:40 +0200
+Subject: [PATCH] timesyncd: check root distance
+
+Upstream commit:
+commit 3af0442c52090f34ae7a1c8e6b6587c540c06896
+Author: Miroslav Lichvar <mlichvar at redhat.com>
+Date:   Wed Aug 27 16:47:20 2014 +0200
+
+    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.
+---
+ src/timesync/timesyncd.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index 436aeaea56..5187df58c2 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -91,6 +91,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."
+@@ -136,6 +139,10 @@ static int manager_clock_watch_setup(Manager *m);
+ static int manager_connect(Manager *m);
+ static void manager_disconnect(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);
+ }
+@@ -565,6 +572,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;
+@@ -650,6 +658,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;
+@@ -691,6 +705,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"
+@@ -706,6 +721,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,
diff --git a/0093-timesyncd-wait-before-reconnecting-to-first-server.patch b/0093-timesyncd-wait-before-reconnecting-to-first-server.patch
new file mode 100644
index 0000000..9ff04a4
--- /dev/null
+++ b/0093-timesyncd-wait-before-reconnecting-to-first-server.patch
@@ -0,0 +1,83 @@
+From 75d472e1a9a5bfbfc572443eece28322caef0792 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:44:24 +0200
+Subject: [PATCH] timesyncd: wait before reconnecting to first server
+
+Upstream commit:
+commit 63463bf091949e0178b749016828ec400c106582
+Author: Miroslav Lichvar <mlichvar at redhat.com>
+Date:   Wed Aug 27 16:47:24 2014 +0200
+
+    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.
+
+Conflicts:
+	src/timesync/timesyncd-manager.c
+---
+ src/timesync/timesyncd.c | 22 +++++++++++++++++++++-
+ src/timesync/timesyncd.h |  1 +
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index 5187df58c2..589c5ec521 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -935,12 +935,32 @@ static int manager_connect(Manager *m) {
+                 if (m->current_server_name && m->current_server_name->names_next)
+                         m->current_server_name = m->current_server_name->names_next;
+                 else {
++
+                         if (!m->servers) {
+                                 m->current_server_name = NULL;
+                                 log_debug("No server found.");
+                                 return 0;
+                         }
+ 
++                        if (!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, 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;
++
+                         m->current_server_name = m->servers;
+                 }
+ 
+@@ -1150,7 +1170,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 != -1);
++        connected = (m->server_socket != -1) || m->exhausted_servers;
+ 
+         if (connected && !online) {
+                 log_info("No network connectivity, watching for changes.");
+diff --git a/src/timesync/timesyncd.h b/src/timesync/timesyncd.h
+index 4afe4b9f5b..04d83f0cc9 100644
+--- a/src/timesync/timesyncd.h
++++ b/src/timesync/timesyncd.h
+@@ -49,6 +49,7 @@ struct Manager {
+         LIST_HEAD(ServerName, servers);
+ 
+         RateLimit ratelimit;
++        bool exhausted_servers;
+ 
+         /* network */
+         sd_event_source *network_event_source;
diff --git a/0094-timesyncd-allow-two-missed-replies-before-reselectin.patch b/0094-timesyncd-allow-two-missed-replies-before-reselectin.patch
new file mode 100644
index 0000000..9fff168
--- /dev/null
+++ b/0094-timesyncd-allow-two-missed-replies-before-reselectin.patch
@@ -0,0 +1,94 @@
+From 8269ab5ca37ca93f52ec1766d673e85887aa0ebe Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:55:59 +0200
+Subject: [PATCH] timesyncd: allow two missed replies before reselecting server
+
+Upstream commit:
+commit e8206972be6a7ebeb198cd0d400bc7a94a6a5fc5
+Author: Miroslav Lichvar <mlichvar at redhat.com>
+Date:   Tue Sep 2 14:29:51 2014 +0200
+
+    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.
+
+Conflicts:
+	src/timesync/timesyncd-manager.c
+---
+ src/timesync/timesyncd.c | 27 ++++++++++++++++++---------
+ src/timesync/timesyncd.h |  1 +
+ 2 files changed, 19 insertions(+), 9 deletions(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index 589c5ec521..7470f4db97 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -94,6 +94,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."
+@@ -277,15 +280,18 @@ static int manager_send_request(Manager *m) {
+                 return r;
+         }
+ 
+-        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;
+@@ -627,6 +633,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) {
+@@ -791,6 +799,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;
+ 
+         sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
+diff --git a/src/timesync/timesyncd.h b/src/timesync/timesyncd.h
+index 04d83f0cc9..bcd14f71f6 100644
+--- a/src/timesync/timesyncd.h
++++ b/src/timesync/timesyncd.h
+@@ -61,6 +61,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;
+ 
diff --git a/0095-timesyncd-don-t-reset-polling-interval-when-reselect.patch b/0095-timesyncd-don-t-reset-polling-interval-when-reselect.patch
new file mode 100644
index 0000000..972fceb
--- /dev/null
+++ b/0095-timesyncd-don-t-reset-polling-interval-when-reselect.patch
@@ -0,0 +1,32 @@
+From 4242ef948fb91a1e65e34078b25f419950fc79e8 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 10 Sep 2014 19:57:04 +0200
+Subject: [PATCH] timesyncd: don't reset polling interval when reselecting
+ server
+
+Upstream commit:
+commit 80cd2606b91ce2735a0609c6f964917cf12685aa
+Author: Kay Sievers <kay at vrfy.org>
+Date:   Tue Sep 2 14:33:59 2014 +0200
+
+    timesyncd: don't reset polling interval when reselecting server
+
+    Original patch from: Miroslav Lichvar <mlichvar at redhat.com>
+---
+ src/timesync/timesyncd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
+index 7470f4db97..19ab1cf999 100644
+--- a/src/timesync/timesyncd.c
++++ b/src/timesync/timesyncd.c
+@@ -800,7 +800,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;
+ 
+         sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
+         log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string);
diff --git a/systemd.spec b/systemd.spec
index ebf60f7..12f6347 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -16,7 +16,7 @@
 Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 Version:        215
-Release:        15%{?gitcommit:.git%{gitcommit}}%{?dist}
+Release:        16%{?gitcommit:.git%{gitcommit}}%{?dist}
 # For a breakdown of the licensing, see README
 License:        LGPLv2+ and MIT and GPLv2+
 Summary:        A System and Service Manager
@@ -124,6 +124,16 @@ Patch082:       0082-update-done-set-proper-selinux-context-for-.updated.patch
 Patch083:       0083-Added-arch-tuple-for-PPC64LE.patch
 Patch084:       0084-base_filesystem_create-do-not-try-to-create-root-if-.patch
 Patch085:       0085-initrd-parse-etc.service-ignore-return-code-of-daemo.patch
+Patch086:       0086-sd-event-add-support-for-CLOCK_BOOTTIME.patch
+Patch087:       0087-time-util-add-clock_boottime_or_monotonic.patch
+Patch088:       0088-timesyncd-always-use-CLOCK_BOOTTIME-if-we-can.patch
+Patch089:       0089-timesyncd-check-if-stratum-is-valid.patch
+Patch090:       0090-timesyncd-fix-calculation-of-transmit-time.patch
+Patch091:       0091-timesyncd-get-kernel-timestamp-in-nanoseconds.patch
+Patch092:       0092-timesyncd-check-root-distance.patch
+Patch093:       0093-timesyncd-wait-before-reconnecting-to-first-server.patch
+Patch094:       0094-timesyncd-allow-two-missed-replies-before-reselectin.patch
+Patch095:       0095-timesyncd-don-t-reset-polling-interval-when-reselect.patch
 
 # Presently not accepted upstream, but we disable systemd-resolved in
 # the presets anyways, and this unbreaks anaconda/lorax/livecd-creator
@@ -882,6 +892,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> - 215-16
+- Update timesyncd with patches to avoid hitting NTP pool too often.
+
 * Tue Sep 09 2014 Michal Schmidt <mschmidt at redhat.com> - 215-15
 - 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