From 3c4eca60b79180f43a2484ce2a4b3d54dd868482 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 9 Apr 2021 19:51:03 +0200 Subject: [PATCH] initctl: fix restart of run/tasks, stuck in DONE state Signed-off-by: Joachim Wiberg --- src/api.c | 30 +++++++++++++++++++++++++++--- src/finit.h | 4 ++-- src/initctl.c | 2 +- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/api.c b/src/api.c index e9d139d9..2f9f4d6e 100644 --- a/src/api.c +++ b/src/api.c @@ -74,6 +74,23 @@ static int start(svc_t *svc) return 0; } +/* + * NOTE: this does not wait for svc to be stopped first, that is the + * responsibility of initctl to do. Otherwise we'd block PID 1, + * or introduce some nasty race conditions. + */ +static int restart(svc_t *svc) +{ + if (!svc) + return 1; + + svc_mark_dirty(svc); + svc_start(svc); + service_step(svc); + + return 0; +} + static int reload(svc_t *svc) { if (!svc) @@ -88,9 +105,10 @@ static int reload(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_reload(char *buf, size_t len) { return call(reload, buf, len); } +static int do_stop (char *buf, size_t len) { return call(stop, buf, len); } +static int do_start (char *buf, size_t len) { return call(start, buf, len); } +static int do_restart(char *buf, size_t len) { return call(restart, 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) @@ -327,6 +345,12 @@ static void api_cb(uev_t *w, void *arg, int events) result = do_start(rq.data, sizeof(rq.data)); break; + case INIT_CMD_RESTART_SVC: + _d("restart %s", rq.data); + strterm(rq.data, sizeof(rq.data)); + result = do_restart(rq.data, sizeof(rq.data)); + break; + case INIT_CMD_STOP_SVC: _d("stop %s", rq.data); strterm(rq.data, sizeof(rq.data)); diff --git a/src/finit.h b/src/finit.h index 0018e3c7..4cfb403b 100644 --- a/src/finit.h +++ b/src/finit.h @@ -71,10 +71,10 @@ /* Finit extensions over std SysV */ #define INIT_CMD_DEBUG 8 /* Toggle Finit debug */ #define INIT_CMD_RELOAD 9 /* Reload *.conf in /etc/finit.d/ */ -#define INIT_CMD_START_SVC 10 +#define INIT_CMD_START_SVC 10 /* START service */ #define INIT_CMD_STOP_SVC 11 #define INIT_CMD_RELOAD_SVC 12 /* SIGHUP service */ -#define INIT_CMD_RESTART_SVC 13 /* STOP + START service */ +#define INIT_CMD_RESTART_SVC 13 /* START service, clearing blocks */ #define INIT_CMD_UNUSED2 14 /* Unused, was INIT_CMD_QUERY_INETD */ #define INIT_CMD_UNUSED1 15 /* Unused, was INIT_CMD_EMIT */ #define INIT_CMD_GET_RUNLEVEL 16 diff --git a/src/initctl.c b/src/initctl.c index 7915e7da..dc3db66e 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -262,7 +262,7 @@ static int do_restart(char *arg) if (retries == 0) errx(1, "Failed stopping %s (restart)", arg); - return do_startstop(INIT_CMD_START_SVC, arg); + return do_startstop(INIT_CMD_RESTART_SVC, arg); } static int dump_one_cond(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf)