Merge pull request #24 from westermo/wmo/2.4

Assert svc condition only when PID file has been created/updated

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2016-04-10 19:50:16 +02:00
commit d7d45b65d0
3 files changed
+22 -4

No files matched your search

+11 -4
View File
@@ -71,13 +71,20 @@ static void pidfile_callback(void *UNUSED(arg), int fd, int UNUSED(events))
_d("%s: match %s", basename, svc->cmd); _d("%s: match %s", basename, svc->cmd);
snprintf(cond, sizeof(cond), "svc%s", svc->cmd); snprintf(cond, sizeof(cond), "svc%s", svc->cmd);
if (ev->mask & (IN_CREATE | IN_ATTRIB)) if (ev->mask & (IN_CREATE | IN_ATTRIB)) {
svc_started(svc);
cond_set(cond); cond_set(cond);
else if (ev->mask & IN_DELETE) } else if (ev->mask & IN_DELETE)
cond_clear(cond); cond_clear(cond);
} }
} }
/*
* Assert condition only if the service is running, but not if it's
* recently been changed or while it's starting up.
*
* We must wait for the service to create/touch its pidfile.
*/
static void pidfile_reconf(void *_null) static void pidfile_reconf(void *_null)
{ {
static char name[MAX_ARG_LEN]; static char name[MAX_ARG_LEN];
@@ -86,14 +93,14 @@ static void pidfile_reconf(void *_null)
(void)(_null); (void)(_null);
for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) { for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
if (svc->state == SVC_RUNNING_STATE && !svc_is_changed(svc)) { if (svc->state == SVC_RUNNING_STATE && !svc_is_changed(svc) && !svc_is_starting(svc)) {
snprintf(name, MAX_ARG_LEN, "svc%s", svc->cmd); snprintf(name, MAX_ARG_LEN, "svc%s", svc->cmd);
cond_set_path(cond_path(name), COND_ON); cond_set_path(cond_path(name), COND_ON);
} }
} }
} }
static void pidfile_init (void *arg) static void pidfile_init(void *arg)
{ {
struct context *ctx = arg; struct context *ctx = arg;
+6
View File
@@ -153,6 +153,9 @@ static int service_start(svc_t *svc)
} }
#endif #endif
/* Declare we're waiting for svc to create its pidfile */
svc_starting(svc);
/* Block sigchild while forking. */ /* Block sigchild while forking. */
sigemptyset(&nmask); sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD); sigaddset(&nmask, SIGCHLD);
@@ -341,6 +344,9 @@ static int service_restart(svc_t *svc)
if (verbose) if (verbose)
print_desc("Restarting ", svc->desc); print_desc("Restarting ", svc->desc);
/* Declare we're waiting for svc to re-assert/touch its pidfile */
svc_starting(svc);
_d("Sending SIGHUP to PID %d", svc->pid); _d("Sending SIGHUP to PID %d", svc->pid);
err = kill(svc->pid, SIGHUP); err = kill(svc->pid, SIGHUP);
+5
View File
@@ -88,6 +88,7 @@ typedef struct svc {
time_t mtime; /* Modification time for .conf from /etc/finit.d/ */ time_t mtime; /* Modification time for .conf from /etc/finit.d/ */
const int dirty; /* Set if old mtime != new mtime => reloaded, const int dirty; /* Set if old mtime != new mtime => reloaded,
* or -1 when marked for removal */ * or -1 when marked for removal */
int starting; /* ... waiting for pidfile to be re-asserted */
int runlevels; int runlevels;
int sighup; /* This service supports SIGHUP :) */ int sighup; /* This service supports SIGHUP :) */
svc_block_t block; /* Reason that this service is currently blocked */ svc_block_t block; /* Reason that this service is currently blocked */
@@ -168,6 +169,10 @@ int svc_is_unique (svc_t *svc);
static inline int svc_in_runlevel(svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); } static inline int svc_in_runlevel(svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
static inline int svc_has_sighup(svc_t *svc) { return svc && 0 != svc->sighup; } static inline int svc_has_sighup(svc_t *svc) { return svc && 0 != svc->sighup; }
static inline void svc_starting (svc_t *svc) { svc->starting = 1; }
static inline void svc_started (svc_t *svc) { svc->starting = 0; }
static inline int svc_is_starting(svc_t *svc) { 0 != svc->starting; }
static inline int svc_is_dynamic(svc_t *svc) { return svc && 0 != svc->mtime; } static inline int svc_is_dynamic(svc_t *svc) { return svc && 0 != svc->mtime; }
static inline int svc_is_removed(svc_t *svc) { return svc && -1 == svc->dirty; } static inline int svc_is_removed(svc_t *svc) { return svc && -1 == svc->dirty; }
static inline int svc_is_changed(svc_t *svc) { return svc && 0 != svc->dirty; } static inline int svc_is_changed(svc_t *svc) { return svc && 0 != svc->dirty; }