systemd/1106-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch

90 lines
2.9 KiB
Diff
Raw Permalink Normal View History

From 14a2f6dd75ef4eefd0a7791a7c086e72a141bc69 Mon Sep 17 00:00:00 2001
From: Richard Phibel <rphibel@googlemail.com>
Date: Tue, 23 May 2023 16:09:40 +0200
Subject: [PATCH] core: Don't GC unit if it is in cgroup_empty_queue
The gc_unit_queue is dispatched before the cgroup_empty_queue. Because
of this, when we enter in on_cgroup_empty_event, the unit in
cgroup_empty_queue may already have been freed and we don't clean up the
corresponding cgroup. With this change, we prevent the unit from being
garbage collected if it is in the cgroup_empty_queue.
(cherry picked from commit 8db998981a4fefd0122bcf5f965726b63c9045c2)
Resolves: RHEL-55301
---
src/core/unit.c | 3 ++
test/units/testsuite-19.cleanup-slice.sh | 49 ++++++++++++++++++++++++
2 files changed, 52 insertions(+)
create mode 100755 test/units/testsuite-19.cleanup-slice.sh
diff --git a/src/core/unit.c b/src/core/unit.c
index f109d16eb3..08f87851d9 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -417,6 +417,9 @@ bool unit_may_gc(Unit *u) {
if (u->perpetual)
return false;
+ if (u->in_cgroup_empty_queue)
+ return false;
+
if (sd_bus_track_count(u->bus_track) > 0)
return false;
diff --git a/test/units/testsuite-19.cleanup-slice.sh b/test/units/testsuite-19.cleanup-slice.sh
new file mode 100755
index 0000000000..5d63160334
--- /dev/null
+++ b/test/units/testsuite-19.cleanup-slice.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+# shellcheck source=test/units/util.sh
+. "$(dirname "$0")"/util.sh
+
+export SYSTEMD_LOG_LEVEL=debug
+
+# Create service with KillMode=none inside a slice
+cat <<EOF >/run/systemd/system/test19cleanup.service
+[Unit]
+Description=Test 19 cleanup Service
+[Service]
+Slice=test19cleanup.slice
+Type=exec
+ExecStart=sleep infinity
+KillMode=none
+EOF
+cat <<EOF >/run/systemd/system/test19cleanup.slice
+[Unit]
+Description=Test 19 cleanup Slice
+EOF
+
+# Start service
+systemctl start test19cleanup.service
+assert_rc 0 systemd-cgls /test19cleanup.slice
+
+pid=$(systemctl show --property MainPID --value test19cleanup)
+ps "$pid"
+
+# Stop slice
+# The sleep process will not be killed because of KillMode=none
+# Since there is still a process running under it, the /test19cleanup.slice cgroup won't be removed
+systemctl stop test19cleanup.slice
+
+ps "$pid"
+
+# Kill sleep process manually
+kill -s TERM "$pid"
+while kill -0 "$pid" 2>/dev/null; do sleep 0.1; done
+
+timeout 30 bash -c 'while systemd-cgls /test19cleanup.slice/test19cleanup.service >& /dev/null; do sleep .5; done'
+assert_rc 1 systemd-cgls /test19cleanup.slice/test19cleanup.service
+
+# Check that empty cgroup /test19cleanup.slice has been removed
+timeout 30 bash -c 'while systemd-cgls /test19cleanup.slice >& /dev/null; do sleep .5; done'
+assert_rc 1 systemd-cgls /test19cleanup.slice