52b84b
From 6e732b6e44ad8eb3e94c47459c64f0bc6ef2fcb0 Mon Sep 17 00:00:00 2001
52b84b
From: Anita Zhang <the.anitazha@gmail.com>
52b84b
Date: Sat, 25 Jan 2020 16:46:16 +0100
52b84b
Subject: [PATCH] core: transition to FINAL_SIGTERM state after ExecStopPost=
52b84b
52b84b
Fixes #14566
52b84b
52b84b
(cherry picked from commit c1566ef0d22ed786b9ecf4c476e53b8a91e67578)
52b84b
52b84b
Resolves: #1766479
52b84b
---
52b84b
 src/core/service.c                    | 10 +++++
52b84b
 test/TEST-47-ISSUE-14566/Makefile     |  1 +
52b84b
 test/TEST-47-ISSUE-14566/repro.sh     |  5 +++
52b84b
 test/TEST-47-ISSUE-14566/test.sh      | 55 +++++++++++++++++++++++++++
52b84b
 test/TEST-47-ISSUE-14566/testsuite.sh | 23 +++++++++++
52b84b
 5 files changed, 94 insertions(+)
52b84b
 create mode 120000 test/TEST-47-ISSUE-14566/Makefile
52b84b
 create mode 100755 test/TEST-47-ISSUE-14566/repro.sh
52b84b
 create mode 100755 test/TEST-47-ISSUE-14566/test.sh
52b84b
 create mode 100755 test/TEST-47-ISSUE-14566/testsuite.sh
52b84b
52b84b
diff --git a/src/core/service.c b/src/core/service.c
52b84b
index b1ec52d220..5035dcacac 100644
52b84b
--- a/src/core/service.c
52b84b
+++ b/src/core/service.c
52b84b
@@ -3280,6 +3280,12 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
52b84b
                                 break;
52b84b
 
52b84b
                         case SERVICE_STOP_POST:
52b84b
+
52b84b
+                                if (control_pid_good(s) <= 0)
52b84b
+                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
52b84b
+
52b84b
+                                break;
52b84b
+
52b84b
                         case SERVICE_FINAL_SIGTERM:
52b84b
                         case SERVICE_FINAL_SIGKILL:
52b84b
 
52b84b
@@ -3415,6 +3421,10 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
52b84b
                                 break;
52b84b
 
52b84b
                         case SERVICE_STOP_POST:
52b84b
+                                if (main_pid_good(s) <= 0)
52b84b
+                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
52b84b
+                                break;
52b84b
+
52b84b
                         case SERVICE_FINAL_SIGTERM:
52b84b
                         case SERVICE_FINAL_SIGKILL:
52b84b
                                 if (main_pid_good(s) <= 0)
52b84b
diff --git a/test/TEST-47-ISSUE-14566/Makefile b/test/TEST-47-ISSUE-14566/Makefile
52b84b
new file mode 120000
52b84b
index 0000000000..e9f93b1104
52b84b
--- /dev/null
52b84b
+++ b/test/TEST-47-ISSUE-14566/Makefile
52b84b
@@ -0,0 +1 @@
52b84b
+../TEST-01-BASIC/Makefile
52b84b
\ No newline at end of file
52b84b
diff --git a/test/TEST-47-ISSUE-14566/repro.sh b/test/TEST-47-ISSUE-14566/repro.sh
52b84b
new file mode 100755
52b84b
index 0000000000..5217602257
52b84b
--- /dev/null
52b84b
+++ b/test/TEST-47-ISSUE-14566/repro.sh
52b84b
@@ -0,0 +1,5 @@
52b84b
+#!/bin/bash
52b84b
+
52b84b
+sleep infinity &
52b84b
+echo $! > /leakedtestpid
52b84b
+wait $!
52b84b
diff --git a/test/TEST-47-ISSUE-14566/test.sh b/test/TEST-47-ISSUE-14566/test.sh
52b84b
new file mode 100755
52b84b
index 0000000000..0ce772164a
52b84b
--- /dev/null
52b84b
+++ b/test/TEST-47-ISSUE-14566/test.sh
52b84b
@@ -0,0 +1,55 @@
52b84b
+#!/bin/bash
52b84b
+set -e
52b84b
+TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over proccesses with ExecStopPost="
52b84b
+. $TEST_BASE_DIR/test-functions
52b84b
+
52b84b
+test_setup() {
52b84b
+    create_empty_image
52b84b
+    mkdir -p $TESTDIR/root
52b84b
+    mount ${LOOPDEV}p1 $TESTDIR/root
52b84b
+
52b84b
+    (
52b84b
+        LOG_LEVEL=5
52b84b
+        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
52b84b
+
52b84b
+        setup_basic_environment
52b84b
+
52b84b
+        # mask some services that we do not want to run in these tests
52b84b
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
52b84b
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
52b84b
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
52b84b
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
52b84b
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
52b84b
+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
52b84b
+
52b84b
+        # setup the testsuite service
52b84b
+        cat >$initdir/etc/systemd/system/testsuite.service <
52b84b
+[Unit]
52b84b
+Description=Testsuite service
52b84b
+
52b84b
+[Service]
52b84b
+ExecStart=/testsuite.sh
52b84b
+Type=oneshot
52b84b
+EOF
52b84b
+        cat > $initdir/etc/systemd/system/issue_14566_test.service << EOF
52b84b
+[Unit]
52b84b
+Description=Issue 14566 Repro
52b84b
+
52b84b
+[Service]
52b84b
+ExecStart=/repro.sh
52b84b
+ExecStopPost=/bin/true
52b84b
+KillMode=mixed
52b84b
+EOF
52b84b
+
52b84b
+        cp testsuite.sh $initdir/
52b84b
+        cp repro.sh $initdir/
52b84b
+
52b84b
+        setup_testsuite
52b84b
+    )
52b84b
+    setup_nspawn_root
52b84b
+
52b84b
+    ddebug "umount $TESTDIR/root"
52b84b
+    umount $TESTDIR/root
52b84b
+}
52b84b
+
52b84b
+do_test "$@"
52b84b
diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/TEST-47-ISSUE-14566/testsuite.sh
52b84b
new file mode 100755
52b84b
index 0000000000..d917cf52ff
52b84b
--- /dev/null
52b84b
+++ b/test/TEST-47-ISSUE-14566/testsuite.sh
52b84b
@@ -0,0 +1,23 @@
52b84b
+#!/bin/bash
52b84b
+set -ex
52b84b
+set -o pipefail
52b84b
+
52b84b
+systemd-analyze log-level debug
52b84b
+systemd-analyze log-target console
52b84b
+
52b84b
+systemctl start issue_14566_test
52b84b
+systemctl status issue_14566_test
52b84b
+
52b84b
+leaked_pid=$(cat /leakedtestpid)
52b84b
+
52b84b
+systemctl stop issue_14566_test
52b84b
+
52b84b
+# Leaked PID will still be around if we're buggy.
52b84b
+# I personally prefer to see 42.
52b84b
+ps -p "$leaked_pid" && exit 42
52b84b
+
52b84b
+systemd-analyze log-level info
52b84b
+
52b84b
+echo OK > /testok
52b84b
+
52b84b
+exit 0