From f8371dbd56d27621932ecbe3f5c1246e925fd53a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Apr 2023 21:06:22 +0200 Subject: udev: port to DelegateSubgroup= --- src/udev/udevd.c | 59 ++++++------------------------------------ units/systemd-udevd.service.in | 1 + 2 files changed, 9 insertions(+), 51 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c56956c378..b3aabcaa1f 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1799,54 +1799,6 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static int create_subcgroup(char **ret) { - _cleanup_free_ char *cgroup = NULL, *subcgroup = NULL; - int r; - - if (getppid() != 1) - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Not invoked by PID1."); - - r = sd_booted(); - if (r < 0) - return log_debug_errno(r, "Failed to check if systemd is running: %m"); - if (r == 0) - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "systemd is not running."); - - /* Get our own cgroup, we regularly kill everything udev has left behind. - * We only do this on systemd systems, and only if we are directly spawned - * by PID1. Otherwise we are not guaranteed to have a dedicated cgroup. */ - - r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup); - if (r < 0) { - if (IN_SET(r, -ENOENT, -ENOMEDIUM)) - return log_debug_errno(r, "Dedicated cgroup not found: %m"); - return log_debug_errno(r, "Failed to get cgroup: %m"); - } - - r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, cgroup, "trusted.delegate"); - if (r == 0 || (r < 0 && ERRNO_IS_XATTR_ABSENT(r))) - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "The cgroup %s is not delegated to us.", cgroup); - if (r < 0) - return log_debug_errno(r, "Failed to read trusted.delegate attribute: %m"); - - /* We are invoked with our own delegated cgroup tree, let's move us one level down, so that we - * don't collide with the "no processes in inner nodes" rule of cgroups, when the service - * manager invokes the ExecReload= job in the .control/ subcgroup. */ - - subcgroup = path_join(cgroup, "/udev"); - if (!subcgroup) - return log_oom_debug(); - - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, subcgroup, 0); - if (r < 0) - return log_debug_errno(r, "Failed to create %s subcgroup: %m", subcgroup); - - log_debug("Created %s subcgroup.", subcgroup); - if (ret) - *ret = TAKE_PTR(subcgroup); - return 0; -} - static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent) { _cleanup_(manager_freep) Manager *manager = NULL; _cleanup_free_ char *cgroup = NULL; @@ -1854,8 +1806,6 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent) { assert(ret); - (void) create_subcgroup(&cgroup); - manager = new(Manager, 1); if (!manager) return log_oom(); @@ -1863,7 +1813,6 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent) { *manager = (Manager) { .inotify_fd = -EBADF, .worker_watch = PIPE_EBADF, - .cgroup = TAKE_PTR(cgroup), }; r = udev_ctrl_new_from_fd(&manager->ctrl, fd_ctrl); @@ -1895,6 +1844,14 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent) { manager->log_level = log_get_max_level(); + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup); + if (r < 0) + log_warning_errno(r, "Failed to get cgroup, ignoring: %m"); + else if (endswith(cgroup, "/udev")) { /* If we are in a subcgroup /udev/ we assume it was delegated to us */ + log_debug("Running in delegated subcgroup '%s'.", cgroup); + manager->cgroup = TAKE_PTR(cgroup); + } + *ret = TAKE_PTR(manager); return 0; diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in index dfc2a0e341..a0ee9e0a50 100644 --- a/units/systemd-udevd.service.in +++ b/units/systemd-udevd.service.in @@ -18,6 +18,7 @@ ConditionPathIsReadWrite=/sys [Service] CapabilityBoundingSet=~CAP_SYS_TIME CAP_WAKE_ALARM Delegate=pids +DelegateSubgroup=udev Type=notify-reload # Note that udev will reset the value internally for its workers OOMScoreAdjust=-1000 -- cgit v1.2.1