From ccb84ced2e132bb476deea9c1cf0219ae9208d8e Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 30 May 2022 06:54:27 +0200 Subject: [PATCH] Fix #280: allow calling `initctl restart foo` from within foo Move the stop+start from initctl to the state machine by allowing stopped tasks to restart once it has been collected. This should prevent finit from blocking, allowing it to handle other requests while waiting for the service's PID to be collected. Effectively, this will allow a service to call initctl to restart itself, as reported in issue #280. Signed-off-by: Joachim Wiberg --- src/api.c | 7 +++++-- src/initctl.c | 19 +++---------------- src/service.c | 6 +++++- src/service.h | 1 + 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/api.c b/src/api.c index a4a3e09c..1e07d804 100644 --- a/src/api.c +++ b/src/api.c @@ -89,8 +89,7 @@ static int restart(svc_t *svc, void *user_data) if (!svc) return 1; - svc_mark_dirty(svc); - svc_start(svc); + service_stop(svc); service_step(svc); return 0; @@ -319,6 +318,10 @@ static void api_cb(uev_t *w, void *arg, int events) if (EAGAIN == errno) break; + /* we get here when client restarts itself */ + if (ECONNRESET == errno) + break; + _e("Failed reading initctl request, error %d: %s", errno, strerror(errno)); } diff --git a/src/initctl.c b/src/initctl.c index 3993e40b..7fb8411a 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -271,23 +271,10 @@ static int do_reload (char *arg) static int do_restart(char *arg) { - size_t retries = 3; - svc_t *svc; + if (do_startstop(INIT_CMD_RESTART_SVC, arg)) + ERRX(7, "failed restarting %s", arg); - 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(7, "failed stopping %s (restart)", arg); - - return do_startstop(INIT_CMD_RESTART_SVC, arg); + return 0; } /** diff --git a/src/service.c b/src/service.c index f0b00a63..6567793b 100644 --- a/src/service.c +++ b/src/service.c @@ -731,10 +731,14 @@ static void service_cleanup(svc_t *svc) * service_stop - Stop service * @svc: Service to stop * + * Called externally by initctl to perform stop/start (restart) of + * services. Internally it is used to bring a run/task/service to + * HALTED state. + * * Returns: * 0 if the service was successfully stopped. Non-zero otherwise. */ -static int service_stop(svc_t *svc) +int service_stop(svc_t *svc) { char cmdline[CMD_SIZE] = ""; int do_progress = 1; diff --git a/src/service.h b/src/service.h index 9cc421e0..9831ea05 100644 --- a/src/service.h +++ b/src/service.h @@ -40,6 +40,7 @@ int service_timeout_cancel (svc_t *svc); void service_forked (svc_t *svc); +int service_stop (svc_t *svc); int service_step (svc_t *svc); void service_step_all (int types); void service_worker (void *unused);