1
0
mirror of https://github.com/systemd/systemd synced 2026-03-29 19:24:50 +02:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Luca Boccassi
dff4fb7c35 test: skip test-loop-block udev part in chroot too
Same reason as containers, need full udev/uevent machinery for this
2025-11-21 09:16:57 +01:00
Matteo Croce
38e9d40c80 oomd: check if a cgroup can be killed before attempting to kill it
On OOM event, oomd tries to kill a cgroup until it succeedes.
The kill can fail with EPERM in case a pid is not killed, this leaves
the cgroup with only half of the processed killed.
This is unlikely but theoretically possible in a user namespace,
where systemd run as root inside the container and tries to kill a
cgroup with some PID from the host namespace.

To address this, send the SIG0 signal to all the processes to check
that we have privileges to kill them.
2025-11-21 09:15:37 +01:00
2 changed files with 14 additions and 2 deletions

View File

@ -337,6 +337,12 @@ int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char
if (c->pgscan == 0 && c->current_memory_usage == 0)
continue;
/* First try killing recursively to ensure all child cgroups can be killed. */
r = cg_kill_recursive(c->path, /* sig= */ 0, CGROUP_IGNORE_SELF, /* killed_pids= */ NULL,
/* log_kill= */ NULL, /* userdata= */ NULL);
if (r < 0)
continue;
r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run);
if (r == -ENOMEM)
return r; /* Treat oom as a hard error */
@ -381,6 +387,12 @@ int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run,
if (c->swap_usage <= threshold_usage)
continue;
/* First try killing recursively to ensure all child cgroups can be killed. */
r = cg_kill_recursive(c->path, /* sig= */ 0, CGROUP_IGNORE_SELF, /* killed_pids= */ NULL,
/* log_kill= */ NULL, /* userdata= */ NULL);
if (r < 0)
continue;
r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run);
if (r == -ENOMEM)
return r; /* Treat oom as a hard error */

View File

@ -240,8 +240,8 @@ static int run(int argc, char *argv[]) {
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
return log_tests_skipped("not running privileged");
if (detect_container() > 0)
return log_tests_skipped("Test not supported in a container, requires udev/uevent notifications");
if (detect_container() > 0 || running_in_chroot() > 0)
return log_tests_skipped("Test not supported in a container/chroot, requires udev/uevent notifications");
assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, 0, LO_FLAGS_PARTSCAN, LOCK_EX, &loop) >= 0);