pid1: add SurviveFinalKillSignal= to skip units on final sigterm/sigkill spree
Add a new boolean for units, SurviveFinalKillSignal=yes/no. Units that set it will not have their process receive the final sigterm/sigkill in the shutdown phase. This is implemented by checking if a process is part of a cgroup marked with a user.survive_final_kill_signal xattr (or a trusted xattr if we can't set a user one, which were added only in kernel v5.7 and are not supported in CentOS 8).
This commit is contained in:
+23
-23
@@ -20,8 +20,8 @@ if [ -f /run/testsuite82.touch3 ]; then
|
||||
read -r x <&5
|
||||
test "$x" = "oinkoink"
|
||||
|
||||
# Check that no service is still around
|
||||
test "$(systemctl show -P ActiveState testsuite-82-survive.service)" != "active"
|
||||
# Check that the surviving service is still around
|
||||
test "$(systemctl show -P ActiveState testsuite-82-survive.service)" = "active"
|
||||
test "$(systemctl show -P ActiveState testsuite-82-nosurvive.service)" != "active"
|
||||
|
||||
# All succeeded, exit cleanly now
|
||||
@@ -43,8 +43,8 @@ elif [ -f /run/testsuite82.touch2 ]; then
|
||||
systemd-notify --fd=3 --pid=parent 3<"$T"
|
||||
rm "$T"
|
||||
|
||||
# Check that no service is still around
|
||||
test "$(systemctl show -P ActiveState testsuite-82-survive.service)" != "active"
|
||||
# Check that the surviving service is still around
|
||||
test "$(systemctl show -P ActiveState testsuite-82-survive.service)" = "active"
|
||||
test "$(systemctl show -P ActiveState testsuite-82-nosurvive.service)" != "active"
|
||||
|
||||
# Test that we really are in the new overlayfs root fs
|
||||
@@ -57,6 +57,9 @@ elif [ -f /run/testsuite82.touch2 ]; then
|
||||
mount --bind /original-root /run/nextroot
|
||||
mount
|
||||
|
||||
# Restart the unit that is not supposed to survive
|
||||
systemd-run -p Type=exec --unit=testsuite-82-nosurvive.service sleep infinity
|
||||
|
||||
# Now issue the soft reboot. We should be right back soon.
|
||||
touch /run/testsuite82.touch3
|
||||
systemctl --no-block soft-reboot
|
||||
@@ -85,8 +88,8 @@ elif [ -f /run/testsuite82.touch ]; then
|
||||
systemd-notify --fd=3 --pid=parent 3<"$T"
|
||||
rm "$T"
|
||||
|
||||
# Check that no service survived, regardless of the configuration
|
||||
test "$(systemctl show -P ActiveState testsuite-82-survive.service)" != "active"
|
||||
# Check that the surviving service is still around
|
||||
test "$(systemctl show -P ActiveState testsuite-82-survive.service)" = "active"
|
||||
test "$(systemctl show -P ActiveState testsuite-82-nosurvive.service)" != "active"
|
||||
|
||||
# This time we test the /run/nextroot/ root switching logic. (We synthesize a new rootfs from the old via overlayfs)
|
||||
@@ -107,6 +110,9 @@ elif [ -f /run/testsuite82.touch ]; then
|
||||
# Bind our current root into the target so that we later can return to it
|
||||
mount --bind / /run/nextroot/original-root
|
||||
|
||||
# Restart the unit that is not supposed to survive
|
||||
systemd-run -p Type=exec --unit=testsuite-82-nosurvive.service sleep infinity
|
||||
|
||||
# Now issue the soft reboot. We should be right back soon.
|
||||
touch /run/testsuite82.touch2
|
||||
systemctl --no-block soft-reboot
|
||||
@@ -123,23 +129,17 @@ else
|
||||
systemd-notify --fd=3 --pid=parent 3<"$T"
|
||||
rm "$T"
|
||||
|
||||
# Create a script that can survive the soft reboot by ignoring SIGTERM (we
|
||||
# do this instead of the argv[0][0] = '@' thing because that's so hard to
|
||||
# do from a shell
|
||||
T="/dev/shm/survive-$RANDOM.sh"
|
||||
cat >$T <<EOF
|
||||
#!/bin/bash
|
||||
trap "" TERM
|
||||
systemd-notify --ready
|
||||
rm "$T"
|
||||
exec sleep infinity
|
||||
EOF
|
||||
chmod +x "$T"
|
||||
# This sets DefaultDependencies=no so that it remains running until the
|
||||
# very end, and IgnoreOnIsolate=yes so that it isn't stopped via the
|
||||
# "testsuite.target" isolation we do on next boot
|
||||
systemd-run -p Type=notify -p DefaultDependencies=no -p IgnoreOnIsolate=yes --unit=testsuite-82-survive.service "$T"
|
||||
systemd-run -p Type=exec -p DefaultDependencies=no -p IgnoreOnIsolate=yes --unit=testsuite-82-nosurvive.service sleep infinity
|
||||
# Configure this transient unit to survive the soft reboot - it will not conflict with shutdown.target
|
||||
# and it will be ignored on the isolate that happens in the next boot.
|
||||
systemd-run -p Type=exec --unit=testsuite-82-survive.service \
|
||||
--property SurviveFinalKillSignal=yes \
|
||||
--property IgnoreOnIsolate=yes \
|
||||
--property DefaultDependencies=no \
|
||||
--property After=basic.target \
|
||||
--property "Conflicts=reboot.target kexec.target poweroff.target halt.target emergency.target rescue.target" \
|
||||
--property "Before=reboot.target kexec.target poweroff.target halt.target emergency.target rescue.target" \
|
||||
sleep infinity
|
||||
systemd-run -p Type=exec --unit=testsuite-82-nosurvive.service sleep infinity
|
||||
|
||||
# Check that we can set up an inhibitor, and that busctl monitor sees the
|
||||
# PrepareForShutdownWithMetadata signal and that it says 'soft-reboot'.
|
||||
|
||||
Reference in New Issue
Block a user