Reassert condition when svc_t goes from WAITING --> RUNNING

Reassert condition when an unchanged/unmodified process goes from
WAITING state to RUNNING.  I.e. it had a condition that went to flux
during `initctl reload`, which drove it to WAITING and was then sent
SIGSTOP during reconf.

Also, on condition update, loop through all services until no more state
changes are observed.  This allows long dependency chains of services to
resolve and actually go back to RUNNING state as intended whenever any
condition changes at runtime.

Signed-off-by: Jonas Johansson <jonasj76@gmail.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Jonas Johansson
2018-10-02 19:03:30 +02:00
committed by Joachim Nilsson
parent cb9f6213dc
commit dddd45e3b5
5 changed files with 27 additions and 13 deletions
-6
View File
@@ -37,12 +37,6 @@ struct context {
int wd;
};
static char *mkcond(char *buf, size_t len, char *nm)
{
snprintf(buf, len, "svc%s%s", nm[0] != '/' ? "/" : "", nm);
return buf;
}
static void pidfile_callback(void *arg, int fd, int events)
{
static char ev_buf[8 *(sizeof(struct inotify_event) + NAME_MAX + 1) + 1];
+10 -6
View File
@@ -140,15 +140,19 @@ static int svc_has_cond(svc_t *svc)
static void cond_update(const char *name)
{
svc_t *svc, *iter = NULL;
int restart = 0;
_d("%s", name);
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (!svc_has_cond(svc) || !cond_affects(name, svc->cond))
continue;
do {
restart = 0;
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (!svc_has_cond(svc) || !cond_affects(name, svc->cond))
continue;
_d("%s: match <%s> %s(%s)", name ?: "nil", svc->cond, svc->desc, svc->cmd);
service_step(svc);
}
_d("%s: match <%s> %s(%s)", name ?: "nil", svc->cond, svc->desc, svc->cmd);
restart += service_step(svc);
}
} while (restart);
}
void cond_set(const char *name)
+6
View File
@@ -30,6 +30,12 @@
#include "service.h"
char *mkcond(char *buf, size_t len, char *nm)
{
snprintf(buf, len, "svc%s%s", nm[0] != '/' ? "/" : "", nm);
return buf;
}
const char *condstr(enum cond_state s)
{
static const char *strs[] = {
+1
View File
@@ -13,6 +13,7 @@ typedef enum cond_state {
COND_ON
} cond_state_t;
char *mkcond (char *buf, size_t len, char *nm);
const char *condstr (enum cond_state s);
const char *cond_path (const char *name);
unsigned int cond_get_gen (const char *path);
+10 -1
View File
@@ -1009,6 +1009,7 @@ int service_step(svc_t *svc)
svc_cmd_t enabled;
svc_state_t old_state;
cond_state_t cond;
int restarts = 0;
restart:
old_state = svc->state;
@@ -1165,6 +1166,13 @@ restart:
case COND_ON:
kill(svc->pid, SIGCONT);
svc_set_state(svc, SVC_RUNNING_STATE);
/* Reassert condition if we go from waiting and no change */
if (!svc_is_changed(svc)) {
char cond[MAX_COND_LEN];
mkcond(cond, sizeof(cond), svc->cmd);
cond_set_path(cond_path(cond), COND_ON);
}
break;
case COND_OFF:
@@ -1180,10 +1188,11 @@ restart:
if (svc->state != old_state) {
_d("%20s(%4d): -> %8s", svc->cmd, svc->pid, svc_status(svc));
restarts++;
goto restart;
}
return 0;
return restarts;
}
void service_step_all(int types)