From e1f85b49b09ed3e3717cf7776c9da7acc4e906c6 Mon Sep 17 00:00:00 2001 From: Nick Rosbrook Date: Tue, 4 Apr 2023 18:39:26 -0400 Subject: [PATCH 1/2] scope: do not disable timer event source when state is SCOPE_RUNNING In scope_set_state(), the timer event source may be disabled depending on the state. Currently, it will be disabled when the state is SCOPE_RUNNING. This has the effect of new RuntimeMaxSec values being ignored on coldplug. Note that this issue is not currently present when scopes are started because when scope_start() is called, scope_arm_timer() is called after scope_set_state(). --- src/core/scope.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/scope.c b/src/core/scope.c index 510bb28c93..5f3b62e021 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -116,7 +116,7 @@ static void scope_set_state(Scope *s, ScopeState state) { old_state = s->state; s->state = state; - if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL, SCOPE_START_CHOWN)) + if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL, SCOPE_START_CHOWN, SCOPE_RUNNING)) s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source); if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED)) { From af4688398f55b110c9d7d57be5cd0199b06e18c8 Mon Sep 17 00:00:00 2001 From: Nick Rosbrook Date: Thu, 13 Apr 2023 11:29:32 -0400 Subject: [PATCH 2/2] test: add some tests for RuntimeMaxSec Make sure the RuntimeMaxSec is applied correctly to service and scope units when they are started, and also on coldplug. --- test/units/testsuite-16.sh | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/test/units/testsuite-16.sh b/test/units/testsuite-16.sh index 1b8cd018bb..9b8a7bd6fa 100755 --- a/test/units/testsuite-16.sh +++ b/test/units/testsuite-16.sh @@ -23,6 +23,25 @@ function wait_for() fi } +function wait_for_timeout() +{ + local unit="$1" + local time="$2" + + while [[ $time -gt 0 ]]; do + if [[ "$(systemctl show --property=Result "$unit")" == "Result=timeout" ]]; then + return 0 + fi + + sleep 1 + time=$((time - 1)) + done + + journalctl -u "$unit" >>"$TESTLOG" + + return 1 +} + # This checks all stages, start, runtime and stop, can be extended by # EXTEND_TIMEOUT_USEC @@ -44,6 +63,53 @@ wait_for fail_start startfail wait_for fail_stop stopfail wait_for fail_runtime runtimefail +# These ensure that RuntimeMaxSec is honored for scope and service units +# when they are created. +runtime_max_sec=5 + +systemd-run \ + --property=RuntimeMaxSec=${runtime_max_sec}s \ + -u runtime-max-sec-test-1.service \ + /usr/bin/sh -c "while true; do sleep 1; done" +wait_for_timeout runtime-max-sec-test-1.service $((runtime_max_sec + 2)) + +systemd-run \ + --property=RuntimeMaxSec=${runtime_max_sec}s \ + --scope \ + -u runtime-max-sec-test-2.scope \ + /usr/bin/sh -c "while true; do sleep 1; done" & +wait_for_timeout runtime-max-sec-test-2.scope $((runtime_max_sec + 2)) + +# These ensure that RuntimeMaxSec is honored for scope and service +# units if the value is changed and then the manager is reloaded. +systemd-run \ + -u runtime-max-sec-test-3.service \ + /usr/bin/sh -c "while true; do sleep 1; done" +mkdir -p /etc/systemd/system/runtime-max-sec-test-3.service.d/ +cat > /etc/systemd/system/runtime-max-sec-test-3.service.d/override.conf << EOF +[Service] +RuntimeMaxSec=${runtime_max_sec}s +EOF +systemctl daemon-reload +wait_for_timeout runtime-max-sec-test-3.service $((runtime_max_sec + 2)) + +systemd-run \ + --scope \ + -u runtime-max-sec-test-4.scope \ + /usr/bin/sh -c "while true; do sleep 1; done" & + +# Wait until the unit is running to avoid race with creating the override. +until systemctl is-active runtime-max-sec-test-4.scope; do + sleep 1 +done +mkdir -p /etc/systemd/system/runtime-max-sec-test-4.scope.d/ +cat > /etc/systemd/system/runtime-max-sec-test-4.scope.d/override.conf << EOF +[Scope] +RuntimeMaxSec=${runtime_max_sec}s +EOF +systemctl daemon-reload +wait_for_timeout runtime-max-sec-test-4.scope $((runtime_max_sec + 2)) + if [[ -f "$TESTLOG" ]]; then # no mv cp "$TESTLOG" /test.log