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 <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2022-05-30 06:54:27 +02:00
1 parent 5ef669fb6c
commit ccb84ced2e
4 files changed
+14 -19

No files matched your search

+5 -2
View File
@@ -89,8 +89,7 @@ static int restart(svc_t *svc, void *user_data)
if (!svc) if (!svc)
return 1; return 1;
svc_mark_dirty(svc); service_stop(svc);
svc_start(svc);
service_step(svc); service_step(svc);
return 0; return 0;
@@ -319,6 +318,10 @@ static void api_cb(uev_t *w, void *arg, int events)
if (EAGAIN == errno) if (EAGAIN == errno)
break; break;
/* we get here when client restarts itself */
if (ECONNRESET == errno)
break;
_e("Failed reading initctl request, error %d: %s", errno, strerror(errno)); _e("Failed reading initctl request, error %d: %s", errno, strerror(errno));
} }
+3 -16
View File
@@ -271,23 +271,10 @@ static int do_reload (char *arg)
static int do_restart(char *arg) static int do_restart(char *arg)
{ {
size_t retries = 3; if (do_startstop(INIT_CMD_RESTART_SVC, arg))
svc_t *svc; ERRX(7, "failed restarting %s", arg);
if (do_startstop(INIT_CMD_STOP_SVC, arg)) return 0;
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);
} }
/** /**
+5 -1
View File
@@ -731,10 +731,14 @@ static void service_cleanup(svc_t *svc)
* service_stop - Stop service * service_stop - Stop service
* @svc: Service to stop * @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: * Returns:
* 0 if the service was successfully stopped. Non-zero otherwise. * 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] = ""; char cmdline[CMD_SIZE] = "";
int do_progress = 1; int do_progress = 1;
+1
View File
@@ -40,6 +40,7 @@ int service_timeout_cancel (svc_t *svc);
void service_forked (svc_t *svc); void service_forked (svc_t *svc);
int service_stop (svc_t *svc);
int service_step (svc_t *svc); int service_step (svc_t *svc);
void service_step_all (int types); void service_step_all (int types);
void service_worker (void *unused); void service_worker (void *unused);