mirror of
https://github.com/troglobit/finit.git
synced 2026-10-27 12:20:54 +00:00
services: do not start services before all stopped processes has been halted
Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se>
This commit is contained in:
1 parent
c1f725340d
commit
c5fad8e659
3 files changed
+40
-75
No files matched your search
@@ -42,8 +42,6 @@
|
|||||||
|
|
||||||
#define RESPAWN_MAX 10 /* Prevent endless respawn of faulty services. */
|
#define RESPAWN_MAX 10 /* Prevent endless respawn of faulty services. */
|
||||||
|
|
||||||
static int in_teardown = 0, in_dyn_teardown = 0;
|
|
||||||
|
|
||||||
#ifndef INETD_DISABLED
|
#ifndef INETD_DISABLED
|
||||||
static svc_t *find_inetd_svc (char *path, char *service, char *proto);
|
static svc_t *find_inetd_svc (char *path, char *service, char *proto);
|
||||||
#endif
|
#endif
|
||||||
@@ -332,19 +330,6 @@ static int service_restart(svc_t *svc)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* service_reload_dynamic_finish - Finish dynamic service reload
|
|
||||||
*
|
|
||||||
* Second stage of dynamic reload. Called either directly from first
|
|
||||||
* stage if no services had to be stopped, or later from
|
|
||||||
* service_monitor once all stopped services have been collected.
|
|
||||||
*/
|
|
||||||
static void service_reload_dynamic_finish(void)
|
|
||||||
{
|
|
||||||
in_dyn_teardown = 0;
|
|
||||||
sm_step(&sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* service_reload_dynamic - Called on SIGHUP, 'init q' or 'initctl reload'
|
* service_reload_dynamic - Called on SIGHUP, 'init q' or 'initctl reload'
|
||||||
*
|
*
|
||||||
@@ -354,24 +339,10 @@ static void service_reload_dynamic_finish(void)
|
|||||||
*/
|
*/
|
||||||
void service_reload_dynamic(void)
|
void service_reload_dynamic(void)
|
||||||
{
|
{
|
||||||
in_dyn_teardown = 1;
|
|
||||||
sm_set_reload(&sm);
|
sm_set_reload(&sm);
|
||||||
sm_step(&sm);
|
sm_step(&sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* service_runlevel_finish - Finish runlevel change
|
|
||||||
*
|
|
||||||
* Second stage of runlevel change. Called either directly from first
|
|
||||||
* stage if no services had to be stopped, or later from
|
|
||||||
* service_monitor once all stopped services have been collected.
|
|
||||||
*/
|
|
||||||
static void service_runlevel_finish(void)
|
|
||||||
{
|
|
||||||
in_teardown = 0;
|
|
||||||
sm_step(&sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* service_runlevel - Change to a new runlevel
|
* service_runlevel - Change to a new runlevel
|
||||||
* @newlevel: New runlevel to activate
|
* @newlevel: New runlevel to activate
|
||||||
@@ -381,7 +352,6 @@ static void service_runlevel_finish(void)
|
|||||||
*/
|
*/
|
||||||
void service_runlevel(int newlevel)
|
void service_runlevel(int newlevel)
|
||||||
{
|
{
|
||||||
in_teardown = 1;
|
|
||||||
sm_set_runlevel(&sm, newlevel);
|
sm_set_runlevel(&sm, newlevel);
|
||||||
sm_step(&sm);
|
sm_step(&sm);
|
||||||
}
|
}
|
||||||
@@ -627,29 +597,6 @@ void service_unregister(svc_t *svc)
|
|||||||
svc_del(svc);
|
svc_del(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* service_teardown_finish - Complete runlevel change or dynamic reload
|
|
||||||
*
|
|
||||||
* If any runlevel change or dynamic service reload is in progress and
|
|
||||||
* all services that had to be stopped have been collected, run the
|
|
||||||
* corresponding second stage.
|
|
||||||
*/
|
|
||||||
static void service_teardown_finish(void)
|
|
||||||
{
|
|
||||||
if (!(in_teardown || in_dyn_teardown))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!service_stop_is_done())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (in_teardown)
|
|
||||||
service_runlevel_finish();
|
|
||||||
|
|
||||||
if (in_dyn_teardown)
|
|
||||||
service_reload_dynamic_finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void service_monitor(pid_t lost)
|
void service_monitor(pid_t lost)
|
||||||
{
|
{
|
||||||
svc_t *svc;
|
svc_t *svc;
|
||||||
@@ -676,8 +623,7 @@ void service_monitor(pid_t lost)
|
|||||||
svc->pid = 0;
|
svc->pid = 0;
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
|
|
||||||
/* Check if we're still collecting stopped dynamic services */
|
sm_step(&sm);
|
||||||
service_teardown_finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void svc_set_state(svc_t *svc, svc_state_t new)
|
static void svc_set_state(svc_t *svc, svc_state_t new)
|
||||||
@@ -757,6 +703,10 @@ restart:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wait until all processes has been stopped before continuing... */
|
||||||
|
if (sm_is_in_teardown(&sm))
|
||||||
|
break;
|
||||||
|
|
||||||
err = service_start(svc);
|
err = service_start(svc);
|
||||||
if (err) {
|
if (err) {
|
||||||
(*restart_counter)++;
|
(*restart_counter)++;
|
||||||
@@ -813,6 +763,9 @@ restart:
|
|||||||
case COND_ON:
|
case COND_ON:
|
||||||
if (svc_is_changed(svc)) {
|
if (svc_is_changed(svc)) {
|
||||||
if (svc->sighup) {
|
if (svc->sighup) {
|
||||||
|
/* wait until all processes has been stopped before continuing... */
|
||||||
|
if (sm_is_in_teardown(&sm))
|
||||||
|
break;
|
||||||
service_restart(svc);
|
service_restart(svc);
|
||||||
} else {
|
} else {
|
||||||
service_stop(svc);
|
service_stop(svc);
|
||||||
|
|||||||
@@ -40,19 +40,10 @@ void sm_init(sm_t *sm)
|
|||||||
sm->state = SM_BOOTSTRAP_STATE;
|
sm->state = SM_BOOTSTRAP_STATE;
|
||||||
sm->newlevel = -1;
|
sm->newlevel = -1;
|
||||||
sm->reload = 0;
|
sm->reload = 0;
|
||||||
|
sm->in_teardown = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm_set_runlevel(sm_t *sm, int newlevel)
|
static char *sm_status(sm_t *sm)
|
||||||
{
|
|
||||||
sm->newlevel = newlevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sm_set_reload(sm_t *sm)
|
|
||||||
{
|
|
||||||
sm->reload = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *sm_status(sm_t *sm)
|
|
||||||
{
|
{
|
||||||
switch (sm->state) {
|
switch (sm->state) {
|
||||||
case SM_BOOTSTRAP_STATE:
|
case SM_BOOTSTRAP_STATE:
|
||||||
@@ -72,6 +63,21 @@ char *sm_status(sm_t *sm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sm_set_runlevel(sm_t *sm, int newlevel)
|
||||||
|
{
|
||||||
|
sm->newlevel = newlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm_set_reload(sm_t *sm)
|
||||||
|
{
|
||||||
|
sm->reload = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sm_is_in_teardown(sm_t *sm)
|
||||||
|
{
|
||||||
|
return sm->in_teardown;
|
||||||
|
}
|
||||||
|
|
||||||
void sm_step(sm_t *sm)
|
void sm_step(sm_t *sm)
|
||||||
{
|
{
|
||||||
sm_state_t old_state;
|
sm_state_t old_state;
|
||||||
@@ -117,6 +123,7 @@ restart:
|
|||||||
conf_reload_dynamic();
|
conf_reload_dynamic();
|
||||||
|
|
||||||
_d("Stopping services services not allowed in new runlevel ...");
|
_d("Stopping services services not allowed in new runlevel ...");
|
||||||
|
sm->in_teardown = 1;
|
||||||
service_step_all(SVC_TYPE_ANY);
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
sm->state = SM_RUNLEVEL_WAIT_STATE;
|
sm->state = SM_RUNLEVEL_WAIT_STATE;
|
||||||
@@ -133,6 +140,7 @@ restart:
|
|||||||
plugin_run_hooks(HOOK_RUNLEVEL_CHANGE); /* Reconfigure HW/VLANs/etc here */
|
plugin_run_hooks(HOOK_RUNLEVEL_CHANGE); /* Reconfigure HW/VLANs/etc here */
|
||||||
|
|
||||||
_d("Starting services services new to this runlevel ...");
|
_d("Starting services services new to this runlevel ...");
|
||||||
|
sm->in_teardown = 0;
|
||||||
service_step_all(SVC_TYPE_ANY);
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
/* Cleanup stale services */
|
/* Cleanup stale services */
|
||||||
@@ -168,6 +176,7 @@ restart:
|
|||||||
/* Then, mark all affected service conditions as in-flux and
|
/* Then, mark all affected service conditions as in-flux and
|
||||||
* let all affected services move to WAITING/HALTED */
|
* let all affected services move to WAITING/HALTED */
|
||||||
_d("Stopping services services not allowed after reconf ...");
|
_d("Stopping services services not allowed after reconf ...");
|
||||||
|
sm->in_teardown = 1;
|
||||||
cond_reload();
|
cond_reload();
|
||||||
service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD);
|
service_step_all(SVC_TYPE_SERVICE | SVC_TYPE_INETD);
|
||||||
|
|
||||||
@@ -180,6 +189,7 @@ restart:
|
|||||||
if (!service_stop_is_done())
|
if (!service_stop_is_done())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
sm->in_teardown = 0;
|
||||||
/* Cleanup stale services */
|
/* Cleanup stale services */
|
||||||
svc_clean_dynamic(service_unregister);
|
svc_clean_dynamic(service_unregister);
|
||||||
|
|
||||||
|
|||||||
@@ -25,24 +25,26 @@
|
|||||||
#define FINIT_SM_H_
|
#define FINIT_SM_H_
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SM_BOOTSTRAP_STATE = 0,
|
SM_BOOTSTRAP_STATE = 0, /* Init state, bootstrap services */
|
||||||
SM_RUNNING_STATE,
|
SM_RUNNING_STATE, /* Normal state, services running */
|
||||||
SM_RUNLEVEL_CHANGE_STATE,
|
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occured */
|
||||||
SM_RUNLEVEL_WAIT_STATE,
|
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped runlevel processes to be halted */
|
||||||
SM_RELOAD_CHANGE_STATE,
|
SM_RELOAD_CHANGE_STATE, /* A reload event has occured */
|
||||||
SM_RELOAD_WAIT_STATE,
|
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped reload processes to be halted */
|
||||||
} sm_state_t;
|
} sm_state_t;
|
||||||
|
|
||||||
typedef struct sm {
|
typedef struct sm {
|
||||||
sm_state_t state;
|
sm_state_t state; /* Running, Changed, Waiting, ... */
|
||||||
int newlevel;
|
int newlevel; /* Set on runlevel change to new runlevel, -1 if not change */
|
||||||
int reload;
|
int reload; /* Set on reload event, else 0 */
|
||||||
|
int in_teardown; /* Set when waiting for all processes to be halted */
|
||||||
} sm_t;
|
} sm_t;
|
||||||
|
|
||||||
void sm_init(sm_t *sm);
|
void sm_init(sm_t *sm);
|
||||||
void sm_step(sm_t *sm);
|
void sm_step(sm_t *sm);
|
||||||
void sm_set_runlevel(sm_t *sm, int newlevel);
|
void sm_set_runlevel(sm_t *sm, int newlevel);
|
||||||
void sm_set_reload(sm_t *sm);
|
void sm_set_reload(sm_t *sm);
|
||||||
|
int sm_is_in_teardown(sm_t *sm);
|
||||||
|
|
||||||
#endif /* FINIT_SM_H_ */
|
#endif /* FINIT_SM_H_ */
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user