Update timesyncd with patches to avoid hitting NTP pool too often

This commit is contained in:
Michal Schmidt 2014-09-10 20:19:29 +02:00
parent a562db4b47
commit 5a725fc56f
14 changed files with 767 additions and 4 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -0,0 +1,172 @@
From df1b5312d9bc17853d51a37d01319164ed4e0dc5 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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;

View File

@ -0,0 +1,68 @@
From 9ec9316b80b531793d27aea177f13d33adef22e8 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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);

View File

@ -0,0 +1,80 @@
From 908c733f6676b0154b669d116aad80851d97d024 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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;

View File

@ -0,0 +1,29 @@
From e5ef9861f95f46b0b6462b7c4de62cd470ead17f Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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);
}

View File

@ -0,0 +1,40 @@
From 355043d3d3778d4516ab410c7da461d53f0de0a9 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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;

View File

@ -0,0 +1,68 @@
From 1cdb867fa07aa9a1fa698dd4eb8fa26e145eecf1 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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;

View File

@ -0,0 +1,84 @@
From c5b5c6b8cbf326031ef2de87a2268ecb10a3a44c Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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,

View File

@ -0,0 +1,83 @@
From 75d472e1a9a5bfbfc572443eece28322caef0792 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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;

View File

@ -0,0 +1,94 @@
From 8269ab5ca37ca93f52ec1766d673e85887aa0ebe Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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;

View File

@ -0,0 +1,32 @@
From 4242ef948fb91a1e65e34078b25f419950fc79e8 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@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@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@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);

View File

@ -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@redhat.com> - 215-16
- Update timesyncd with patches to avoid hitting NTP pool too often.
* Tue Sep 09 2014 Michal Schmidt <mschmidt@redhat.com> - 215-15
- Use common CONFIGURE_OPTS for build2 and build3.
- Configure timesyncd with NTP servers from Fedora/RHEL vendor zone.