From dddd45e3b59493b6ba20273399e40ac9912507dd Mon Sep 17 00:00:00 2001 From: Jonas Johansson Date: Tue, 2 Oct 2018 13:29:46 +0200 Subject: [PATCH] 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 Signed-off-by: Joachim Nilsson --- plugins/pidfile.c | 6 ------ src/cond-w.c | 16 ++++++++++------ src/cond.c | 6 ++++++ src/cond.h | 1 + src/service.c | 11 ++++++++++- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/plugins/pidfile.c b/plugins/pidfile.c index 44515b00..23179586 100644 --- a/plugins/pidfile.c +++ b/plugins/pidfile.c @@ -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]; diff --git a/src/cond-w.c b/src/cond-w.c index afe69a63..14cae487 100644 --- a/src/cond-w.c +++ b/src/cond-w.c @@ -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) diff --git a/src/cond.c b/src/cond.c index 9698b963..38c62348 100644 --- a/src/cond.c +++ b/src/cond.c @@ -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[] = { diff --git a/src/cond.h b/src/cond.h index 90378765..6512a721 100644 --- a/src/cond.h +++ b/src/cond.h @@ -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); diff --git a/src/service.c b/src/service.c index 3f1e27e5..6f54c5a4 100644 --- a/src/service.c +++ b/src/service.c @@ -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)