]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
service: stop/reset watchdog on freeze/thaw
authorLuca Boccassi <luca.boccassi@gmail.com>
Fri, 8 Aug 2025 19:08:20 +0000 (20:08 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 3 Sep 2025 10:10:48 +0000 (12:10 +0200)
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)

src/core/service.c
test/units/TEST-38-FREEZER.sh

index 92d2f3d77cb9bd7ae6e1abf7fa1756bfe5a85fb1..c83540c12095b673fbc53035d6b25e4082603894 100644 (file)
@@ -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,
index 4c483df46a8ce002f6da98800be8d3830e28dceb..81682cfc017d50736caf2853afca2e08e7931782 100755 (executable)
@@ -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