From 53cb2b7bdb46fe899d4f6b84ef9812c6326b61f4 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 26 Jul 2026 22:14:32 +0200 Subject: [PATCH] service: give stop and reload scripts their own timeout Both were bounded by killdelay, the delay between the stop signal and SIGKILL, because service_run_script() had nothing else to reach for. That conflates two things: how long the daemon may take to die, and how long its stop script may run. Give each hook a timeout of its own, defaulting to killdelay when unset, so the existing behaviour is what you get until you ask for something else. parse_script() already falls back that way for the hooks that had one. Signed-off-by: Joachim Wiberg --- src/service.c | 12 ++++++------ src/svc.h | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/service.c b/src/service.c index 055985cd..34647923 100644 --- a/src/service.c +++ b/src/service.c @@ -1076,7 +1076,7 @@ static void service_kill(svc_t *svc) * Called by service_stop() and service_reload() when alternate mechanisms * for stopping and reloading have been specified by the user. */ -static int service_run_script(svc_t *svc, char *script) +static int service_run_script(svc_t *svc, char *script, int tmo) { const char *id = svc_ident(svc, NULL, 0); pid_t pid = service_fork(svc); @@ -1106,7 +1106,7 @@ static int service_run_script(svc_t *svc, char *script) } dbg("%s: script '%s' started as PID %d", id, script, pid); - return service_script_add(svc, pid, svc->killdelay); + return service_script_add(svc, pid, tmo ? tmo : svc->killdelay); } /* Ensure we don't have any notify socket lingering */ @@ -1268,7 +1268,7 @@ int service_stop(svc_t *svc) print_desc("Stopping ", svc->desc); if (svc->stop_script[0]) { - rc = service_run_script(svc, svc->stop_script); + rc = service_run_script(svc, svc->stop_script, svc->stop_tmo); } else if (!svc_is_sysv(svc)) { if (svc->pid > 1) { /* @@ -1360,7 +1360,7 @@ static int service_reload(svc_t *svc) if (svc->reload_script[0]) { logit(LOG_CONSOLE | LOG_NOTICE, "Reloading %s[%d], calling reload:%s ...", id, svc->pid, svc->reload_script); - rc = service_run_script(svc, svc->reload_script); + rc = service_run_script(svc, svc->reload_script, svc->reload_tmo); } else if (svc->sighup) { if (svc->pid <= 1) { dbg("%s[%d]: bad PID, cannot reload service", id, svc->pid); @@ -2211,12 +2211,12 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file) memset(svc->cleanup_script, 0, sizeof(svc->cleanup_script)); if (reload_script) - parse_script(svc, "reload", reload_script, NULL, svc->reload_script, sizeof(svc->reload_script)); + parse_script(svc, "reload", reload_script, &svc->reload_tmo, svc->reload_script, sizeof(svc->reload_script)); else memset(svc->reload_script, 0, sizeof(svc->reload_script)); if (stop_script) - parse_script(svc, "stop", stop_script, NULL, svc->stop_script, sizeof(svc->stop_script)); + parse_script(svc, "stop", stop_script, &svc->stop_tmo, svc->stop_script, sizeof(svc->stop_script)); else memset(svc->stop_script, 0, sizeof(svc->stop_script)); diff --git a/src/svc.h b/src/svc.h index 1d4b46e3..59f4ed43 100644 --- a/src/svc.h +++ b/src/svc.h @@ -221,9 +221,11 @@ typedef struct svc { /* When set, used instead of SIGHUP or stop-start */ char reload_script[MAX_CMD_LEN]; + int reload_tmo; /* When set, used instead of SIGTERM or sysv 'stop' */ char stop_script[MAX_CMD_LEN]; + int stop_tmo; /* * Used to forcefully kill services that won't shutdown on