mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
Merge pull request #33084 from DaanDeMeyer/cgroup-log
cgroup-util: Don't try to open pidfd for pids from cgroup.threads
This commit is contained in:
@@ -140,7 +140,7 @@ int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags) {
|
||||
|
||||
r = cg_read_pid(f, &pid, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_debug_errno(r, "Failed to read pid from cgroup item: %m");
|
||||
if (r == 0) {
|
||||
*ret = PIDREF_NULL;
|
||||
return 0;
|
||||
@@ -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;
|
||||
@@ -347,14 +352,14 @@ static int cg_kill_items(
|
||||
if (r == -ENOENT)
|
||||
break;
|
||||
if (r < 0)
|
||||
return RET_GATHER(ret, r);
|
||||
return RET_GATHER(ret, log_debug_errno(r, "Failed to enumerate cgroup items: %m"));
|
||||
|
||||
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, r);
|
||||
return RET_GATHER(ret, log_debug_errno(r, "Failed to read pidref from cgroup '%s': %m", path));
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
@@ -370,7 +375,7 @@ static int cg_kill_items(
|
||||
/* If we haven't killed this process yet, kill it */
|
||||
r = pidref_kill(&pidref, sig);
|
||||
if (r < 0 && r != -ESRCH)
|
||||
RET_GATHER(ret, r);
|
||||
RET_GATHER(ret, log_debug_errno(r, "Failed to kill process with pid " PID_FMT " from cgroup '%s': %m", pidref.pid, path));
|
||||
if (r >= 0) {
|
||||
if (flags & CGROUP_SIGCONT)
|
||||
(void) pidref_kill(&pidref, SIGCONT);
|
||||
@@ -409,6 +414,8 @@ int cg_kill(
|
||||
int r, ret;
|
||||
|
||||
r = cg_kill_items(path, sig, flags, s, log_kill, userdata, "cgroup.procs");
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to kill processes in cgroup '%s' item cgroup.procs: %m", path);
|
||||
if (r < 0 || sig != SIGKILL)
|
||||
return r;
|
||||
|
||||
@@ -423,9 +430,13 @@ 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 r;
|
||||
return log_debug_errno(r, "Failed to kill processes in cgroup '%s' item cgroup.threads: %m", path);
|
||||
|
||||
return r > 0 || ret > 0;
|
||||
}
|
||||
@@ -448,7 +459,7 @@ int cg_kill_kernel_sigkill(const char *path) {
|
||||
|
||||
r = write_string_file(killfile, "1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_debug_errno(r, "Failed to write to cgroup.kill for cgroup '%s': %m", path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -485,7 +496,7 @@ int cg_kill_recursive(
|
||||
r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
RET_GATHER(ret, r);
|
||||
RET_GATHER(ret, log_debug_errno(r, "Failed to enumerate cgroup '%s' subgroups: %m", path));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -495,7 +506,7 @@ int cg_kill_recursive(
|
||||
|
||||
r = cg_read_subgroup(d, &fn);
|
||||
if (r < 0) {
|
||||
RET_GATHER(ret, r);
|
||||
RET_GATHER(ret, log_debug_errno(r, "Failed to read subgroup from cgroup '%s': %m", path));
|
||||
break;
|
||||
}
|
||||
if (r == 0)
|
||||
@@ -506,6 +517,8 @@ int cg_kill_recursive(
|
||||
return -ENOMEM;
|
||||
|
||||
r = cg_kill_recursive(p, sig, flags, s, log_kill, userdata);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to recursively kill processes in cgroup '%s': %m", p);
|
||||
if (r != 0 && ret >= 0)
|
||||
ret = r;
|
||||
}
|
||||
@@ -514,7 +527,7 @@ int cg_kill_recursive(
|
||||
if (FLAGS_SET(flags, CGROUP_REMOVE)) {
|
||||
r = cg_rmdir(SYSTEMD_CGROUP_CONTROLLER, path);
|
||||
if (!IN_SET(r, -ENOENT, -EBUSY))
|
||||
RET_GATHER(ret, r);
|
||||
RET_GATHER(ret, log_debug_errno(r, "Failed to remove cgroup '%s': %m", path));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -54,7 +54,7 @@ int pidref_set_pid(PidRef *pidref, pid_t pid) {
|
||||
if (fd < 0) {
|
||||
/* Graceful fallback in case the kernel doesn't support pidfds or is out of fds */
|
||||
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno) && !ERRNO_IS_RESOURCE(errno))
|
||||
return -errno;
|
||||
return log_debug_errno(errno, "Failed to open pidfd for pid " PID_FMT ": %m", pid);
|
||||
|
||||
fd = -EBADF;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user