diff --git a/src/core/unit.c b/src/core/unit.c index e99f8f2b3e..147bc8f5f2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -5559,11 +5559,11 @@ int unit_fork_helper_process(Unit *u, const char *name, bool into_cgroup, PidRef * with the child's PID. */ if (into_cgroup) { - (void) unit_realize_cgroup(u); + r = unit_realize_cgroup(u); + if (r < 0) + return r; - crt = unit_setup_cgroup_runtime(u); - if (!crt) - return -ENOMEM; + crt = unit_get_cgroup_runtime(u); } r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM, &pid); @@ -6013,7 +6013,9 @@ int unit_prepare_exec(Unit *u) { /* Prepares everything so that we can fork of a process for this unit */ - (void) unit_realize_cgroup(u); + r = unit_realize_cgroup(u); + if (r < 0) + return r; CGroupRuntime *crt = unit_get_cgroup_runtime(u); if (crt && crt->reset_accounting) { diff --git a/test/units/TEST-19-CGROUP.abort-on-cgroup-creation-failure.sh b/test/units/TEST-19-CGROUP.abort-on-cgroup-creation-failure.sh new file mode 100755 index 0000000000..41f8b96e25 --- /dev/null +++ b/test/units/TEST-19-CGROUP.abort-on-cgroup-creation-failure.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -ex +set -o pipefail + +# Test that the service is not invoked if the cgroup cannot be created. + +# It seems openSUSE kernel (at least kernel-default-6.16.8-1.1.x86_64.rpm) has a +# bag in kernel oom killer or clone3 syscall, and spawning executor on a cgroup +# with too small MemoryMax= triggers infinite loop of OOM kill, and posix_spawn() +# will never return, and the service manager will stuck. +#### +# [ 119.776797] systemd invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=0 +# [ 119.776859] CPU: 1 UID: 0 PID: 1472 Comm: systemd Not tainted 6.16.8-1-default #1 PREEMPT(voluntary) openSUSE Tumbleweed 6c85865973e4ae641870ed68afe8933a6986c974 +# [ 119.776865] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014 +# [ 119.776867] Call Trace: +# (snip) +# [ 119.778126] Out of memory and no killable processes... +#### +# On other distributions, the oom killer is triggered, but clone3 immediately +# fails with ENOMEM, and such problematic loop does not happen. +. /etc/os-release +if [[ "$ID" =~ opensuse ]]; then + echo "Skipping cgroup test with too small MemoryMax= setting on openSUSE." + exit 0 +fi + +cat >/run/systemd/system/testslice.slice </run/systemd/system/testservice.service <