From 29315090f99b5f30cb23ebe6504eb9503aa5df50 Mon Sep 17 00:00:00 2001 From: Jonas Johansson Date: Wed, 18 May 2016 10:24:37 +0200 Subject: [PATCH] sm: handle reload event Signed-off-by: Jonas Johansson --- service.c | 31 +++-------------------------- sm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++---- sm.h | 12 +++++++---- 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/service.c b/service.c index 4a8b0eb9..5e22e27f 100644 --- a/service.c +++ b/service.c @@ -342,18 +342,7 @@ static int service_restart(svc_t *svc) static void service_reload_dynamic_finish(void) { in_dyn_teardown = 0; - - /* Cleanup stale services */ - svc_clean_dynamic(service_unregister); - - _d("Starting services after reconf ..."); - service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); - - _d("Calling reconf hooks ..."); - plugin_run_hooks(HOOK_SVC_RECONF); - - service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); - _d("Reconfiguration done"); + sm_step(&sm); } /** @@ -365,23 +354,9 @@ static void service_reload_dynamic_finish(void) */ void service_reload_dynamic(void) { - /* First reload all *.conf in /etc/finit.d/ */ - conf_reload_dynamic(); - - /* Then, mark all affected service conditions as in-flux and - * let all affected services move to WAITING/HALTED */ - _d("Stopping services services not allowed after reconf ..."); in_dyn_teardown = 1; - cond_reload(); - service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); - - /* Need to wait for any services to stop? If so, exit early - * and perform second stage from service_monitor later. */ - if (!service_stop_is_done()) - return; - - /* Otherwise, kick all svcs again right away */ - service_reload_dynamic_finish(); + sm_set_reload(&sm); + sm_step(&sm); } /** diff --git a/sm.c b/sm.c index 8aad6853..222f9a92 100644 --- a/sm.c +++ b/sm.c @@ -26,6 +26,7 @@ #include #include "finit.h" +#include "cond.h" #include "conf.h" #include "helpers.h" #include "private.h" @@ -38,6 +39,7 @@ void sm_init(sm_t *sm) { sm->state = SM_BOOTSTRAP_STATE; sm->newlevel = -1; + sm->reload = 0; } void sm_set_runlevel(sm_t *sm, int newlevel) @@ -45,6 +47,11 @@ void sm_set_runlevel(sm_t *sm, int newlevel) sm->newlevel = newlevel; } +void sm_set_reload(sm_t *sm) +{ + sm->reload = 1; +} + char *sm_status(sm_t *sm) { switch (sm->state) { @@ -54,8 +61,12 @@ char *sm_status(sm_t *sm) return "running"; case SM_RUNLEVEL_CHANGE_STATE: return "runlevel/change"; - case SM_RUNLEVEL_WAIT_STOP_STATE: + case SM_RUNLEVEL_WAIT_STATE: return "runlevel/wait"; + case SM_RELOAD_CHANGE_STATE: + return "reload/change"; + case SM_RELOAD_WAIT_STATE: + return "reload/wait"; default: return "unknown"; } @@ -70,7 +81,7 @@ restart: _d("state: %s", sm_status(sm)); - switch(sm->state) { + switch (sm->state) { case SM_BOOTSTRAP_STATE: _d("Bootstrapping all services in runlevel S from %s", FINIT_CONF); service_step_all(SVC_TYPE_RUN | SVC_TYPE_TASK | SVC_TYPE_SERVICE); @@ -87,6 +98,12 @@ restart: sm->state = SM_RUNLEVEL_CHANGE_STATE; break; } + /* reload ? */ + if (sm->reload) { + sm->reload = 0; + sm->state = SM_RELOAD_CHANGE_STATE; + } + break; case SM_RUNLEVEL_CHANGE_STATE: prevlevel = runlevel; @@ -102,10 +119,10 @@ restart: _d("Stopping services services not allowed in new runlevel ..."); service_step_all(SVC_TYPE_ANY); - sm->state = SM_RUNLEVEL_WAIT_STOP_STATE; + sm->state = SM_RUNLEVEL_WAIT_STATE; break; - case SM_RUNLEVEL_WAIT_STOP_STATE: + case SM_RUNLEVEL_WAIT_STATE: /* Need to wait for any services to stop? If so, exit early * and perform second stage from service_monitor later. */ if (!service_stop_is_done()) @@ -143,6 +160,40 @@ restart: sm->state = SM_RUNNING_STATE; break; + + case SM_RELOAD_CHANGE_STATE: + /* First reload all *.conf in /etc/finit.d/ */ + conf_reload_dynamic(); + + /* Then, mark all affected service conditions as in-flux and + * let all affected services move to WAITING/HALTED */ + _d("Stopping services services not allowed after reconf ..."); + cond_reload(); + service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); + + sm->state = SM_RELOAD_WAIT_STATE; + break; + + case SM_RELOAD_WAIT_STATE: + /* Need to wait for any services to stop? If so, exit early + * and perform second stage from service_monitor later. */ + if (!service_stop_is_done()) + break; + + /* Cleanup stale services */ + svc_clean_dynamic(service_unregister); + + _d("Starting services after reconf ..."); + service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); + + _d("Calling reconf hooks ..."); + plugin_run_hooks(HOOK_SVC_RECONF); + + service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD); + _d("Reconfiguration done"); + + sm->state = SM_RUNNING_STATE; + break; } if (sm->state != old_state) { diff --git a/sm.h b/sm.h index 61544352..9f158ffa 100644 --- a/sm.h +++ b/sm.h @@ -28,17 +28,21 @@ typedef enum { SM_BOOTSTRAP_STATE = 0, SM_RUNNING_STATE, SM_RUNLEVEL_CHANGE_STATE, - SM_RUNLEVEL_WAIT_STOP_STATE, + SM_RUNLEVEL_WAIT_STATE, + SM_RELOAD_CHANGE_STATE, + SM_RELOAD_WAIT_STATE, } sm_state_t; typedef struct sm { sm_state_t state; int newlevel; + int reload; } sm_t; -void sm_init(sm_t *sm); -void sm_step(sm_t *sm); -void sm_set_runlevel(sm_t *sm, int newlevel); +void sm_init(sm_t *sm); +void sm_step(sm_t *sm); +void sm_set_runlevel(sm_t *sm, int newlevel); +void sm_set_reload(sm_t *sm); #endif /* FINIT_SM_H_ */