From: Luca Boccassi Date: Fri, 8 Aug 2025 19:08:20 +0000 (+0100) Subject: service: stop/reset watchdog on freeze/thaw X-Git-Tag: v257.9~53 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2b85de380b68ffcef8661cec642689ce45fbaabf;p=thirdparty%2Fsystemd.git service: stop/reset watchdog on freeze/thaw Otherwise the unit will be killed by the watchdog given it's frozen but the clock keeps ticking Fixes https://github.com/systemd/systemd/issues/38517 (cherry picked from commit 25178aadb2bd04ef9e63f48c1ef42fb309f9332e) --- diff --git a/src/core/service.c b/src/core/service.c index 92d2f3d77cb..c83540c1209 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -5518,6 +5518,22 @@ int service_determine_exec_selinux_label(Service *s, char **ret) { return 0; } +static int service_cgroup_freezer_action(Unit *u, FreezerAction action) { + Service *s = ASSERT_PTR(SERVICE(u)); + int r; + + r = unit_cgroup_freezer_action(u, action); + if (r <= 0) + return r; + + if (action == FREEZER_FREEZE) + service_stop_watchdog(s); + else if (action == FREEZER_THAW) + service_reset_watchdog(s); + + return r; +} + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { [SERVICE_RESTART_NO] = "no", [SERVICE_RESTART_ON_SUCCESS] = "on-success", @@ -5655,7 +5671,7 @@ const UnitVTable service_vtable = { .live_mount = service_live_mount, .can_live_mount = service_can_live_mount, - .freezer_action = unit_cgroup_freezer_action, + .freezer_action = service_cgroup_freezer_action, .serialize = service_serialize, .deserialize_item = service_deserialize_item, diff --git a/test/units/TEST-38-FREEZER.sh b/test/units/TEST-38-FREEZER.sh index 4c483df46a8..81682cfc017 100755 --- a/test/units/TEST-38-FREEZER.sh +++ b/test/units/TEST-38-FREEZER.sh @@ -360,6 +360,26 @@ testcase_preserve_state() { echo } +testcase_watchdog() { + local unit="wd.service" + + systemd-run --collect --unit "$unit" --property WatchdogSec=4s --property Type=notify \ + /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" + sleep 6 + check_freezer_state "$unit" "running" + systemctl is-active "$unit" + + systemctl stop "$unit" +} + if [[ -e /sys/fs/cgroup/system.slice/cgroup.freeze ]]; then start_test_service run_testcases