diff --git a/src/api.c b/src/api.c index 264276b4..a9e4e568 100644 --- a/src/api.c +++ b/src/api.c @@ -74,7 +74,7 @@ static int start(svc_t *svc) return 0; } -static int restart(svc_t *svc) +static int reload(svc_t *svc) { if (!svc) return 1; @@ -88,9 +88,9 @@ static int restart(svc_t *svc) return 0; } -static int do_start (char *buf, size_t len) { return call(start, buf, len); } -static int do_stop (char *buf, size_t len) { return call(stop, buf, len); } -static int do_restart(char *buf, size_t len) { return call(restart, buf, len); } +static int do_start (char *buf, size_t len) { return call(start, buf, len); } +static int do_stop (char *buf, size_t len) { return call(stop, buf, len); } +static int do_reload(char *buf, size_t len) { return call(reload, buf, len); } static char query_buf[368]; static int missing(char *job, char *id) @@ -333,10 +333,10 @@ static void api_cb(uev_t *w, void *arg, int events) result = do_stop(rq.data, sizeof(rq.data)); break; - case INIT_CMD_RESTART_SVC: - _d("restart %s", rq.data); + case INIT_CMD_RELOAD_SVC: + _d("reload %s", rq.data); strterm(rq.data, sizeof(rq.data)); - result = do_restart(rq.data, sizeof(rq.data)); + result = do_reload(rq.data, sizeof(rq.data)); break; case INIT_CMD_GET_RUNLEVEL: diff --git a/src/initctl.c b/src/initctl.c index 6e92a105..f6d200bd 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -193,7 +193,8 @@ static int do_svc(int cmd, char *arg) { struct init_request rq = { .magic = INIT_MAGIC, - .cmd = cmd, + .cmd = cmd, + .data = "", }; if (arg) @@ -202,8 +203,6 @@ static int do_svc(int cmd, char *arg) return client_send(&rq, sizeof(rq)); } -static int do_reload (char *arg) { return do_svc(INIT_CMD_RELOAD, arg); } - /* * This is a wrapper for do_svc() that adds a simple sanity check of * the service(s) provided as argument. If a service does not exist @@ -237,7 +236,35 @@ static int do_startstop(int cmd, char *arg) static int do_start (char *arg) { return do_startstop(INIT_CMD_START_SVC, arg); } static int do_stop (char *arg) { return do_startstop(INIT_CMD_STOP_SVC, arg); } -static int do_restart(char *arg) { return do_startstop(INIT_CMD_RESTART_SVC, arg); } + +static int do_reload (char *arg) +{ + if (!arg || !arg[0]) + return do_svc(INIT_CMD_RELOAD, NULL); + + return do_startstop(INIT_CMD_RELOAD_SVC, arg); +} + +static int do_restart(char *arg) +{ + size_t retries = 3; + svc_t *svc; + + if (do_startstop(INIT_CMD_STOP_SVC, arg)) + return 1; + + while (retries-- > 0 && (svc = client_svc_find(arg))) { + if (!svc_is_running(svc)) + break; + + sleep(1); + } + + if (retries == 0) + errx(1, "Failed stopping %s (restart)", arg); + + return do_startstop(INIT_CMD_START_SVC, arg); +} static int dump_one_cond(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) { @@ -789,6 +816,7 @@ static int usage(int rc) " log [NAME] Show ten last Finit, or NAME, messages from syslog\n" " start [:ID] Start service by name, with optional ID\n" " stop [:ID] Stop/Pause a running service by name\n" + " reload [:ID] Reload service by name (SIGHUP or restart)\n" " restart [:ID] Restart (stop/start) service by name\n" " status [:ID] Show service status, by name\n" " status Show status of services, default command\n" diff --git a/src/svc.h b/src/svc.h index f20d5bec..de16bb49 100644 --- a/src/svc.h +++ b/src/svc.h @@ -201,6 +201,7 @@ static inline int svc_has_pidfile (svc_t *svc) { return svc_is_daemon(svc) && s static inline void svc_starting (svc_t *svc) { if (svc) svc->starting = 1; } static inline void svc_started (svc_t *svc) { if (svc) svc->starting = 0; } static inline int svc_is_starting (svc_t *svc) { return svc && 0 != svc->starting; } +static inline int svc_is_running (svc_t *svc) { return svc && svc->state == SVC_RUNNING_STATE; } static inline int svc_is_removed (svc_t *svc) { return svc && svc->removed; } static inline int svc_is_changed (svc_t *svc) { return svc && 0 != svc->dirty; }