From: Mike Yuan Date: Mon, 6 Oct 2025 00:03:12 +0000 (+0200) Subject: core/service: properly handle freezer action -> watchdog propagation X-Git-Tag: v258.2~82 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5179e7a558de7a7ea4398b606d9cbe38148bde80;p=thirdparty%2Fsystemd.git core/service: properly handle freezer action -> watchdog propagation Follow-up for 25178aadb2bd04ef9e63f48c1ef42fb309f9332e (cherry picked from commit 4f07ec2b651e40fe04455e660606d2a0f9ae375c) --- diff --git a/src/core/service.c b/src/core/service.c index ebffa90fb7e..09276fc4eed 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -5645,16 +5645,31 @@ int service_determine_exec_selinux_label(Service *s, char **ret) { static int service_freezer_action(Unit *u, FreezerAction action) { Service *s = ASSERT_PTR(SERVICE(u)); + FreezerState old_objective, new_objective; int r; + old_objective = freezer_state_objective(u->freezer_state); + r = unit_cgroup_freezer_action(u, action); - if (r <= 0) + if (r < 0) return r; - if (action == FREEZER_FREEZE) - service_stop_watchdog(s); - else if (action == FREEZER_THAW) - service_reset_watchdog(s); + new_objective = freezer_state_objective(u->freezer_state); + + /* Note that we cannot trivially check the retval of unit_cgroup_freezer_action() here, since + * that signals whether the operation is ongoing from *kernel's PoV*. If the freeze operation + * is aborted, the frozen attribute of the cgroup would never have been flipped in kernel, + * and unit_cgroup_freezer_action() will happily return 0, yet the watchdog still needs to be reset; + * vice versa. */ + + if (old_objective != new_objective) { + if (new_objective == FREEZER_FROZEN) + service_stop_watchdog(s); + else if (new_objective == FREEZER_RUNNING) + service_reset_watchdog(s); + else + assert_not_reached(); + } return r; }