Add stop:'script [args]' support for service/sysv stanzas

Fixes #412

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2025-07-06 13:20:46 +02:00
1 parent bb841383b8
commit 14336bd407
2 files changed
+32 -17

No files matched your search

+29 -17
View File
@@ -1002,6 +1002,7 @@ static void service_cleanup(svc_t *svc)
*/ */
int service_stop(svc_t *svc) int service_stop(svc_t *svc)
{ {
const char *id = svc_ident(svc, NULL, 0);
char cmdline[CMD_SIZE] = ""; char cmdline[CMD_SIZE] = "";
int do_progress = 1; int do_progress = 1;
int rc = 0; int rc = 0;
@@ -1014,11 +1015,11 @@ int service_stop(svc_t *svc)
service_timeout_cancel(svc); service_timeout_cancel(svc);
compose_cmdline(svc, cmdline, sizeof(cmdline)); if (svc->stop_script[0]) {
if (!svc_is_sysv(svc)) { logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], calling stop:%s ...", id, svc->pid, svc->stop_script);
} else if (!svc_is_sysv(svc)) {
char *nm = pid_get_name(svc->pid, NULL, 0); char *nm = pid_get_name(svc->pid, NULL, 0);
const char *sig = sig_name(svc->sighalt); const char *sig = sig_name(svc->sighalt);
char *id = svc_ident(svc, NULL, 0);
if (svc->pid <= 1) if (svc->pid <= 1)
return 1; return 1;
@@ -1030,9 +1031,10 @@ int service_stop(svc_t *svc)
} }
dbg("Sending %s to pid:%d name:%s(%s)", sig, svc->pid, id, nm); dbg("Sending %s to pid:%d name:%s(%s)", sig, svc->pid, id, nm);
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s[%d], sending %s ...", id, svc->pid, sig); logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], stopping, sending %s ...", id, svc->pid, sig);
} else { } else {
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s stop' ...", cmdline); compose_cmdline(svc, cmdline, sizeof(cmdline));
logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], calling '%s stop' ...", id, svc->pid, cmdline);
} }
/* /*
@@ -1060,7 +1062,9 @@ int service_stop(svc_t *svc)
if (runlevel != 1 && do_progress && svc_is_daemon(svc)) if (runlevel != 1 && do_progress && svc_is_daemon(svc))
print_desc("Stopping ", svc->desc); print_desc("Stopping ", svc->desc);
if (!svc_is_sysv(svc)) { if (svc->stop_script[0]) {
rc = run(svc->stop_script, NULL);
} else if (!svc_is_sysv(svc)) {
if (svc->pid > 1) { if (svc->pid > 1) {
/* /*
* Send SIGTERM to parent process of process group, not to the * Send SIGTERM to parent process of process group, not to the
@@ -1071,11 +1075,8 @@ int service_stop(svc_t *svc)
rc = kill(svc->pid, svc->sighalt); rc = kill(svc->pid, svc->sighalt);
dbg("kill(%d, %d) => rc %d, errno %d", svc->pid, svc->sighalt, rc, errno); dbg("kill(%d, %d) => rc %d, errno %d", svc->pid, svc->sighalt, rc, errno);
/* PID lost or forking process never really started */ /* PID lost or forking process never really started */
if (rc == -1 && (errno == ESRCH || errno == ENOENT)) { if (rc == -1 && (errno == ESRCH || errno == ENOENT))
service_cleanup(svc); rc = 1;
svc_set_state(svc, SVC_HALTED_STATE);
} else
svc_set_state(svc, SVC_STOPPING_STATE);
} else { } else {
service_cleanup(svc); service_cleanup(svc);
svc_set_state(svc, SVC_HALTED_STATE); svc_set_state(svc, SVC_HALTED_STATE);
@@ -1083,7 +1084,6 @@ int service_stop(svc_t *svc)
} else { } else {
char *args[MAX_NUM_SVC_ARGS + 1]; char *args[MAX_NUM_SVC_ARGS + 1];
size_t i = 0, j; size_t i = 0, j;
pid_t pid;
args[i++] = svc->cmd; args[i++] = svc->cmd;
/* this handles, e.g., bridge-stop br0 stop */ /* this handles, e.g., bridge-stop br0 stop */
@@ -1095,8 +1095,7 @@ int service_stop(svc_t *svc)
args[i++] = "stop"; args[i++] = "stop";
args[i] = NULL; args[i] = NULL;
pid = fork(); switch (fork()) {
switch (pid) {
case 0: case 0:
setsid(); setsid();
redirect(svc); redirect(svc);
@@ -1108,11 +1107,16 @@ int service_stop(svc_t *svc)
rc = 1; rc = 1;
break; break;
default: default:
svc_set_state(svc, SVC_STOPPING_STATE);
break; break;
} }
} }
if (rc == 1) {
service_cleanup(svc);
svc_set_state(svc, SVC_HALTED_STATE);
} else
svc_set_state(svc, SVC_STOPPING_STATE);
if (runlevel != 1 && do_progress && svc_is_daemon(svc)) if (runlevel != 1 && do_progress && svc_is_daemon(svc))
print_result(rc); print_result(rc);
@@ -1149,7 +1153,7 @@ static int service_reload(svc_t *svc)
print_desc("Restarting ", svc->desc); print_desc("Restarting ", svc->desc);
if (svc->reload_script[0]) { if (svc->reload_script[0]) {
logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], calling %s ...", id, svc->pid, svc->reload_script); logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], calling reload:%s ...", id, svc->pid, svc->reload_script);
rc = run(svc->reload_script, NULL); rc = run(svc->reload_script, NULL);
} else if (svc->sighup) { } else if (svc->sighup) {
if (svc->pid <= 1) { if (svc->pid <= 1) {
@@ -1608,7 +1612,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
char *id = NULL, *env = NULL, *cgroup = NULL; char *id = NULL, *env = NULL, *cgroup = NULL;
char *pre_script = NULL, *post_script = NULL; char *pre_script = NULL, *post_script = NULL;
char *ready_script = NULL, *conflict = NULL; char *ready_script = NULL, *conflict = NULL;
char *reload_script = NULL, *cleanup_script = NULL; char *reload_script = NULL, *stop_script = NULL;
char *cleanup_script = NULL;
char ident[MAX_IDENT_LEN]; char ident[MAX_IDENT_LEN];
char *ifstmt = NULL; char *ifstmt = NULL;
char *notify = NULL; char *notify = NULL;
@@ -1720,6 +1725,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
cleanup_script = arg; cleanup_script = arg;
else if (MATCH_CMD(cmd, "reload:", arg)) else if (MATCH_CMD(cmd, "reload:", arg))
reload_script = arg; reload_script = arg;
else if (MATCH_CMD(cmd, "stop:", arg))
stop_script = arg;
else if (MATCH_CMD(cmd, "env:", arg)) else if (MATCH_CMD(cmd, "env:", arg))
env = arg; env = arg;
/* catch both cgroup: and cgroup. handled in parse_cgroup() */ /* catch both cgroup: and cgroup. handled in parse_cgroup() */
@@ -1920,6 +1927,11 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
else else
memset(svc->reload_script, 0, sizeof(svc->reload_script)); 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));
else
memset(svc->stop_script, 0, sizeof(svc->stop_script));
if (!svc_is_tty(svc)) { if (!svc_is_tty(svc)) {
if (log) if (log)
parse_log(svc, log); parse_log(svc, log);
+3
View File
@@ -215,6 +215,9 @@ typedef struct svc {
/* When set, used instead of SIGHUP or stop-start */ /* When set, used instead of SIGHUP or stop-start */
char reload_script[MAX_CMD_LEN]; char reload_script[MAX_CMD_LEN];
/* When set, used instead of SIGTERM or sysv 'stop' */
char stop_script[MAX_CMD_LEN];
/* /*
* Used to forcefully kill services that won't shutdown on * Used to forcefully kill services that won't shutdown on
* termination and to delay restarts of crashing services. * termination and to delay restarts of crashing services.