summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-05-29 12:55:33 +0200
committerLennart Poettering <lennart@poettering.net>2018-06-06 10:55:45 +0200
commit4f811d27d6d9324e65ce628fa20ac1761ef98de0 (patch)
treeb2673f25c2e521455ec92a2440cf1e86370ca1df
parentbbf5fd8e41b1abdf03c8ab463a2c9af7c7dc64d8 (diff)
downloadsystemd-4f811d27d6d9324e65ce628fa20ac1761ef98de0.tar.gz
time-util: introduce common implementation of TFD_TIMER_CANCEL_ON_SET client code
We now use pretty much the same code at three places, let's unify that.
-rw-r--r--src/basic/time-util.c24
-rw-r--r--src/basic/time-util.h2
-rw-r--r--src/core/manager.c20
-rw-r--r--src/time-wait-sync/time-wait-sync.c26
-rw-r--r--src/timesync/timesyncd-manager.c12
5 files changed, 40 insertions, 44 deletions
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index 671311e885..031b871640 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -1463,3 +1463,27 @@ bool in_utc_timezone(void) {
return timezone == 0 && daylight == 0;
}
+
+int time_change_fd(void) {
+
+ /* We only care for the cancellation event, hence we set the timeout to the latest possible value. */
+ static const struct itimerspec its = {
+ .it_value.tv_sec = TIME_T_MAX,
+ };
+
+ _cleanup_close_ int fd;
+
+ assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
+
+ /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever CLOCK_REALTIME makes a jump relative to
+ * CLOCK_MONOTONIC. */
+
+ fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0)
+ return -errno;
+
+ return TAKE_FD(fd);
+}
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
index f9c34a3e15..54aebfa36b 100644
--- a/src/basic/time-util.h
+++ b/src/basic/time-util.h
@@ -185,3 +185,5 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
#else
#error "Yuck, time_t is neither 4 nor 8 bytes wide?"
#endif
+
+int time_change_fd(void);
diff --git a/src/core/manager.c b/src/core/manager.c
index 0f767d651c..d2f628d2bb 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -353,14 +353,7 @@ static void manager_close_idle_pipe(Manager *m) {
static int manager_setup_time_change(Manager *m) {
int r;
- /* We only care for the cancellation event, hence we set the
- * timeout to the latest possible value. */
- struct itimerspec its = {
- .it_value.tv_sec = TIME_T_MAX,
- };
-
assert(m);
- assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
if (m->test_run_flags)
return 0;
@@ -368,18 +361,9 @@ static int manager_setup_time_change(Manager *m) {
m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
m->time_change_fd = safe_close(m->time_change_fd);
- /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
- * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
-
- m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+ m->time_change_fd = time_change_fd();
if (m->time_change_fd < 0)
- return log_error_errno(errno, "Failed to create timerfd: %m");
-
- if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
- log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
- m->time_change_fd = safe_close(m->time_change_fd);
- return 0;
- }
+ return log_error_errno(m->time_change_fd, "Failed to create timer change timer fd: %m");
r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
if (r < 0)
diff --git a/src/time-wait-sync/time-wait-sync.c b/src/time-wait-sync/time-wait-sync.c
index 198c055650..37b032b39e 100644
--- a/src/time-wait-sync/time-wait-sync.c
+++ b/src/time-wait-sync/time-wait-sync.c
@@ -115,16 +115,15 @@ static int inotify_handler(sd_event_source *s,
return 0;
}
-static int clock_state_update(ClockState *sp,
- sd_event *event) {
- static const struct itimerspec its = {
- .it_value.tv_sec = TIME_T_MAX,
- };
- int r;
- struct timex tx = {};
+static int clock_state_update(
+ ClockState *sp,
+ sd_event *event) {
+
char buf[MAX((size_t)FORMAT_TIMESTAMP_MAX, STRLEN("unrepresentable"))];
- usec_t t;
+ struct timex tx = {};
const char * ts;
+ usec_t t;
+ int r;
clock_state_release_timerfd(sp);
@@ -151,18 +150,13 @@ static int clock_state_update(ClockState *sp,
* it synchronized. When an NTP source is selected it sets the clock again with clock_adjtime(2) which marks it
* synchronized and also touches /run/systemd/timesync/synchronized which covers the case when the clock wasn't
* "set". */
- r = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
- if (r < 0) {
- log_error_errno(errno, "Failed to create timerfd: %m");
- goto finish;
- }
- sp->timerfd_fd = r;
- r = timerfd_settime(sp->timerfd_fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &its, NULL);
+ r = time_change_fd();
if (r < 0) {
- log_error_errno(errno, "Failed to set timerfd conditions: %m");
+ log_error_errno(r, "Failed to create timerfd: %m");
goto finish;
}
+ sp->timerfd_fd = r;
r = adjtimex(&tx);
if (r < 0) {
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index f76f07e655..46036c41f7 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -224,11 +224,6 @@ static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents
/* wake up when the system time changes underneath us */
static int manager_clock_watch_setup(Manager *m) {
-
- struct itimerspec its = {
- .it_value.tv_sec = TIME_T_MAX
- };
-
int r;
assert(m);
@@ -236,12 +231,9 @@ static int manager_clock_watch_setup(Manager *m) {
m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
safe_close(m->clock_watch_fd);
- m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+ m->clock_watch_fd = time_change_fd();
if (m->clock_watch_fd < 0)
- return log_error_errno(errno, "Failed to create timerfd: %m");
-
- if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0)
- return log_error_errno(errno, "Failed to set up timerfd: %m");
+ return log_error_errno(m->clock_watch_fd, "Failed to create timerfd: %m");
r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
if (r < 0)