From c01faef99b7e4ff9c39f29ad5648db61a4742539 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 19 Mar 2026 06:37:50 +0100 Subject: [PATCH] service: clear condition before stopping rdeps on reload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a service without SIGHUP reload support (noreload) is touched and 'initctl reload' is called, service_update_rdeps() correctly identifies its reverse dependencies but only marks them dirty. It does not clear the service's condition, so when service_step_all() runs: - rdeps supporting SIGHUP hit the sm_in_reload() guard and break early, left running while their dependency is being killed. - rdeps without SIGHUP support may receive SIGTERM too late, after the dependency has already died and broken their connection, causing them to exit from RUNNING state and have their restart counter incremented. Fix by calling cond_clear() on the service's condition immediately in service_update_rdeps(), before service_step_all() runs. cond_clear() calls cond_update() which calls service_step() inline on all affected services, which see COND_OFF and transition to STOPPING_STATE — all before SIGTERM is ever sent to the dependency itself. This mirrors the pattern already used in api.c:do_reload() for direct 'initctl reload ' calls. Fixes: avahi/mdns stop causing mdns-alias restart counter increment Signed-off-by: Joachim Wiberg --- src/service.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index b2c6c15b..016b5d2f 100644 --- a/src/service.c +++ b/src/service.c @@ -2418,7 +2418,21 @@ void service_update_rdeps(void) if (!svc_is_noreload(svc)) continue; /* Yup, no need to stop start rdeps */ - svc_mark_affected(mkcond(svc, cond, sizeof(cond))); + /* + * Clear the condition immediately, before service_step_all() + * runs. cond_clear() calls cond_update() which calls + * service_step() on all affected services right now. Those + * services see COND_OFF and get service_stop() called, + * transitioning to STOPPING_STATE before we ever send SIGTERM + * to this service. Without this, the condition is only cleared + * after the service dies, by which time reverse-dependencies + * may have already crashed due to the lost connection. + * See also: api.c do_reload() which does the same for direct + * 'initctl reload ' calls. + */ + mkcond(svc, cond, sizeof(cond)); + cond_clear(cond); + svc_mark_affected(cond); } }