From 1aedc8fe5e8d3683413c805e79b2e7c4f5758fdb Mon Sep 17 00:00:00 2001 From: David 'equinox' Lamparter Date: Mon, 24 Aug 2026 02:04:13 +0200 Subject: [PATCH] core/service: document & improve STOPPING=1 `STOPPING=1` is final, explain in the sd_notify man page that this is the case and log an error if a service attempts to get back out of STOPPING with another notification. Fixes #43465 / 98734ac74d16862302c490e2a5bbc60539b7e6a4 --- man/sd_notify.xml | 5 +++++ src/core/service.c | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 52685c404b..fd229535d9 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -209,6 +209,11 @@ to allow the service manager to track the service's internal state, and present it to the user. + Starting with version 259, transitioning to the STOPPING state is final and cannot be undone + with another notification. If after sending STOPPING=1 the service doesn't + terminate within the stop timeout, all remaining processes in the unit will be killed. + + diff --git a/src/core/service.c b/src/core/service.c index 1918147525..535c833e25 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -5448,11 +5448,12 @@ static void service_notify_message_process_state(Service *s, char * const *tags) return; } - /* Disallow resurrecting a dying service */ - if (s->notify_state == NOTIFY_STOPPING) - return; - if (strv_contains(tags, "READY=1")) { + if (s->notify_state == NOTIFY_STOPPING) { + log_unit_error(UNIT(s), + "Service must stop after STOPPING=1 notification, refusing attempted transition to READY."); + return; + } if (s->type == SERVICE_NOTIFY_RELOAD && s->state == SERVICE_START) { r = service_check_reload_signal_handler(s, ", refusing service startup", ", ignoring"); @@ -5498,6 +5499,11 @@ static void service_notify_message_process_state(Service *s, char * const *tags) service_enter_reload_post(s); } else if (strv_contains(tags, "RELOADING=1")) { + if (s->notify_state == NOTIFY_STOPPING) { + log_unit_error(UNIT(s), + "Service must stop after STOPPING=1 notification, refusing attempted transition to RELOADING."); + return; + } s->notify_state = NOTIFY_RELOADING;