From 56cb6f861387fe6a183dec7283105ca9d8dc36f6 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 15 Jan 2023 06:02:18 +0100 Subject: [PATCH] Fix #343: handle 'initctl reload' of unmodified non-native services When 'initctl reload' is called new "configuration generation" is started by Finit. This mechanism ensures services reaffirm their readiness and helps distinguish between their ready before reload and after. For native services the pidfile plugin handles this. The s6 style services are one-shot only, and thus use a static ready condition. This patch adds support for stepping the configuration generation of unmodified systemd style services. Signed-off-by: Joachim Wiberg --- src/service.c | 35 +++++++++++++++++++++++++++++++++++ src/service.h | 1 + src/sm.c | 3 +++ 3 files changed, 39 insertions(+) diff --git a/src/service.c b/src/service.c index 45ddb8b1..bcc412a2 100644 --- a/src/service.c +++ b/src/service.c @@ -2437,6 +2437,29 @@ int service_completed(void) return 1; } +/* + * Called in SM_RELOAD_WAIT_STATE to update unmodified non-native + * services' READY condition to the current generation. Similar + * to the pidfile_reconf() function for native services. + */ +void service_notify_reconf(void) +{ + svc_t *svc, *iter = NULL; + + for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) { + if (!svc->notify) + continue; /* managed by pidfile plugin */ + + if (svc->state != SVC_RUNNING_STATE) + continue; + + if (svc_is_changed(svc) || svc_is_starting(svc)) + continue; + + service_ready(svc); + } +} + /* * Called when a service sends readiness notification, or when * the service closes its end of the IPC connection. @@ -2463,7 +2486,19 @@ void service_notify_cb(uev_t *w, void *arg, int events) /* systemd and s6, respectively. The latter then closes the socket */ if (!strcmp(buf, "READY=1\n") || !strcmp(buf, "\n")) { + /* + * native (pidfile) services are marked as started by + * the pidfile plugin. + */ + svc_started(svc); + + /* + * On reload, and this svc is unmodified, it is up to + * the service_notify_reconf() function to step the + * generation of the READY condition. + */ service_ready(svc); + /* s6 applications close their socket after notification */ if (svc->notify == 2) { uev_io_stop(w); diff --git a/src/service.h b/src/service.h index 23d409b5..a423d090 100644 --- a/src/service.h +++ b/src/service.h @@ -49,6 +49,7 @@ void service_step_all (int types); void service_worker (void *unused); int service_completed (void); +void service_notify_reconf (void); void service_init (void); diff --git a/src/sm.c b/src/sm.c index 1effeb38..ec0f444e 100644 --- a/src/sm.c +++ b/src/sm.c @@ -256,6 +256,9 @@ restart: dbg("Calling reconf hooks ..."); plugin_run_hooks(HOOK_SVC_RECONF); + dbg("Update configuration generation of unmodified non-native services ..."); + service_notify_reconf(); + service_step_all(SVC_TYPE_ANY); dbg("Reconfiguration done");