From ec75e8e07a0ad972e0c40e0a187e15a8d4fb3d66 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Mar 2022 16:28:38 +0100 Subject: [PATCH] sd-event: add a single implementation of an event source that runs on clock changes We basically had the same code in three places. Let's unify it in a common helper function. event_add_time_change() might be something we should add to the official sd-event API sooner or later, given its general usefulness. --- src/core/manager.c | 13 ++-------- src/core/manager.h | 1 - src/libsystemd/sd-event/event-util.c | 39 ++++++++++++++++++++++++++++ src/libsystemd/sd-event/event-util.h | 2 ++ src/resolve/resolved-manager.c | 15 ++--------- src/timesync/timesyncd-manager.c | 14 +++------- src/timesync/timesyncd-manager.h | 1 - 7 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/core/manager.c b/src/core/manager.c index 4c59506ccb5..a4ff2c83555 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -39,6 +39,7 @@ #include "dirent-util.h" #include "env-util.h" #include "escape.h" +#include "event-util.h" #include "exec-util.h" #include "execute.h" #include "exit-status.h" @@ -406,13 +407,8 @@ static int manager_setup_time_change(Manager *m) { return 0; m->time_change_event_source = sd_event_source_disable_unref(m->time_change_event_source); - m->time_change_fd = safe_close(m->time_change_fd); - m->time_change_fd = time_change_fd(); - if (m->time_change_fd < 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); + r = event_add_time_change(m->event, &m->time_change_event_source, manager_dispatch_time_change_fd, m); if (r < 0) return log_error_errno(r, "Failed to create time change event source: %m"); @@ -421,8 +417,6 @@ static int manager_setup_time_change(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to set priority of time change event sources: %m"); - (void) sd_event_source_set_description(m->time_change_event_source, "manager-time-change"); - log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd."); return 0; @@ -820,7 +814,6 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager .notify_fd = -1, .cgroups_agent_fd = -1, .signal_fd = -1, - .time_change_fd = -1, .user_lookup_fds = { -1, -1 }, .private_listen_fd = -1, .dev_autofs_fd = -1, @@ -1509,7 +1502,6 @@ Manager* manager_free(Manager *m) { safe_close(m->signal_fd); safe_close(m->notify_fd); safe_close(m->cgroups_agent_fd); - safe_close(m->time_change_fd); safe_close_pair(m->user_lookup_fds); manager_close_ask_password(m); @@ -2913,7 +2905,6 @@ static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint Unit *u; assert(m); - assert(m->time_change_fd == fd); log_struct(LOG_DEBUG, "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR, diff --git a/src/core/manager.h b/src/core/manager.h index e5d988b7456..f9096cf3485 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -226,7 +226,6 @@ struct Manager { sd_event_source *sigchld_event_source; - int time_change_fd; sd_event_source *time_change_event_source; sd_event_source *timezone_change_event_source; diff --git a/src/libsystemd/sd-event/event-util.c b/src/libsystemd/sd-event/event-util.c index 0e53406a948..4d0d780741a 100644 --- a/src/libsystemd/sd-event/event-util.c +++ b/src/libsystemd/sd-event/event-util.c @@ -4,6 +4,7 @@ #include "event-source.h" #include "event-util.h" +#include "fd-util.h" #include "log.h" #include "string-util.h" @@ -121,3 +122,41 @@ int event_source_is_enabled(sd_event_source *s) { return sd_event_source_get_enabled(s, NULL); } + +int event_add_time_change(sd_event *e, sd_event_source **ret, sd_event_io_handler_t callback, void *userdata) { + _cleanup_(sd_event_source_disable_unrefp) sd_event_source *s = NULL; + _cleanup_close_ int fd = -1; + int r; + + assert(e); + + /* Allocates an IO event source that gets woken up whenever the clock changes. Needs to be recreated on each event */ + + fd = time_change_fd(); + if (fd < 0) + return fd; + + r = sd_event_add_io(e, &s, fd, EPOLLIN, callback, userdata); + if (r < 0) + return r; + + r = sd_event_source_set_io_fd_own(s, true); + if (r < 0) + return r; + + TAKE_FD(fd); + + r = sd_event_source_set_description(s, "time-change"); + if (r < 0) + return r; + + if (ret) + *ret = TAKE_PTR(s); + else { + r = sd_event_source_set_floating(s, true); + if (r < 0) + return r; + } + + return 0; +} diff --git a/src/libsystemd/sd-event/event-util.h b/src/libsystemd/sd-event/event-util.h index 64a41992449..abd043bdcc9 100644 --- a/src/libsystemd/sd-event/event-util.h +++ b/src/libsystemd/sd-event/event-util.h @@ -29,3 +29,5 @@ int event_reset_time_relative( bool force_reset); int event_source_disable(sd_event_source *s); int event_source_is_enabled(sd_event_source *s); + +int event_add_time_change(sd_event *e, sd_event_source **ret, sd_event_io_handler_t callback, void *userdata); diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 615431ebb7e..221d0afbdb9 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -13,6 +13,7 @@ #include "bus-polkit.h" #include "dirent-util.h" #include "dns-domain.h" +#include "event-util.h" #include "fd-util.h" #include "fileio.h" #include "hostname-util.h" @@ -338,28 +339,16 @@ static int on_clock_change(sd_event_source *source, int fd, uint32_t revents, vo } static int manager_clock_change_listen(Manager *m) { - _cleanup_close_ int fd = -1; int r; assert(m); m->clock_change_event_source = sd_event_source_disable_unref(m->clock_change_event_source); - fd = time_change_fd(); - if (fd < 0) - return log_error_errno(fd, "Failed to allocate clock change timer fd: %m"); - - r = sd_event_add_io(m->event, &m->clock_change_event_source, fd, EPOLLIN, on_clock_change, m); + r = event_add_time_change(m->event, &m->clock_change_event_source, on_clock_change, m); if (r < 0) return log_error_errno(r, "Failed to create clock change event source: %m"); - r = sd_event_source_set_io_fd_own(m->clock_change_event_source, true); - if (r < 0) - return log_error_errno(r, "Failed to pass ownership of clock fd to event source: %m"); - TAKE_FD(fd); - - (void) sd_event_source_set_description(m->clock_change_event_source, "clock-change"); - return 0; } diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c index 3ab08a0fd60..193d13742b6 100644 --- a/src/timesync/timesyncd-manager.c +++ b/src/timesync/timesyncd-manager.c @@ -14,6 +14,7 @@ #include "alloc-util.h" #include "dns-domain.h" +#include "event-util.h" #include "fd-util.h" #include "format-util.h" #include "fs-util.h" @@ -229,14 +230,9 @@ static int manager_clock_watch_setup(Manager *m) { assert(m); - m->event_clock_watch = sd_event_source_unref(m->event_clock_watch); - safe_close(m->clock_watch_fd); + m->event_clock_watch = sd_event_source_disable_unref(m->event_clock_watch); - m->clock_watch_fd = time_change_fd(); - if (m->clock_watch_fd < 0) - 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); + r = event_add_time_change(m->event, &m->event_clock_watch, manager_clock_watch, m); if (r < 0) return log_error_errno(r, "Failed to create clock watch event source: %m"); @@ -889,8 +885,7 @@ void manager_disconnect(Manager *m) { manager_listen_stop(m); - m->event_clock_watch = sd_event_source_unref(m->event_clock_watch); - m->clock_watch_fd = safe_close(m->clock_watch_fd); + m->event_clock_watch = sd_event_source_disable_unref(m->event_clock_watch); m->event_timeout = sd_event_source_unref(m->event_timeout); @@ -1089,7 +1084,6 @@ int manager_new(Manager **ret) { .connection_retry_usec = DEFAULT_CONNECTION_RETRY_USEC, .server_socket = -1, - .clock_watch_fd = -1, .ratelimit = (RateLimit) { RATELIMIT_INTERVAL_USEC, diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h index aceb0098cef..5368dba98c0 100644 --- a/src/timesync/timesyncd-manager.h +++ b/src/timesync/timesyncd-manager.h @@ -92,7 +92,6 @@ struct Manager { /* watch for time changes */ sd_event_source *event_clock_watch; - int clock_watch_fd; /* Retry connections */ sd_event_source *event_retry;