From 4d05bf9359058896163bec3c649daa87bc266675 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 7 Mar 2021 13:26:56 +0100 Subject: [PATCH] Mark affected services as dirty if their rdeps are dirty Provided a configuration that looks like this: ospfd.conf: service [2345] log ospfd -A 127.0.0.1 -u root -g root -- OSPF daemon zebra.conf: service [2345] log zebra -A 127.0.0.1 -u root -g root -- Zebra Routing daemon If zebra.conf is changed, we restart it when `initctl reload` is issued. This change ensures that ospfd is also restarted, because ospfd depends on zebra, we must restart it too. Signed-off-by: Joachim Wiberg --- src/cond-w.c | 20 -------------------- src/conf.c | 2 ++ src/service.c | 32 ++++++++++++++++++++++++++++++++ src/service.h | 1 + src/svc.h | 20 ++++++++++++++++++++ 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/cond-w.c b/src/cond-w.c index e5f7456e..daa90d08 100644 --- a/src/cond-w.c +++ b/src/cond-w.c @@ -162,26 +162,6 @@ int cond_set_path(const char *path, enum cond_state new) return new != old; } -/* Has condition in configuration and cond is allowed? */ -static int svc_has_cond(svc_t *svc) -{ - if (!svc->cond[0]) - return 0; - - switch (svc->type) { - case SVC_TYPE_SERVICE: - case SVC_TYPE_TASK: - case SVC_TYPE_RUN: - case SVC_TYPE_SYSV: - return 1; - - default: - break; - } - - return 0; -} - static void cond_update(const char *name) { svc_t *svc, *iter = NULL; diff --git a/src/conf.c b/src/conf.c index f34cf34a..8cb91d78 100644 --- a/src/conf.c +++ b/src/conf.c @@ -697,6 +697,8 @@ int conf_reload(void) globfree(&gl); + /* Mark any reverse deps as chenaged. */ + service_update_rdeps(); done: /* Drop record of all .conf changes */ drop_changes(); diff --git a/src/service.c b/src/service.c index e56adee7..cf04fa56 100644 --- a/src/service.c +++ b/src/service.c @@ -1250,6 +1250,38 @@ void service_monitor(pid_t lost, int status) sm_step(&sm); } +static void svc_mark_affected(char *cond) +{ + svc_t *svc, *iter = NULL; + + for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) { + if (!svc_has_cond(svc)) + continue; + + if (cond_affects(cond, svc->cond)) + svc_mark_dirty(svc); + } +} + +/* + * Called on conf_reload() to update service reverse dependencies. + * E.g., if ospfd depends on zebra and the zebra Finit conf has + * changed, we need to mark the ospfd Finit conf as changed too. + */ +void service_update_rdeps(void) +{ + svc_t *svc, *iter = NULL; + + for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) { + char cond[MAX_COND_LEN]; + + if (!svc_is_changed(svc)) + continue; + + svc_mark_affected(mkcond(svc, cond, sizeof(cond))); + } +} + static void service_retry(svc_t *svc) { int timeout; diff --git a/src/service.h b/src/service.h index b1ee2081..e9688868 100644 --- a/src/service.h +++ b/src/service.h @@ -33,6 +33,7 @@ void service_unregister (svc_t *svc); void service_runtask_clean (void); void service_reload_dynamic (void); +void service_update_rdeps (void); int service_step (svc_t *svc); void service_step_all (int types); diff --git a/src/svc.h b/src/svc.h index cf510127..edd38d87 100644 --- a/src/svc.h +++ b/src/svc.h @@ -208,6 +208,26 @@ static inline void svc_missing (svc_t *svc) { if (svc) svc->block = SVC_BLOC static inline void svc_restarting (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_RESTARTING; } static inline void svc_crashing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_CRASHING; } +/* Has condition in configuration and cond is allowed? */ +static inline int svc_has_cond(svc_t *svc) +{ + if (!svc->cond[0]) + return 0; + + switch (svc->type) { + case SVC_TYPE_SERVICE: + case SVC_TYPE_TASK: + case SVC_TYPE_RUN: + case SVC_TYPE_SYSV: + return 1; + + default: + break; + } + + return 0; +} + static inline char *svc_status(svc_t *svc) { if (!svc)