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 / 98734ac74d
This commit is contained in:
David 'equinox' Lamparter
2026-08-24 22:46:01 +09:00
committed by Yu Watanabe
parent 98b867040e
commit 1aedc8fe5e
2 changed files with 15 additions and 4 deletions
+5
View File
@@ -209,6 +209,11 @@
to allow the service manager to track the service's internal state, and present it to the user.
</para>
<para>Starting with version 259, transitioning to the STOPPING state is final and cannot be undone
with another notification. If after sending <literal>STOPPING=1</literal> the service doesn't
terminate within the stop timeout, all remaining processes in the unit will be killed.
</para>
<xi:include href="version-info.xml" xpointer="v217"/></listitem>
</varlistentry>
+10 -4
View File
@@ -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;