diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2024-05-29 22:03:38 +0200 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2024-05-30 10:30:36 +0200 |
commit | 8783355fd98448c08dae68e80da9580d74ea8687 (patch) | |
tree | 07721cdd68316b714ba51a9d111297ce842996dd /src/basic | |
parent | basic: Add debug logging for pidref_set_pid() (diff) | |
download | systemd-8783355fd98448c08dae68e80da9580d74ea8687.tar.xz systemd-8783355fd98448c08dae68e80da9580d74ea8687.zip |
cgroup-util: Don't try to open pidfd for pids from cgroup.threads
Opening pidfds for non thread group leaders only works from 6.9 onwards with PIDFD_THREAD. On
older kernels or without PIDFD_THREAD pidfd_open() fails with EINVAL. Since we might read non
thread group leader IDs from cgroup.threads, we introduce and set CGROUP_NO_PIDFD to avoid
trying open pidfd's for them and instead use the pid as is.
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/cgroup-util.c | 13 | ||||
-rw-r--r-- | src/basic/cgroup-util.h | 1 |
2 files changed, 12 insertions, 2 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index be7f7c787d..553ee6075a 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -149,6 +149,11 @@ int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags) { if (pid == 0) return -EREMOTE; + if (FLAGS_SET(flags, CGROUP_NO_PIDFD)) { + *ret = PIDREF_MAKE_FROM_PID(pid); + return 1; + } + r = pidref_set_pid(ret, pid); if (r >= 0) return 1; @@ -352,7 +357,7 @@ static int cg_kill_items( for (;;) { _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; - r = cg_read_pidref(f, &pidref, /* flags = */ 0); + r = cg_read_pidref(f, &pidref, flags); if (r < 0) return RET_GATHER(ret, log_debug_errno(r, "Failed to read pidref from cgroup '%s': %m", path)); if (r == 0) @@ -425,7 +430,11 @@ int cg_kill( if (r == 0) return ret; - r = cg_kill_items(path, sig, flags, s, log_kill, userdata, "cgroup.threads"); + /* Opening pidfds for non thread group leaders only works from 6.9 onwards with PIDFD_THREAD. On + * older kernels or without PIDFD_THREAD pidfd_open() fails with EINVAL. Since we might read non + * thread group leader IDs from cgroup.threads, we set CGROUP_NO_PIDFD to avoid trying open pidfd's + * for them and instead use the regular pid. */ + r = cg_kill_items(path, sig, flags|CGROUP_NO_PIDFD, s, log_kill, userdata, "cgroup.threads"); if (r < 0) return log_debug_errno(r, "Failed to kill processes in cgroup '%s' item cgroup.threads: %m", path); diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 29417b39ad..a8871785b6 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -188,6 +188,7 @@ typedef enum CGroupFlags { CGROUP_IGNORE_SELF = 1 << 1, CGROUP_REMOVE = 1 << 2, CGROUP_DONT_SKIP_UNMAPPED = 1 << 3, + CGROUP_NO_PIDFD = 1 << 4, } CGroupFlags; int cg_enumerate_processes(const char *controller, const char *path, FILE **ret); |