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;