systemd/0326-udev-split-manager_init-and-manager_main-into-small-.patch
Jan Macku eb5b3a87a8 systemd-257-8
Resolves: RHEL-71409, RHEL-75774
2025-02-14 10:09:33 +01:00

311 lines
13 KiB
Diff

From b6876d46a4695c0626db089170ea28cb263d3cdb Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 22 Dec 2024 00:11:38 +0900
Subject: [PATCH] udev: split manager_init() and manager_main() into small
pieces
No functional change, just refactoring.
Co-authored-by: David Tardon <dtardon@redhat.com>
(cherry picked from commit 0079651876aa5df73fd787b272e91ae4a7898853)
Resolves: RHEL-75774
---
src/udev/udev-manager.c | 217 +++++++++++++++++++++++++++++-----------
1 file changed, 161 insertions(+), 56 deletions(-)
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 4fc316e106..d9bd9d6d7b 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -1232,32 +1232,66 @@ static int listen_fds(int *ret_ctrl, int *ret_netlink) {
return 0;
}
-int manager_init(Manager *manager) {
- _cleanup_close_ int fd_ctrl = -EBADF, fd_uevent = -EBADF;
- _cleanup_free_ char *cgroup = NULL;
+static int manager_init_ctrl(Manager *manager, int fd_ctrl) {
+ _cleanup_(udev_ctrl_unrefp) UdevCtrl *ctrl = NULL;
+ _cleanup_close_ int fd = fd_ctrl;
int r;
assert(manager);
- r = listen_fds(&fd_ctrl, &fd_uevent);
- if (r < 0)
- return log_error_errno(r, "Failed to listen on fds: %m");
+ /* This consumes passed file descriptor. */
- r = udev_ctrl_new_from_fd(&manager->ctrl, fd_ctrl);
+ r = udev_ctrl_new_from_fd(&ctrl, fd);
if (r < 0)
return log_error_errno(r, "Failed to initialize udev control socket: %m");
- TAKE_FD(fd_ctrl);
+ TAKE_FD(fd);
- r = udev_ctrl_enable_receiving(manager->ctrl);
+ r = udev_ctrl_enable_receiving(ctrl);
if (r < 0)
return log_error_errno(r, "Failed to bind udev control socket: %m");
- r = device_monitor_new_full(&manager->monitor, MONITOR_GROUP_KERNEL, fd_uevent);
+ manager->ctrl = TAKE_PTR(ctrl);
+ return 0;
+}
+
+static int manager_init_device_monitor(Manager *manager, int fd_uevent) {
+ _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
+ _cleanup_close_ int fd = fd_uevent;
+ int r;
+
+ assert(manager);
+
+ /* This consumes passed file descriptor. */
+
+ r = device_monitor_new_full(&monitor, MONITOR_GROUP_KERNEL, fd);
if (r < 0)
return log_error_errno(r, "Failed to initialize device monitor: %m");
- TAKE_FD(fd_uevent);
+ TAKE_FD(fd);
+
+ (void) sd_device_monitor_set_description(monitor, "manager");
+
+ manager->monitor = TAKE_PTR(monitor);
+ return 0;
+}
- (void) sd_device_monitor_set_description(manager->monitor, "manager");
+int manager_init(Manager *manager) {
+ _cleanup_close_ int fd_ctrl = -EBADF, fd_uevent = -EBADF;
+ _cleanup_free_ char *cgroup = NULL;
+ int r;
+
+ assert(manager);
+
+ r = listen_fds(&fd_ctrl, &fd_uevent);
+ if (r < 0)
+ return log_error_errno(r, "Failed to listen on fds: %m");
+
+ r = manager_init_ctrl(manager, TAKE_FD(fd_ctrl));
+ if (r < 0)
+ return r;
+
+ r = manager_init_device_monitor(manager, TAKE_FD(fd_uevent));
+ if (r < 0)
+ return r;
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
if (r < 0)
@@ -1270,95 +1304,166 @@ int manager_init(Manager *manager) {
return 0;
}
-int manager_main(Manager *manager) {
- int fd_worker, r;
+static int manager_start_ctrl(Manager *manager) {
+ int r;
+
+ assert(manager);
+ assert(manager->ctrl);
+
+ r = udev_ctrl_attach_event(manager->ctrl, manager->event);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach event to udev control: %m");
+
+ r = udev_ctrl_start(manager->ctrl, on_ctrl_msg, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start udev control: %m");
+
+ /* This needs to be after the inotify and uevent handling, to make sure that the ping is send back
+ * after fully processing the pending uevents (including the synthetic ones we may create due to
+ * inotify events). */
+ r = sd_event_source_set_priority(udev_ctrl_get_event_source(manager->ctrl), SD_EVENT_PRIORITY_IDLE);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set IDLE event priority for udev control event source: %m");
+
+ return 0;
+}
+
+static int manager_start_device_monitor(Manager *manager) {
+ int r;
+
+ assert(manager);
+ assert(manager->monitor);
+
+ r = sd_device_monitor_attach_event(manager->monitor, manager->event);
+ if (r < 0)
+ return log_error_errno(r, "Failed to attach event to device monitor: %m");
+
+ r = sd_device_monitor_start(manager->monitor, on_uevent, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start device monitor: %m");
+
+ return 0;
+}
+
+static int manager_start_inotify(Manager *manager) {
+ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
+ _cleanup_close_ int fd = -EBADF;
+ int r;
+
+ assert(manager);
+ assert(manager->event);
+
+ fd = inotify_init1(IN_CLOEXEC);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to create inotify descriptor: %m");
+
+ udev_watch_restore(fd);
+
+ r = sd_event_add_io(manager->event, &s, fd, EPOLLIN, on_inotify, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create inotify event source: %m");
+
+ (void) sd_event_source_set_description(s, "manager-inotify");
+
+ manager->inotify_fd = TAKE_FD(fd);
+ manager->inotify_event = TAKE_PTR(s);
+ return 0;
+}
+
+static int manager_start_worker_event(Manager *manager) {
+ int r;
+
+ assert(manager);
+ assert(manager->event);
/* unnamed socket from workers to the main daemon */
r = socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
if (r < 0)
return log_error_errno(errno, "Failed to create socketpair for communicating with workers: %m");
- fd_worker = manager->worker_watch[READ_END];
-
- r = setsockopt_int(fd_worker, SOL_SOCKET, SO_PASSCRED, true);
+ r = setsockopt_int(manager->worker_watch[READ_END], SOL_SOCKET, SO_PASSCRED, true);
if (r < 0)
return log_error_errno(r, "Failed to enable SO_PASSCRED: %m");
- manager->inotify_fd = inotify_init1(IN_CLOEXEC);
- if (manager->inotify_fd < 0)
- return log_error_errno(errno, "Failed to create inotify descriptor: %m");
+ r = sd_event_add_io(manager->event, NULL, manager->worker_watch[READ_END], EPOLLIN, on_worker, manager);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create worker event source: %m");
- udev_watch_restore(manager->inotify_fd);
+ return 0;
+}
+
+static int manager_setup_event(Manager *manager) {
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+ int r;
+
+ assert(manager);
/* block SIGCHLD for listening child events. */
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
- r = sd_event_default(&manager->event);
+ r = sd_event_default(&e);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
+ r = sd_event_add_signal(e, /* ret_event_source = */ NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGINT event source: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
+ r = sd_event_add_signal(e, /* ret_event_source = */ NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGTERM event source: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, on_sighup, manager);
+ r = sd_event_add_signal(e, /* ret_event_source = */ NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, on_sighup, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGHUP event source: %m");
- r = sd_event_set_watchdog(manager->event, true);
+ r = sd_event_add_post(e, /* ret_event_source = */ NULL, on_post, manager);
if (r < 0)
- return log_error_errno(r, "Failed to create watchdog event source: %m");
+ return log_error_errno(r, "Failed to create post event source: %m");
- r = udev_ctrl_attach_event(manager->ctrl, manager->event);
+ /* Eventually, we probably want to do more here on memory pressure, for example, kill idle workers immediately */
+ r = sd_event_add_memory_pressure(e, /* ret_event_source= */ NULL, /* callback= */ NULL, /* userdata= */ NULL);
if (r < 0)
- return log_error_errno(r, "Failed to attach event to udev control: %m");
+ log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to allocate memory pressure watch, ignoring: %m");
- r = udev_ctrl_start(manager->ctrl, on_ctrl_msg, manager);
+ r = sd_event_add_signal(e, /* ret_event_source= */ NULL,
+ (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, /* userdata= */ NULL);
if (r < 0)
- return log_error_errno(r, "Failed to start udev control: %m");
+ return log_error_errno(r, "Failed to allocate SIGRTMIN+18 event source, ignoring: %m");
- /* This needs to be after the inotify and uevent handling, to make sure
- * that the ping is send back after fully processing the pending uevents
- * (including the synthetic ones we may create due to inotify events).
- */
- r = sd_event_source_set_priority(udev_ctrl_get_event_source(manager->ctrl), SD_EVENT_PRIORITY_IDLE);
+ r = sd_event_set_watchdog(e, true);
if (r < 0)
- return log_error_errno(r, "Failed to set IDLE event priority for udev control event source: %m");
+ return log_error_errno(r, "Failed to create watchdog event source: %m");
- r = sd_event_add_io(manager->event, &manager->inotify_event, manager->inotify_fd, EPOLLIN, on_inotify, manager);
- if (r < 0)
- return log_error_errno(r, "Failed to create inotify event source: %m");
+ manager->event = TAKE_PTR(e);
+ return 0;
+}
- r = sd_device_monitor_attach_event(manager->monitor, manager->event);
- if (r < 0)
- return log_error_errno(r, "Failed to attach event to device monitor: %m");
+int manager_main(Manager *manager) {
+ int r;
- r = sd_device_monitor_start(manager->monitor, on_uevent, manager);
+ assert(manager);
+
+ r = manager_setup_event(manager);
if (r < 0)
- return log_error_errno(r, "Failed to start device monitor: %m");
+ return r;
- r = sd_event_add_io(manager->event, NULL, fd_worker, EPOLLIN, on_worker, manager);
+ r = manager_start_ctrl(manager);
if (r < 0)
- return log_error_errno(r, "Failed to create worker event source: %m");
+ return r;
- r = sd_event_add_post(manager->event, NULL, on_post, manager);
+ r = manager_start_device_monitor(manager);
if (r < 0)
- return log_error_errno(r, "Failed to create post event source: %m");
+ return r;
- /* Eventually, we probably want to do more here on memory pressure, for example, kill idle workers immediately */
- r = sd_event_add_memory_pressure(manager->event, /* ret_event_source= */ NULL, /* callback= */ NULL, /* userdata= */ NULL);
+ r = manager_start_inotify(manager);
if (r < 0)
- log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to allocate memory pressure watch, ignoring: %m");
+ return r;
- r = sd_event_add_signal(manager->event, /* ret_event_source= */ NULL,
- (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, /* userdata= */ NULL);
+ r = manager_start_worker_event(manager);
if (r < 0)
- return log_error_errno(r, "Failed to allocate SIGRTMIN+18 event source, ignoring: %m");
+ return r;
manager->last_usec = now(CLOCK_MONOTONIC);