mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +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
|
* @svc: Service to reload
|
||||||
*
|
*
|
||||||
* This function does some basic checks of the runtime state of Finit
|
* 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:
|
* Returns:
|
||||||
* POSIX OK(0) or non-zero on error.
|
* 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;
|
int do_progress = 1;
|
||||||
pid_t lost = 0;
|
pid_t lost = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Ignore if finit is SIGSTOP'ed */
|
/* Ignore if service is invalid or finit is SIGSTOP'ed */
|
||||||
if (is_norespawn())
|
if (!svc || is_norespawn())
|
||||||
return 1;
|
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 */
|
/* Skip progress if desc disabled or bootstrap task */
|
||||||
if (!svc->desc[0] || svc_in_runlevel(svc, INIT_LEVEL))
|
if (!svc->desc[0] || svc_in_runlevel(svc, INIT_LEVEL))
|
||||||
do_progress = 0;
|
do_progress = 0;
|
||||||
@@ -1155,14 +1148,28 @@ static int service_restart(svc_t *svc)
|
|||||||
if (do_progress)
|
if (do_progress)
|
||||||
print_desc("Restarting ", svc->desc);
|
print_desc("Restarting ", svc->desc);
|
||||||
|
|
||||||
dbg("Sending SIGHUP to PID %d", svc->pid);
|
if (svc->reload_script[0]) {
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Restarting %s[%d], sending SIGHUP ...",
|
logit(LOG_CONSOLE | LOG_NOTICE, "%s[%d], calling %s ...", id, svc->pid, svc->reload_script);
|
||||||
svc_ident(svc, NULL, 0), svc->pid);
|
rc = run(svc->reload_script, NULL);
|
||||||
rc = kill(svc->pid, SIGHUP);
|
} else if (svc->sighup) {
|
||||||
if (rc == -1 && (errno == ESRCH || errno == ENOENT)) {
|
if (svc->pid <= 1) {
|
||||||
/* nobody home, reset internal state machine */
|
dbg("%s[%d]: bad PID, cannot reload service", id, svc->pid);
|
||||||
lost = 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 {
|
} 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 */
|
/* Declare we're waiting for svc to re-assert/touch its pidfile */
|
||||||
svc_starting(svc);
|
svc_starting(svc);
|
||||||
|
|
||||||
@@ -1172,7 +1179,7 @@ static int service_restart(svc_t *svc)
|
|||||||
touch(pid_file(svc));
|
touch(pid_file(svc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
if (do_progress)
|
if (do_progress)
|
||||||
print_result(rc);
|
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 *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 *cleanup_script = NULL;
|
char *reload_script = NULL, *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;
|
||||||
@@ -1711,6 +1718,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
ready_script = arg;
|
ready_script = arg;
|
||||||
else if (MATCH_CMD(cmd, "cleanup:", arg))
|
else if (MATCH_CMD(cmd, "cleanup:", arg))
|
||||||
cleanup_script = arg;
|
cleanup_script = arg;
|
||||||
|
else if (MATCH_CMD(cmd, "reload:", arg))
|
||||||
|
reload_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() */
|
||||||
@@ -1906,6 +1915,11 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
else
|
else
|
||||||
memset(svc->cleanup_script, 0, sizeof(svc->cleanup_script));
|
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 (!svc_is_tty(svc)) {
|
||||||
if (log)
|
if (log)
|
||||||
parse_log(svc, log);
|
parse_log(svc, log);
|
||||||
@@ -2151,7 +2165,7 @@ void service_update_rdeps(void)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Service supports reloading conf without stop/start */
|
/* 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 */
|
continue; /* Yup, no need to stop start rdeps */
|
||||||
|
|
||||||
svc_mark_affected(mkcond(svc, cond, sizeof(cond)));
|
svc_mark_affected(mkcond(svc, cond, sizeof(cond)));
|
||||||
@@ -2786,7 +2800,11 @@ restart:
|
|||||||
|
|
||||||
case COND_ON:
|
case COND_ON:
|
||||||
if (svc_is_changed(svc)) {
|
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);
|
service_stop(svc);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -2796,7 +2814,7 @@ restart:
|
|||||||
if (sm_in_reload())
|
if (sm_in_reload())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
service_restart(svc);
|
service_reload(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
svc_mark_clean(svc);
|
svc_mark_clean(svc);
|
||||||
|
|||||||
@@ -212,6 +212,9 @@ typedef struct svc {
|
|||||||
char cleanup_script[MAX_CMD_LEN];
|
char cleanup_script[MAX_CMD_LEN];
|
||||||
int cleanup_tmo;
|
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
|
* 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.
|
||||||
@@ -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_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_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_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_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_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_pre (svc_t *svc) { return svc->pre_script[0]; }
|
||||||
static inline int svc_has_post (svc_t *svc) { return svc->post_script[0]; }
|
static inline int svc_has_post (svc_t *svc) { return svc->post_script[0]; }
|
||||||
|
|||||||
Reference in New Issue
Block a user