mirror of
https://github.com/troglobit/finit.git
synced 2026-09-30 13:02:37 +07:00
Add reload:'script [args]' support for service/sysv stanzas
Fixes #446 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
+44
-26
@@ -1120,34 +1120,27 @@ int service_stop(svc_t *svc)
|
||||
}
|
||||
|
||||
/**
|
||||
* service_restart - Restart a service by sending %SIGHUP
|
||||
* service_reload - Reload a service
|
||||
* @svc: Service to reload
|
||||
*
|
||||
* This function does some basic checks of the runtime state of Finit
|
||||
* and a sanity check of the @svc before sending %SIGHUP.
|
||||
* and a sanity check of the @svc before sending %SIGHUP or calling
|
||||
* the reload:script command.
|
||||
*
|
||||
* Returns:
|
||||
* POSIX OK(0) or non-zero on error.
|
||||
*/
|
||||
static int service_restart(svc_t *svc)
|
||||
static int service_reload(svc_t *svc)
|
||||
{
|
||||
const char *id = svc_ident(svc, NULL, 0);
|
||||
int do_progress = 1;
|
||||
pid_t lost = 0;
|
||||
int rc;
|
||||
|
||||
/* Ignore if finit is SIGSTOP'ed */
|
||||
if (is_norespawn())
|
||||
/* Ignore if service is invalid or finit is SIGSTOP'ed */
|
||||
if (!svc || is_norespawn())
|
||||
return 1;
|
||||
|
||||
if (!svc || !svc->sighup)
|
||||
return 1;
|
||||
|
||||
if (svc->pid <= 1) {
|
||||
dbg("%s: bad PID %d for %s, SIGHUP", svc_ident(svc, NULL, 0), svc->pid, svc->cmd);
|
||||
svc->start_time = svc->pid = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Skip progress if desc disabled or bootstrap task */
|
||||
if (!svc->desc[0] || svc_in_runlevel(svc, INIT_LEVEL))
|
||||
do_progress = 0;
|
||||
@@ -1155,14 +1148,28 @@ static int service_restart(svc_t *svc)
|
||||
if (do_progress)
|
||||
print_desc("Restarting ", svc->desc);
|
||||
|
||||
dbg("Sending SIGHUP to PID %d", svc->pid);
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "Restarting %s[%d], sending SIGHUP ...",
|
||||
svc_ident(svc, NULL, 0), svc->pid);
|
||||
rc = kill(svc->pid, SIGHUP);
|
||||
if (rc == -1 && (errno == ESRCH || errno == ENOENT)) {
|
||||
/* nobody home, reset internal state machine */
|
||||
lost = svc->pid;
|
||||
if (svc->reload_script[0]) {
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], calling %s ...", id, svc->pid, svc->reload_script);
|
||||
rc = run(svc->reload_script, NULL);
|
||||
} else if (svc->sighup) {
|
||||
if (svc->pid <= 1) {
|
||||
dbg("%s[%d]: bad PID, cannot reload service", id, svc->pid);
|
||||
svc->start_time = svc->pid = 0;
|
||||
goto done;
|
||||
}
|
||||
dbg("%s[%d], sending SIGHUP", id, svc->pid);
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], sending SIGHUP ...", id, svc->pid);
|
||||
rc = kill(svc->pid, SIGHUP);
|
||||
if (rc == -1 && (errno == ESRCH || errno == ENOENT)) {
|
||||
/* nobody home, reset internal state machine */
|
||||
lost = svc->pid;
|
||||
}
|
||||
} else {
|
||||
warnx("%s: neither HUP nor reload:script defined, no action.", id);
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
/* Declare we're waiting for svc to re-assert/touch its pidfile */
|
||||
svc_starting(svc);
|
||||
|
||||
@@ -1172,7 +1179,7 @@ static int service_restart(svc_t *svc)
|
||||
touch(pid_file(svc));
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (do_progress)
|
||||
print_result(rc);
|
||||
|
||||
@@ -1601,7 +1608,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
char *id = NULL, *env = NULL, *cgroup = NULL;
|
||||
char *pre_script = NULL, *post_script = NULL;
|
||||
char *ready_script = NULL, *conflict = NULL;
|
||||
char *cleanup_script = NULL;
|
||||
char *reload_script = NULL, *cleanup_script = NULL;
|
||||
char ident[MAX_IDENT_LEN];
|
||||
char *ifstmt = NULL;
|
||||
char *notify = NULL;
|
||||
@@ -1711,6 +1718,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
ready_script = arg;
|
||||
else if (MATCH_CMD(cmd, "cleanup:", arg))
|
||||
cleanup_script = arg;
|
||||
else if (MATCH_CMD(cmd, "reload:", arg))
|
||||
reload_script = arg;
|
||||
else if (MATCH_CMD(cmd, "env:", arg))
|
||||
env = arg;
|
||||
/* catch both cgroup: and cgroup. handled in parse_cgroup() */
|
||||
@@ -1906,6 +1915,11 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
else
|
||||
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));
|
||||
else
|
||||
memset(svc->reload_script, 0, sizeof(svc->reload_script));
|
||||
|
||||
if (!svc_is_tty(svc)) {
|
||||
if (log)
|
||||
parse_log(svc, log);
|
||||
@@ -2151,7 +2165,7 @@ void service_update_rdeps(void)
|
||||
continue;
|
||||
|
||||
/* Service supports reloading conf without stop/start */
|
||||
if (!svc_is_nohup(svc))
|
||||
if (!svc_is_noreload(svc))
|
||||
continue; /* Yup, no need to stop start rdeps */
|
||||
|
||||
svc_mark_affected(mkcond(svc, cond, sizeof(cond)));
|
||||
@@ -2786,7 +2800,11 @@ restart:
|
||||
|
||||
case COND_ON:
|
||||
if (svc_is_changed(svc)) {
|
||||
if (svc_nohup(svc) || !svc_is_daemon(svc)) {
|
||||
/*
|
||||
* If service does not suport reload, or its command line
|
||||
* arguments have been modified, we need to stop-start it.
|
||||
*/
|
||||
if (svc_is_noreload(svc) || svc->args_dirty) {
|
||||
service_stop(svc);
|
||||
} else {
|
||||
/*
|
||||
@@ -2796,7 +2814,7 @@ restart:
|
||||
if (sm_in_reload())
|
||||
break;
|
||||
|
||||
service_restart(svc);
|
||||
service_reload(svc);
|
||||
}
|
||||
|
||||
svc_mark_clean(svc);
|
||||
|
||||
@@ -212,6 +212,9 @@ typedef struct svc {
|
||||
char cleanup_script[MAX_CMD_LEN];
|
||||
int cleanup_tmo;
|
||||
|
||||
/* When set, used instead of SIGHUP or stop-start */
|
||||
char reload_script[MAX_CMD_LEN];
|
||||
|
||||
/*
|
||||
* Used to forcefully kill services that won't shutdown on
|
||||
* termination and to delay restarts of crashing services.
|
||||
@@ -272,10 +275,9 @@ static inline int svc_is_tty (svc_t *svc) { return svc && SVC_TYPE_TTY
|
||||
static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTASK & svc->type);}
|
||||
static inline int svc_is_forking (svc_t *svc) { return svc && svc->forking; }
|
||||
static inline int svc_is_manual (svc_t *svc) { return svc && svc->manual; }
|
||||
static inline int svc_is_nohup (svc_t *svc) { return svc && (0 == svc->sighup); }
|
||||
static inline int svc_is_noreload (svc_t *svc) { return svc && (0 == svc->sighup && 0 == svc->reload_script[0]); }
|
||||
|
||||
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
|
||||
static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); }
|
||||
static inline int svc_has_pidfile (svc_t *svc) { return svc_is_daemon(svc) && svc->pidfile[0] != 0 && svc->pidfile[0] != '!'; }
|
||||
static inline int svc_has_pre (svc_t *svc) { return svc->pre_script[0]; }
|
||||
static inline int svc_has_post (svc_t *svc) { return svc->post_script[0]; }
|
||||
|
||||
Reference in New Issue
Block a user