From: Luca Boccassi Date: Wed, 1 Dec 2021 14:16:24 +0000 (+0000) Subject: core: support user manager with Condition[Memory/CPU/IO]Pressure X-Git-Tag: v250-rc1~92 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=68ee5d774cf4a83573ae401e021a0726dec0bb93;p=thirdparty%2Fsystemd.git core: support user manager with Condition[Memory/CPU/IO]Pressure Get the cgroup root path from the current PID, so that when ran by the user manager we can get to the right path. Eg: foo.slice:10% will check under: /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/foo.slice/cpu.pressure Follow-up for 81513b382b24a7f3602987f71042d075ca27d1a5 --- diff --git a/src/shared/condition.c b/src/shared/condition.c index 63bdc38a490..44e26775db8 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -45,6 +45,7 @@ #include "psi-util.h" #include "selinux-util.h" #include "smack-util.h" +#include "special.h" #include "stat-util.h" #include "string-table.h" #include "string-util.h" @@ -992,14 +993,14 @@ static int condition_test_psi(Condition *c, char **env) { if (r == 1) { pressure_path = path_join("/proc/pressure", pressure_type); if (!pressure_path) - return log_oom(); + return log_oom_debug(); value = first; } else { const char *controller = strjoina(pressure_type, ".pressure"); - _cleanup_free_ char *slice_path = NULL; + _cleanup_free_ char *slice_path = NULL, *root_scope = NULL; CGroupMask mask, required_mask; - char *slice; + char *slice, *e; required_mask = c->type == CONDITION_MEMORY_PRESSURE ? CGROUP_MASK_MEMORY : c->type == CONDITION_CPU_PRESSURE ? CGROUP_MASK_CPU : @@ -1030,6 +1031,26 @@ static int condition_test_psi(Condition *c, char **env) { if (r < 0) return log_debug_errno(r, "Cannot determine slice \"%s\" cgroup path: %m", slice); + /* We might be running under the user manager, so get the root path and prefix it accordingly. */ + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &root_scope); + if (r < 0) + return log_debug_errno(r, "Failed to get root cgroup path: %m"); + + /* Drop init.scope, we want the parent. We could get an empty or / path, but that's fine, + * just skip it in that case. */ + e = endswith(root_scope, "/" SPECIAL_INIT_SCOPE); + if (e) + *e = 0; + if (!empty_or_root(root_scope)) { + _cleanup_free_ char *slice_joined = NULL; + + slice_joined = path_join(root_scope, slice_path); + if (!slice_joined) + return log_oom_debug(); + + free_and_replace(slice_path, slice_joined); + } + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, slice_path, controller, &pressure_path); if (r < 0) return log_debug_errno(r, "Error getting cgroup pressure path from %s: %m", slice_path);