From 11a3318c02ea4108dfa0d0045719b94c6ccb62e1 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 11 Mar 2021 11:39:53 +0100 Subject: [PATCH] Properly set status 'missing' for missing binaries and/or env files When we try to start a service/run/task we call whichp() to see if the binary exists, either tha absolute path given in the .conf file, or in the $PATH we run with. If binary, or the env: file, doesn't exist we now set svc_missing() state. On `initctl reload` we unblock the service to be able to check again. Signed-off-by: Joachim Wiberg --- src/service.c | 13 +++++++++++-- src/svc.c | 3 +++ src/svc.h | 8 +++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/service.c b/src/service.c index cf04fa56..f9881a83 100644 --- a/src/service.c +++ b/src/service.c @@ -407,14 +407,15 @@ static int service_start(svc_t *svc) /* Don't try and start service if it doesn't exist. */ if (!whichp(svc->cmd)) { - print(1, "%s: does not exist", svc->cmd); + logit(LOG_WARNING, "%s: missing or not in $PATH", svc->cmd); svc_missing(svc); return 1; } /* Unlike systemd we do not allow starting service if env is missing, unless - */ if (!check_env(svc)) { - print(1, "%s: environment file %s does not exist (yet)", svc->cmd, svc->env); + logit(LOG_WARNING, "%s: missing env file %s", svc->cmd, svc->env); + svc_missing(svc); return 1; } @@ -1127,6 +1128,9 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file) if (type == SVC_TYPE_SERVICE && manual) svc_stop(svc); + } else { + /* e.g., if missing cmd or env before */ + svc_unblock(svc); } /* Always clear svc PID file, for now. See TODO */ @@ -1229,6 +1233,7 @@ void service_monitor(pid_t lost, int status) if (svc_is_daemon(svc)) { service_cleanup(svc); } else if (svc_is_runtask(svc)) { + /* run/task should run at least once per runlevel */ if (WIFEXITED(status) && !WEXITSTATUS(status)) svc->started = 1; else @@ -1400,6 +1405,10 @@ restart: err = service_start(svc); if (err) { + if (svc_is_missing(svc)) { + svc_set_state(svc, SVC_HALTED_STATE); + break; + } (*restart_cnt)++; break; } diff --git a/src/svc.c b/src/svc.c index f6662a05..323243c4 100644 --- a/src/svc.c +++ b/src/svc.c @@ -534,6 +534,9 @@ int svc_enabled(svc_t *svc) if (svc_is_removed(svc) || svc_is_blocked(svc)) return 0; + if (svc_is_missing(svc)) + return 0; + return 1; } diff --git a/src/svc.h b/src/svc.h index edd38d87..710c0989 100644 --- a/src/svc.h +++ b/src/svc.h @@ -194,12 +194,14 @@ static inline void svc_starting (svc_t *svc) { if (svc) svc->starting = 1; static inline void svc_started (svc_t *svc) { if (svc) svc->starting = 0; } static inline int svc_is_starting (svc_t *svc) { return svc && 0 != svc->starting; } -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_updated (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_updated (svc_t *svc) { return svc && 1 == svc->dirty; } static inline int svc_is_blocked (svc_t *svc) { return svc && svc->block != SVC_BLOCK_NONE; } static inline int svc_is_busy (svc_t *svc) { return svc && svc->block == SVC_BLOCK_BUSY; } +static inline int svc_is_missing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_MISSING; } + static inline void svc_unblock (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_NONE; } #define svc_start(svc) svc_unblock(svc) static inline void svc_stop (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_USER; }