mirror of
https://github.com/troglobit/finit.git
synced 2026-10-14 10:19:36 +00:00
Fix restart logic of sysv start/stop scripts and forking services
Init script return pretty quickly after launch, so we cannot use that to detect if they, or the daemon they launched, have crashed. So we start the service_retry() with a 2 sec delay, which should be ample time to allow the pidfile plugin to detect a forking service's new PID. In release-cycle regression, no public issue needed. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
50f2cbf600
commit
9b17ce0b7c
3 files changed
+33
-16
No files matched your search
@@ -98,6 +98,9 @@ static void pidfile_update_conds(char *dir, char *name, uint32_t mask)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Service is not crashing, let's tell state machine! */
|
||||
service_forked(svc);
|
||||
|
||||
if (pid != svc->pid) {
|
||||
_d("Forking service %s changed PID from %d to %d",
|
||||
svc->cmd, svc->pid, pid);
|
||||
|
||||
+28
-16
@@ -1557,7 +1557,7 @@ void service_monitor(pid_t lost, int status)
|
||||
/* Likely start script exiting */
|
||||
if (svc_is_starting(svc)) {
|
||||
svc->pid = 0; /* Expect no more activity from this one */
|
||||
return;
|
||||
goto cont;
|
||||
}
|
||||
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "Stopped %s[%d]", svc_ident(svc, NULL, 0), lost);
|
||||
@@ -1581,7 +1581,7 @@ void service_monitor(pid_t lost, int status)
|
||||
done:
|
||||
/* No longer running, update books. */
|
||||
svc->start_time = svc->pid = 0;
|
||||
|
||||
cont:
|
||||
if (!service_step(svc)) {
|
||||
/* Clean out any bootstrap tasks, they've had their time in the sun. */
|
||||
if (svc_clean_bootstrap(svc))
|
||||
@@ -1745,6 +1745,7 @@ static void service_retry(svc_t *svc)
|
||||
|
||||
if (svc->state != SVC_HALTED_STATE ||
|
||||
svc->block != SVC_BLOCK_RESTARTING) {
|
||||
svc_set_state(svc, SVC_RUNNING_STATE);
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "Successfully restarted crashing service %s.",
|
||||
svc_ident(svc, NULL, 0));
|
||||
return;
|
||||
@@ -1834,6 +1835,21 @@ static void svc_set_state(svc_t *svc, svc_state_t new)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by pidfile plugin for forking services that have successfully started.
|
||||
* We get here when the service_monitor() collects the PID, sets svc->pid to 0,
|
||||
* and the state machine prepares for the worst bu setting state to HALTED.
|
||||
*/
|
||||
void service_forked(svc_t *svc)
|
||||
{
|
||||
/* Stop forking_retry() timer */
|
||||
service_timeout_cancel(svc);
|
||||
|
||||
/* Not crashing, restore RUNNING state */
|
||||
svc_unblock(svc);
|
||||
svc_set_state(svc, SVC_RUNNING_STATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Transition task/run/service
|
||||
*
|
||||
@@ -1944,30 +1960,26 @@ restart:
|
||||
}
|
||||
|
||||
if (!svc->pid) {
|
||||
if (svc_is_daemon(svc) || svc_is_tty(svc)) {
|
||||
if (svc_is_forking(svc))
|
||||
break;
|
||||
|
||||
if (svc_is_daemon(svc) || svc_is_sysv(svc) || svc_is_tty(svc)) {
|
||||
svc_restarting(svc);
|
||||
svc_set_state(svc, SVC_HALTED_STATE);
|
||||
|
||||
/*
|
||||
* Restart directly after the first crash,
|
||||
* then retry after 2 sec
|
||||
* Restart directly after the first crash, except for forking services
|
||||
* which we need to wait for the forked-off child to create its pid
|
||||
* file. In both cases, after that, retry after 2 sec
|
||||
*/
|
||||
if (!svc->respawn)
|
||||
_d("delayed restart of %s", svc_ident(svc, NULL, 0));
|
||||
service_timeout_after(svc, 1, service_retry);
|
||||
if (svc_is_forking(svc))
|
||||
service_timeout_after(svc, 2000, service_retry);
|
||||
else
|
||||
service_timeout_after(svc, 1, service_retry);
|
||||
break;
|
||||
}
|
||||
|
||||
if (svc_is_runtask(svc)) {
|
||||
if (svc_is_sysv(svc)) {
|
||||
if (!svc->started)
|
||||
svc_set_state(svc, SVC_STOPPING_STATE);
|
||||
} else {
|
||||
svc_set_state(svc, SVC_STOPPING_STATE);
|
||||
}
|
||||
if (svc_is_runtask(svc)) { /* only run/task, not sysv here */
|
||||
svc_set_state(svc, SVC_STOPPING_STATE);
|
||||
svc->once++;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ void service_update_rdeps (void);
|
||||
int service_timeout_after (svc_t *svc, int timeout, void (*cb)(svc_t *svc));
|
||||
int service_timeout_cancel (svc_t *svc);
|
||||
|
||||
void service_forked (svc_t *svc);
|
||||
|
||||
int service_step (svc_t *svc);
|
||||
void service_step_all (int types);
|
||||
void service_worker (void *unused);
|
||||
|
||||
Reference in new issue
Block a user