mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 17:12:32 +07:00
service: keep a pending reload across a second conf reload
A service whose condition goes into flux during a reload is paused with its reload still pending. If another reload was requested in the meantime, re-parsing its unchanged .conf file cleared the pending mark, so the service was resumed without ever being reloaded. Seen with sshd <pid/syslogd> on Infix, where a configuration change that touched both landed as two reloads in a row and sshd kept its old listen addresses. The mark is only ever cleared once the change has been applied, so a mark that is still set when the file is parsed again means exactly that: not applied yet. Leave it alone. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -43,6 +43,7 @@ EXTRA_DIST += conf-template.sh
|
||||
EXTRA_DIST += script-timeout.sh
|
||||
EXTRA_DIST += crashing.sh
|
||||
EXTRA_DIST += dep-chain-reload.sh
|
||||
EXTRA_DIST += reload-while-paused.sh
|
||||
EXTRA_DIST += depserv.sh
|
||||
EXTRA_DIST += devmon.sh
|
||||
EXTRA_DIST += failing-sysv.sh
|
||||
@@ -109,6 +110,7 @@ TESTS += conf-template.sh
|
||||
TESTS += script-timeout.sh
|
||||
TESTS += crashing.sh
|
||||
TESTS += dep-chain-reload.sh
|
||||
TESTS += reload-while-paused.sh
|
||||
TESTS += depserv.sh
|
||||
TESTS += devmon.sh
|
||||
TESTS += failing-sysv.sh
|
||||
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
# A reload must not be lost on a service paused by a condition
|
||||
#
|
||||
# svc_s writes its PID file one second after a SIGHUP, so a service
|
||||
# with <pid/svc_s> is paused for that second whenever svc_s reloads.
|
||||
# svc_x counts the SIGHUPs it gets. Both .conf files are touched and
|
||||
# two reloads are requested back to back, so the second one arrives
|
||||
# while svc_x is paused with its own reload still pending. svc_x must
|
||||
# get exactly one SIGHUP and keep its PID.
|
||||
|
||||
set -eu
|
||||
|
||||
TEST_DIR=$(dirname "$0")
|
||||
|
||||
test_teardown()
|
||||
{
|
||||
say "Running test teardown."
|
||||
run "rm -f $FINIT_RCSD/svc_s.conf $FINIT_RCSD/svc_x.conf /tmp/hup.sh /tmp/hup.log"
|
||||
}
|
||||
|
||||
pidof()
|
||||
{
|
||||
texec initctl -j status "$1" | jq .pid
|
||||
}
|
||||
|
||||
test_setup()
|
||||
{
|
||||
run "cat > /tmp/hup.sh" <<EOF
|
||||
#!/bin/sh
|
||||
trap 'echo HUP >> /tmp/hup.log' HUP
|
||||
trap 'exit 0' TERM
|
||||
while true; do
|
||||
sleep 1
|
||||
done
|
||||
EOF
|
||||
run "cat > $FINIT_RCSD/svc_s.conf" <<EOF
|
||||
service log:stdout notify:pid pid:!/run/service.pid name:svc_s service.sh -- Slow to reassert
|
||||
EOF
|
||||
run "cat > $FINIT_RCSD/svc_x.conf" <<EOF
|
||||
service log:stdout <pid/svc_s> name:svc_x /bin/sh /tmp/hup.sh -- Paused while svc_s reloads
|
||||
EOF
|
||||
}
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. "$TEST_DIR/lib/setup.sh"
|
||||
|
||||
sep "Configuration"
|
||||
run "cat $FINIT_RCSD/svc_s.conf"
|
||||
run "cat $FINIT_RCSD/svc_x.conf"
|
||||
|
||||
say "Reload Finit to start both services"
|
||||
run "initctl reload"
|
||||
retry 'assert_status "svc_x" "running"' 10 1
|
||||
|
||||
pid_x=$(pidof svc_x)
|
||||
say "svc_x PID before: $pid_x"
|
||||
|
||||
sep "Touch both, reload twice"
|
||||
run "rm -f /tmp/hup.log"
|
||||
run "initctl touch svc_s.conf"
|
||||
run "initctl touch svc_x.conf"
|
||||
run "initctl reload"
|
||||
run "initctl reload"
|
||||
|
||||
say "Wait for services to settle"
|
||||
retry 'assert_status "svc_x" "running"' 15 1
|
||||
run "initctl status"
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
retry 'assert "svc_x got its SIGHUP" "$(texec sh -c "cat /tmp/hup.log 2>/dev/null | wc -l")" -eq 1' 10 1
|
||||
|
||||
new_pid_x=$(pidof svc_x)
|
||||
# shellcheck disable=SC2086
|
||||
assert "svc_x was not restarted" $new_pid_x -eq $pid_x
|
||||
|
||||
return 0
|
||||
Reference in New Issue
Block a user