From c70816fd09a0e37732f48f204be282fda09918cf Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 12 Aug 2025 15:35:21 +0900 Subject: [PATCH 1/4] core/service: do not start watchdog on frozen unit when service manager is reloaded or reexecuted Otherwise, when service manager is reloaded or reexecuted, watchdong will be started for frozen services, and they may be killed after timeout. Fixes #38551. --- src/core/service.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/service.c b/src/core/service.c index aa8acdef78..4f8eaf4051 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1418,7 +1418,8 @@ static int service_coldplug(Unit *u) { SERVICE_DEAD_RESOURCES_PINNED)) (void) unit_setup_exec_runtime(u); - if (IN_SET(s->deserialized_state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY, SERVICE_REFRESH_EXTENSIONS, SERVICE_MOUNTING)) + if (IN_SET(s->deserialized_state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY, SERVICE_REFRESH_EXTENSIONS, SERVICE_MOUNTING) && + freezer_state_finish(u->freezer_state) == FREEZER_RUNNING) service_start_watchdog(s); if (UNIT_ISSET(s->accept_socket)) { From b39815ebf7d415cd99049c72c7164d599f967aee Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 13 Aug 2025 10:38:53 +0900 Subject: [PATCH 2/4] core/cgroup: allow to set cgroup path for frozen unit Otherwise, after 'systemctl daemon-reload' or 'daemon-reexec', frozen units cannot gain cgroup paths and we cannot operate anything on them, especially, we cannot thaw or stop them. ``` Aug 12 16:26:09 systemd[1]: wd.service: Job 1278 wd.service/stop finished, result=frozen Aug 12 16:26:09 systemd[1]: Cannot stop frozen unit wd.service. Aug 12 16:26:09 systemd[1]: wd.service: Cannot realize cgroup for frozen unit. Aug 12 16:26:09 systemd[1]: Failed to realize cgroups for queued unit wd.service, ignoring: Device or resource busy ``` Follow-up for 23ac08115af83e3a0a937fa207fc52511aba2ffa. --- src/core/cgroup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index ce9c30fc6e..48149e15bd 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -2088,9 +2088,6 @@ static int unit_update_cgroup( if (!UNIT_HAS_CGROUP_CONTEXT(u)) return 0; - if (u->freezer_state != FREEZER_RUNNING) - return log_unit_error_errno(u, SYNTHETIC_ERRNO(EBUSY), "Cannot realize cgroup for frozen unit."); - r = unit_get_cgroup_path_with_fallback(u, &cgroup); if (r < 0) return log_unit_error_errno(u, r, "Failed to get cgroup path: %m"); From 0e25939a9de04ec3b826757a939294013afd2fa0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 12 Aug 2025 15:44:02 +0900 Subject: [PATCH 3/4] TEST-38-FREEZER: check if watchdog is not restarted by systemctl daemon-reload or daemon-reexec --- test/units/TEST-38-FREEZER.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/units/TEST-38-FREEZER.sh b/test/units/TEST-38-FREEZER.sh index 81682cfc01..6c21a2d3e3 100755 --- a/test/units/TEST-38-FREEZER.sh +++ b/test/units/TEST-38-FREEZER.sh @@ -367,12 +367,36 @@ testcase_watchdog() { /bin/bash -c 'systemd-notify --ready; while true; do systemd-notify WATCHDOG=1; sleep 1; done' systemctl freeze "$unit" - check_freezer_state "$unit" "frozen" sleep 6 check_freezer_state "$unit" "frozen" systemctl thaw "$unit" + check_freezer_state "$unit" "running" + sleep 6 + check_freezer_state "$unit" "running" + systemctl is-active "$unit" + + systemctl freeze "$unit" + check_freezer_state "$unit" "frozen" + systemctl daemon-reload + sleep 6 + check_freezer_state "$unit" "frozen" + + systemctl thaw "$unit" + check_freezer_state "$unit" "running" + sleep 6 + check_freezer_state "$unit" "running" + systemctl is-active "$unit" + + systemctl freeze "$unit" + check_freezer_state "$unit" "frozen" + systemctl daemon-reexec + sleep 6 + check_freezer_state "$unit" "frozen" + + systemctl thaw "$unit" + check_freezer_state "$unit" "running" sleep 6 check_freezer_state "$unit" "running" systemctl is-active "$unit" From ee76ac1411549dc5517b2c58ff1dc84f01c24183 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 13 Aug 2025 12:30:25 +0900 Subject: [PATCH 4/4] TEST-38-FREEZER: use 'systemctl show' to get freezer state Also, use timeout command for waiting freezer state applied. --- test/units/TEST-38-FREEZER.sh | 45 ++++++++--------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/test/units/TEST-38-FREEZER.sh b/test/units/TEST-38-FREEZER.sh index 6c21a2d3e3..5ce073d045 100755 --- a/test/units/TEST-38-FREEZER.sh +++ b/test/units/TEST-38-FREEZER.sh @@ -69,42 +69,18 @@ dbus_thaw_unit() { "$1" } -dbus_can_freeze() { - local name object_path suffix - - suffix="${1##*.}" - name="${1%".$suffix"}" - object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}" - - busctl get-property \ - org.freedesktop.systemd1 \ - "${object_path}" \ - org.freedesktop.systemd1.Unit \ - CanFreeze -} - check_freezer_state() { - local name object_path suffix + local name state expected - suffix="${1##*.}" - name="${1%".$suffix"}" - object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}" + name="${1:?}" + expected="${2:?}" - for _ in {0..10}; do - state=$(busctl get-property \ - org.freedesktop.systemd1 \ - "${object_path}" \ - org.freedesktop.systemd1.Unit \ - FreezerState | cut -d " " -f2 | tr -d '"') + # Ignore the intermediate freezing & thawing states in case we check the unit state too quickly. + timeout 10 bash -c "while [[ \"\$(systemctl show \"$name\" --property FreezerState --value)\" =~ (freezing|thawing) ]]; do sleep .5; done" - # Ignore the intermediate freezing & thawing states in case we check - # the unit state too quickly - [[ "$state" =~ ^(freezing|thawing) ]] || break - sleep .5 - done - - [ "$state" = "$2" ] || { - echo "error: unexpected freezer state, expected: $2, actual: $state" >&2 + state="$(systemctl show "$name" --property FreezerState --value)" + [[ "$state" = "$expected" ]] || { + echo "error: unexpected freezer state, expected: $expected, actual: $state" >&2 exit 1 } } @@ -146,9 +122,8 @@ testcase_dbus_api() { check_cgroup_state "$unit" 0 echo "[ OK ]" - echo -n " - CanFreeze(): " - output=$(dbus_can_freeze "${unit}") - [ "$output" = "b true" ] + echo -n " - CanFreeze: " + [[ "$(systemctl show "${unit}" --property=CanFreeze --value)" == 'yes' ]] echo "[ OK ]" echo