]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: fix (again) race condition in TEST-80-NOTIFYACCESS
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 18 Dec 2025 17:18:11 +0000 (17:18 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sun, 21 Dec 2025 18:29:55 +0000 (19:29 +0100)
Even with the previous fix, it can still happen that pid1
sends SIGHUP to the script after 'sdnotify --ready' but before
'wait', so the test can still get stuck:

[ 2444.373448] reload-timeout.sh[158]: + set -o pipefail
[ 2444.373502] reload-timeout.sh[158]: + COUNTER=0
[ 2444.373590] reload-timeout.sh[158]: + trap sighup_handler SIGHUP
[ 2444.373639] reload-timeout.sh[158]: + export SYSTEMD_LOG_LEVEL=debug
[ 2444.373670] reload-timeout.sh[158]: + SYSTEMD_LOG_LEVEL=debug
[ 2444.373790] reload-timeout.sh[158]: + wait_for_signal 1
[ 2444.373871] reload-timeout.sh[158]: + local notify=1
[ 2444.373912] reload-timeout.sh[158]: + local p
[ 2444.374079] reload-timeout.sh[158]: + p=159
[ 2444.374123] reload-timeout.sh[159]: + sleep infinity
[ 2444.375358] systemd[1]: reload-timeout.service: Got notification message from PID 158: READY=1
[ 2444.375363] systemd[1]: reload-timeout.service: Changed start -> running
[ 2444.375368] systemd[1]: reload-timeout.service: Job 294 reload-timeout.service/start finished, result=done
[ 2444.375374] systemd[1]: Started reload-timeout.service.
[ 2444.375766] systemd[1]: reload-timeout.service: Failed to send unit change signal for reload-timeout.service: Connection reset by peer
[ 2444.376464] reload-timeout.sh[158]: + '[' 1 -eq 1 ']'
[ 2444.376464] reload-timeout.sh[158]: + systemd-notify --ready
[ 2444.376518] TEST-80-NOTIFYACCESS.sh[157]: Job for reload-timeout.service finished.
[ 2444.376518] TEST-80-NOTIFYACCESS.sh[157]: Got result done/Success for job reload-timeout.service.
[ 2444.376518] TEST-80-NOTIFYACCESS.sh[157]: Bus n/a: changing state RUNNING → CLOSED
[ 2444.376952] TEST-80-NOTIFYACCESS.sh[92]: + systemctl reload --no-block reload-timeout.service
[ 2444.379548] TEST-80-NOTIFYACCESS.sh[161]: Bus n/a: changing state UNSET → OPENING
[ 2444.379548] TEST-80-NOTIFYACCESS.sh[161]: sd-bus: starting bus by connecting to /run/systemd/private...
[ 2444.379548] TEST-80-NOTIFYACCESS.sh[161]: Bus n/a: changing state OPENING → AUTHENTICATING
[ 2444.379548] TEST-80-NOTIFYACCESS.sh[161]: Executing dbus call org.freedesktop.systemd1.Manager ReloadUnit(reload-timeout.service, replace)
[ 2444.379548] TEST-80-NOTIFYACCESS.sh[161]: Bus n/a: changing state AUTHENTICATING → RUNNING
[ 2444.379910] systemd-notify[160]: Notify message sent to '/run/systemd/notify': "READY=1"
[ 2444.379931] systemd-notify[160]: Notify message sent to '/run/systemd/notify': "BARRIER=1"
[ 2444.382218] systemd[1]: reload-timeout.service: Trying to enqueue job reload-timeout.service/reload/replace
[ 2444.382241] systemd[1]: reload-timeout.service: Installed new job reload-timeout.service/reload as 366
[ 2444.382248] systemd[1]: reload-timeout.service: Enqueued job reload-timeout.service/reload as 366
[ 2444.383905] systemd[1]: reload-timeout.service: Service has no extensions to reload.
[ 2444.384925] systemd[1]: reload-timeout.service: Changed running -> reload-signal
[ 2444.384935] systemd[1]: Reloading reload-timeout.service...
[ 2444.386410] reload-timeout.sh[158]: ++ sighup_handler
[ 2444.386410] reload-timeout.sh[158]: ++ echo hup1
[ 2444.386455] TEST-80-NOTIFYACCESS.sh[161]: Bus n/a: changing state RUNNING → CLOSED
[ 2444.386555] TEST-80-NOTIFYACCESS.sh[92]: + timeout 10 bash -c 'until [[ $(systemctl show reload-timeout.service -P SubState) == "reload-signal" ]]; do sleep .5; done'
[ 2444.395566] TEST-80-NOTIFYACCESS.sh[165]: Bus n/a: changing state UNSET → OPENING
[ 2444.395566] TEST-80-NOTIFYACCESS.sh[165]: sd-bus: starting bus by connecting to /run/systemd/private...
[ 2444.396041] TEST-80-NOTIFYACCESS.sh[165]: Bus n/a: changing state OPENING → AUTHENTICATING
[ 2444.396041] TEST-80-NOTIFYACCESS.sh[165]: Showing one /org/freedesktop/systemd1/unit/reload_2dtimeout_2eservice
[ 2444.401911] TEST-80-NOTIFYACCESS.sh[165]: Bus n/a: changing state AUTHENTICATING → RUNNING
[ 2444.401911] TEST-80-NOTIFYACCESS.sh[165]: Bus n/a: changing state RUNNING → CLOSED
[ 2444.403806] TEST-80-NOTIFYACCESS.sh[92]: + sync_in hup1
[ 2444.403806] TEST-80-NOTIFYACCESS.sh[92]: + read -r x
[ 2444.403964] reload-timeout.sh[158]: + wait 159
[ 2444.403988] TEST-80-NOTIFYACCESS.sh[92]: + test hup1 = hup1
[ 2444.403988] TEST-80-NOTIFYACCESS.sh[92]: + timeout 10 bash -c 'until [[ $(systemctl show reload-timeout.service -P SubState) == "reload-notify" ]]; do sleep .5; done'

Try to check if the signal handler has ran by checking the counter,
and avoid waiting and immediately return if it has changed

Fixes https://github.com/systemd/systemd/issues/39581

Follow-up for 8fba2ed2588661c91fb3d0ee6c26b034885ee475

test/integration-tests/TEST-80-NOTIFYACCESS/TEST-80-NOTIFYACCESS.units/reload-timeout.sh

index 6ceecb99d413d83fbaa256e7b9c63683ab1b2b83..1ac449c99a33fb67ba8f08e4df9a91e4173067a6 100755 (executable)
@@ -14,9 +14,11 @@ sync_in() {
 wait_for_signal() {
     local notify="${1:?}"
     local p
+    local c
 
     sleep infinity &
     p=$!
+    c="${COUNTER:-0}"
 
     # Notify readiness after 'sleep' is running to avoid race
     # condition where the SIGHUP is sent before 'sleep' is ready to
@@ -25,7 +27,13 @@ wait_for_signal() {
         systemd-notify --ready
     fi
 
-    wait "$p" || :
+    # ...but even that is not sufficient sometimes, so check if the
+    # callback has already ran by checking the counter
+    if [ "$c" -ne "$COUNTER" ]; then
+        kill -TERM "$p" || :
+    else
+        wait "$p" || :
+    fi
 }
 
 sighup_handler() {