mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +07:00
Refactor state machine control functions
This refactor should have been done years ago when we first introduced the big state machine. The old functions service_runvel() and the oddly named service_reload_dynamic() are actually state machine control fns, so let relocate them. Also in this commit, remove the global variable 'sm' and rename a few of the critical functions to better names. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
#include "private.h"
|
||||
#include "schedule.h"
|
||||
#include "service.h"
|
||||
#include "sm.h"
|
||||
#include "sig.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -275,19 +276,19 @@ static int do_reboot(int cmd, int timeout, char *buf, size_t len)
|
||||
case INIT_CMD_REBOOT:
|
||||
dbg("reboot");
|
||||
halt = SHUT_REBOOT;
|
||||
service_runlevel(6);
|
||||
sm_runlevel(6);
|
||||
break;
|
||||
|
||||
case INIT_CMD_HALT:
|
||||
dbg("halt");
|
||||
halt = SHUT_HALT;
|
||||
service_runlevel(0);
|
||||
sm_runlevel(0);
|
||||
break;
|
||||
|
||||
case INIT_CMD_POWEROFF:
|
||||
dbg("poweroff");
|
||||
halt = SHUT_OFF;
|
||||
service_runlevel(0);
|
||||
sm_runlevel(0);
|
||||
break;
|
||||
|
||||
case INIT_CMD_SUSPEND:
|
||||
@@ -316,7 +317,7 @@ typedef struct {
|
||||
} ev_t;
|
||||
|
||||
ev_t ev_list[] = {
|
||||
{ "RELOAD", service_reload_dynamic },
|
||||
{ "RELOAD", sm_reload },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -437,7 +438,7 @@ static void api_cb(uev_t *w, void *arg, int events)
|
||||
if (runlevel == INIT_LEVEL)
|
||||
cfglevel = lvl;
|
||||
else
|
||||
service_runlevel(lvl);
|
||||
sm_runlevel(lvl);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -453,7 +454,7 @@ static void api_cb(uev_t *w, void *arg, int events)
|
||||
|
||||
case INIT_CMD_RELOAD: /* 'init q' and 'initctl reload' */
|
||||
dbg("reload");
|
||||
service_reload_dynamic();
|
||||
sm_reload();
|
||||
break;
|
||||
|
||||
case INIT_CMD_START_SVC:
|
||||
|
||||
+1
-1
@@ -303,7 +303,7 @@ static void cgroup_events_cb(uev_t *w, void *arg, int events)
|
||||
|
||||
#ifdef AUTO_RELOAD
|
||||
if (conf_any_change())
|
||||
service_reload_dynamic();
|
||||
sm_reload();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -218,7 +218,7 @@ static int do_delete(const char *fpath, const struct stat *sb, int tflag, struct
|
||||
err(1, "Failed removing condition %s", fpath);
|
||||
|
||||
cond = ptr + strlen(COND_BASE) + 1;
|
||||
if (sm_is_in_teardown(&sm))
|
||||
if (sm_in_reload())
|
||||
cond_clear_noupdate(cond);
|
||||
else
|
||||
cond_update(cond);
|
||||
|
||||
+1
-1
@@ -1577,7 +1577,7 @@ static void conf_cb(uev_t *w, void *arg, int events)
|
||||
|
||||
#ifdef AUTO_RELOAD
|
||||
if (conf_any_change())
|
||||
service_reload_dynamic();
|
||||
sm_reload();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -745,8 +745,8 @@ int main(int argc, char *argv[])
|
||||
* Initialize state machine and start all bootstrap tasks
|
||||
* NOTE: no network available!
|
||||
*/
|
||||
sm_init(&sm);
|
||||
sm_step(&sm);
|
||||
sm_init();
|
||||
sm_step();
|
||||
|
||||
/*
|
||||
* Enter main loop to monitor /dev/initctl and services
|
||||
|
||||
+7
-38
@@ -1182,38 +1182,6 @@ static int service_restart(svc_t *svc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* service_reload_dynamic - Called on SIGHUP, 'init q' or 'initctl reload'
|
||||
*
|
||||
* This function is called when Finit has received SIGHUP to reload
|
||||
* .conf files in /etc/finit.d. It is responsible for starting,
|
||||
* stopping and reloading (forwarding SIGHUP) to processes affected.
|
||||
*/
|
||||
void service_reload_dynamic(void)
|
||||
{
|
||||
sm_set_reload(&sm);
|
||||
sm_step(&sm);
|
||||
}
|
||||
|
||||
/**
|
||||
* service_runlevel - Change to a new runlevel
|
||||
* @newlevel: New runlevel to activate
|
||||
*
|
||||
* Stops all services not in @newlevel and starts, or lets continue to run,
|
||||
* those in @newlevel. Also updates @prevlevel and active @runlevel.
|
||||
*/
|
||||
void service_runlevel(int newlevel)
|
||||
{
|
||||
if (!rescue && (runlevel == 1 || runlevel == INIT_LEVEL) && !IS_RESERVED_RUNLEVEL(newlevel))
|
||||
networking(1);
|
||||
|
||||
sm_set_runlevel(&sm, newlevel);
|
||||
sm_step(&sm);
|
||||
|
||||
if (!rescue && IS_RESERVED_RUNLEVEL(runlevel))
|
||||
networking(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse run/task/service arguments with support for quoted strings, both
|
||||
* single and double quotes to allow arguments containing spaces.
|
||||
@@ -2137,7 +2105,7 @@ cont:
|
||||
dbg("collected bootstrap task %s(%d), removing.", svc_ident(svc, NULL, 0), lost);
|
||||
}
|
||||
|
||||
sm_step(&sm);
|
||||
sm_step();
|
||||
}
|
||||
|
||||
static void svc_mark_affected(char *cond)
|
||||
@@ -2518,7 +2486,7 @@ static void svc_set_state(svc_t *svc, svc_state_t new_state)
|
||||
if ((old_state == SVC_RUNNING_STATE && new_state == SVC_PAUSED_STATE) ||
|
||||
(old_state == SVC_PAUSED_STATE && new_state == SVC_RUNNING_STATE))
|
||||
; /* only paused during reload, don't clear conds. */
|
||||
else if (sm_is_in_teardown(&sm))
|
||||
else if (sm_in_reload())
|
||||
cond_clear_noupdate(cond);
|
||||
else
|
||||
cond_clear(cond);
|
||||
@@ -2713,7 +2681,7 @@ restart:
|
||||
svc_set_state(svc, SVC_HALTED_STATE);
|
||||
} else if (cond_get_agg(svc->cond) == COND_ON) {
|
||||
/* wait until all processes have been stopped before continuing... */
|
||||
if (sm_is_in_teardown(&sm))
|
||||
if (sm_in_reload())
|
||||
break;
|
||||
|
||||
/* Don't start if it conflicts with something else already started */
|
||||
@@ -2808,15 +2776,16 @@ restart:
|
||||
|
||||
case COND_ON:
|
||||
if (svc_is_changed(svc)) {
|
||||
if (svc_nohup(svc) || !svc_is_daemon(svc))
|
||||
if (svc_nohup(svc) || !svc_is_daemon(svc)) {
|
||||
service_stop(svc);
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* wait until all processes have been
|
||||
* stopped before continuing...
|
||||
*/
|
||||
if (sm_is_in_teardown(&sm))
|
||||
if (sm_in_reload())
|
||||
break;
|
||||
|
||||
service_restart(svc);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,10 @@
|
||||
|
||||
#include "svc.h"
|
||||
|
||||
void service_runlevel (int newlevel);
|
||||
int service_register (int type, char *line, struct rlimit rlimit[], char *file);
|
||||
void service_unregister (svc_t *svc);
|
||||
|
||||
void service_runtask_clean (void);
|
||||
void service_reload_dynamic (void);
|
||||
void service_update_rdeps (void);
|
||||
void service_mark_unavail (void);
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#include "private.h"
|
||||
#include "sig.h"
|
||||
#include "service.h"
|
||||
#include "sm.h"
|
||||
#include "util.h"
|
||||
#include "utmp-api.h"
|
||||
|
||||
@@ -444,7 +445,7 @@ static void sighup_cb(uev_t *w, void *arg, int events)
|
||||
api_init(w->ctx);
|
||||
|
||||
/* INIT_CMD_RELOAD: 'init q', 'initctl reload', and SIGHUP */
|
||||
service_reload_dynamic();
|
||||
sm_reload();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -528,7 +529,7 @@ static void sigusr2_cb(uev_t *w, void *arg, int events)
|
||||
}
|
||||
|
||||
halt = SHUT_OFF;
|
||||
service_runlevel(0);
|
||||
sm_runlevel(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -551,7 +552,7 @@ static void sigterm_cb(uev_t *w, void *arg, int events)
|
||||
}
|
||||
|
||||
halt = SHUT_REBOOT;
|
||||
service_runlevel(6);
|
||||
sm_runlevel(6);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -38,7 +38,24 @@
|
||||
#include "sm.h"
|
||||
#include "utmp-api.h"
|
||||
|
||||
sm_t sm;
|
||||
typedef enum {
|
||||
SM_BOOTSTRAP_STATE = 0, /* Init state, bootstrap services */
|
||||
SM_BOOTSTRAP_WAIT_STATE, /* Waiting for bootstrap to complete */
|
||||
SM_RUNNING_STATE, /* Normal state, services running */
|
||||
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occurred */
|
||||
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped processes to halt */
|
||||
SM_RUNLEVEL_CLEAN_STATE, /* Wait for post:scripts and cleanup:scripts */
|
||||
SM_RELOAD_CHANGE_STATE, /* A reload event has occurred */
|
||||
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped processes to halt */
|
||||
SM_RELOAD_CLEAN_STATE, /* Wait for post:scripts and cleanup:scripts */
|
||||
} sm_state_t;
|
||||
|
||||
static struct {
|
||||
sm_state_t state; /* Running, Changed, Waiting, ... */
|
||||
int newlevel; /* Set to new runlevel on change, -1 otherwise */
|
||||
int reload; /* Set on reload event, else 0 */
|
||||
int in_reload; /* Set when waiting for all processes to be halted */
|
||||
} sm;
|
||||
|
||||
#ifndef FINIT_NOLOGIN_PATH
|
||||
#define FINIT_NOLOGIN_PATH _PATH_NOLOGIN /* Stop user logging in. */
|
||||
@@ -90,7 +107,7 @@ static void sm_check_bootstrap(void *work)
|
||||
} else
|
||||
dbg("Change to default runlevel(%d), starting all services ...", cfglevel);
|
||||
|
||||
service_runlevel(level);
|
||||
sm_runlevel(level);
|
||||
|
||||
/* Clean up bootstrap-only tasks/services that never started */
|
||||
dbg("Clean up all bootstrap-only tasks/services ...");
|
||||
@@ -135,7 +152,7 @@ static char *sm_status(sm_state_t state)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static char sm_runlevel(int lvl)
|
||||
static char sm_rl2ch(int lvl)
|
||||
{
|
||||
if (lvl == INIT_LEVEL)
|
||||
return 'S';
|
||||
@@ -158,60 +175,39 @@ static void nologin(void)
|
||||
erase(FINIT_NOLOGIN_PATH);
|
||||
}
|
||||
|
||||
void sm_init(sm_t *sm)
|
||||
void sm_init(void)
|
||||
{
|
||||
static struct wq work = {
|
||||
.cb = sm_check_bootstrap,
|
||||
.delay = 1000
|
||||
};
|
||||
|
||||
sm->state = SM_BOOTSTRAP_STATE;
|
||||
sm->newlevel = -1;
|
||||
sm->reload = 0;
|
||||
sm->in_teardown = 0;
|
||||
sm.state = SM_BOOTSTRAP_STATE;
|
||||
sm.newlevel = -1;
|
||||
sm.reload = 0;
|
||||
sm.in_reload = 0;
|
||||
|
||||
dbg("Starting bootstrap finalize timer ...");
|
||||
schedule_work(&work);
|
||||
}
|
||||
|
||||
void sm_set_runlevel(sm_t *sm, int newlevel)
|
||||
{
|
||||
sm->newlevel = newlevel;
|
||||
|
||||
dbg("Flushing pending .conf file events ...");
|
||||
conf_flush_events();
|
||||
}
|
||||
|
||||
void sm_set_reload(sm_t *sm)
|
||||
{
|
||||
sm->reload = 1;
|
||||
|
||||
dbg("Flushing pending .conf file events ...");
|
||||
conf_flush_events();
|
||||
}
|
||||
|
||||
int sm_is_in_teardown(sm_t *sm)
|
||||
{
|
||||
return sm->in_teardown;
|
||||
}
|
||||
|
||||
void sm_step(sm_t *sm)
|
||||
void sm_step(void)
|
||||
{
|
||||
sm_state_t old_state;
|
||||
svc_t *svc;
|
||||
|
||||
restart:
|
||||
old_state = sm->state;
|
||||
old_state = sm.state;
|
||||
|
||||
dbg("state: %s, runlevel: %c, newlevel: %d, teardown: %d, reload: %d",
|
||||
sm_status(sm->state), sm_runlevel(runlevel), sm->newlevel, sm->in_teardown, sm->reload);
|
||||
sm_status(sm.state), sm_rl2ch(runlevel), sm.newlevel, sm.in_reload, sm.reload);
|
||||
|
||||
switch (sm->state) {
|
||||
switch (sm.state) {
|
||||
case SM_BOOTSTRAP_STATE:
|
||||
dbg("Bootstrapping all services in runlevel S from %s", finit_conf);
|
||||
service_step_all(SVC_TYPE_RUNTASK | SVC_TYPE_SERVICE | SVC_TYPE_SYSV);
|
||||
|
||||
sm->state = SM_BOOTSTRAP_WAIT_STATE;
|
||||
sm.state = SM_BOOTSTRAP_WAIT_STATE;
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -232,7 +228,7 @@ restart:
|
||||
/* Allow runparts to start */
|
||||
cond_set_oneshot("int/bootstrap");
|
||||
|
||||
if (sm->newlevel == -1)
|
||||
if (sm.newlevel == -1)
|
||||
break;
|
||||
|
||||
/* Hooks that should run at the very end */
|
||||
@@ -246,7 +242,7 @@ restart:
|
||||
/* System bootstrapped, launch TTYs et al */
|
||||
bootstrap = 0;
|
||||
service_step_all(SVC_TYPE_RESPAWN);
|
||||
sm->state = SM_RUNNING_STATE;
|
||||
sm.state = SM_RUNNING_STATE;
|
||||
break;
|
||||
|
||||
case SM_RUNNING_STATE:
|
||||
@@ -254,26 +250,26 @@ restart:
|
||||
service_step_all(SVC_TYPE_ANY);
|
||||
|
||||
/* runlevel changed? */
|
||||
if (sm->newlevel >= 0 && sm->newlevel <= 9) {
|
||||
if (runlevel == sm->newlevel) {
|
||||
sm->newlevel = -1;
|
||||
if (sm.newlevel >= 0 && sm.newlevel <= 9) {
|
||||
if (runlevel == sm.newlevel) {
|
||||
sm.newlevel = -1;
|
||||
break;
|
||||
}
|
||||
sm->state = SM_RUNLEVEL_CHANGE_STATE;
|
||||
sm.state = SM_RUNLEVEL_CHANGE_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* reload ? */
|
||||
if (sm->reload) {
|
||||
sm->reload = 0;
|
||||
sm->state = SM_RELOAD_CHANGE_STATE;
|
||||
if (sm.reload) {
|
||||
sm.reload = 0;
|
||||
sm.state = SM_RELOAD_CHANGE_STATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SM_RUNLEVEL_CHANGE_STATE:
|
||||
prevlevel = runlevel;
|
||||
runlevel = sm->newlevel;
|
||||
sm->newlevel = -1;
|
||||
runlevel = sm.newlevel;
|
||||
sm.newlevel = -1;
|
||||
|
||||
/* Restore terse mode and run hooks before shutdown */
|
||||
if (runlevel == 0 || runlevel == 6) {
|
||||
@@ -282,11 +278,11 @@ restart:
|
||||
plugin_run_hooks(HOOK_SHUTDOWN);
|
||||
}
|
||||
|
||||
dbg("Setting new runlevel --> %c <-- previous %c", sm_runlevel(runlevel), sm_runlevel(prevlevel));
|
||||
dbg("Setting new runlevel --> %c <-- previous %c", sm_rl2ch(runlevel), sm_rl2ch(prevlevel));
|
||||
if (osheading)
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "%s, entering runlevel %c", osheading, sm_runlevel(runlevel));
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "%s, entering runlevel %c", osheading, sm_rl2ch(runlevel));
|
||||
else
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "Entering runlevel %c", sm_runlevel(runlevel));
|
||||
logit(LOG_CONSOLE | LOG_NOTICE, "Entering runlevel %c", sm_rl2ch(runlevel));
|
||||
runlevel_set(prevlevel, runlevel);
|
||||
|
||||
/* Disable login in single-user mode as well as shutdown/reboot */
|
||||
@@ -302,10 +298,10 @@ restart:
|
||||
service_runtask_clean();
|
||||
|
||||
dbg("Stopping services not allowed in new runlevel ...");
|
||||
sm->in_teardown = 1;
|
||||
sm.in_reload = 1;
|
||||
service_step_all(SVC_TYPE_ANY);
|
||||
|
||||
sm->state = SM_RUNLEVEL_WAIT_STATE;
|
||||
sm.state = SM_RUNLEVEL_WAIT_STATE;
|
||||
break;
|
||||
|
||||
case SM_RUNLEVEL_WAIT_STATE:
|
||||
@@ -324,10 +320,10 @@ restart:
|
||||
plugin_run_hooks(HOOK_RUNLEVEL_CHANGE); /* Reconfigure HW/VLANs/etc here */
|
||||
|
||||
dbg("Starting services new to this runlevel ...");
|
||||
sm->in_teardown = 0;
|
||||
sm.in_reload = 0;
|
||||
service_step_all(SVC_TYPE_ANY);
|
||||
|
||||
sm->state = SM_RUNLEVEL_CLEAN_STATE;
|
||||
sm.state = SM_RUNLEVEL_CLEAN_STATE;
|
||||
break;
|
||||
|
||||
case SM_RUNLEVEL_CLEAN_STATE:
|
||||
@@ -361,7 +357,7 @@ restart:
|
||||
if (runlevel == 0 || runlevel == 6)
|
||||
do_shutdown(halt);
|
||||
|
||||
sm->state = SM_RUNNING_STATE;
|
||||
sm.state = SM_RUNNING_STATE;
|
||||
break;
|
||||
|
||||
case SM_RELOAD_CHANGE_STATE:
|
||||
@@ -373,11 +369,11 @@ restart:
|
||||
* let all affected services move to WAITING/HALTED
|
||||
*/
|
||||
dbg("Stopping services not allowed after reconf ...");
|
||||
sm->in_teardown = 1;
|
||||
sm.in_reload = 1;
|
||||
cond_reload();
|
||||
service_step_all(SVC_TYPE_ANY);
|
||||
|
||||
sm->state = SM_RELOAD_WAIT_STATE;
|
||||
sm.state = SM_RELOAD_WAIT_STATE;
|
||||
break;
|
||||
|
||||
case SM_RELOAD_WAIT_STATE:
|
||||
@@ -391,12 +387,12 @@ restart:
|
||||
break;
|
||||
}
|
||||
|
||||
sm->in_teardown = 0;
|
||||
sm.in_reload = 0;
|
||||
|
||||
dbg("Starting services after reconf ...");
|
||||
service_step_all(SVC_TYPE_ANY);
|
||||
|
||||
sm->state = SM_RELOAD_CLEAN_STATE;
|
||||
sm.state = SM_RELOAD_CLEAN_STATE;
|
||||
break;
|
||||
|
||||
case SM_RELOAD_CLEAN_STATE:
|
||||
@@ -422,14 +418,66 @@ restart:
|
||||
service_notify_reconf();
|
||||
|
||||
dbg("Reconfiguration done");
|
||||
sm->state = SM_RUNNING_STATE;
|
||||
sm.state = SM_RUNNING_STATE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sm->state != old_state)
|
||||
if (sm.state != old_state)
|
||||
goto restart;
|
||||
}
|
||||
|
||||
/**
|
||||
* sm_in_reload - System currently in reload or runlevel change?
|
||||
*
|
||||
* Returns:
|
||||
* %TRUE(1) or %FALSE(0)
|
||||
*/
|
||||
int sm_in_reload(void)
|
||||
{
|
||||
return sm.in_reload;
|
||||
}
|
||||
|
||||
/**
|
||||
* sm_reload - Called on SIGHUP, 'init q' or 'initctl reload'
|
||||
*
|
||||
* This function is called when Finit has received SIGHUP to reload
|
||||
* .conf files in /etc/finit.d. It is responsible for starting,
|
||||
* stopping and reloading (forwarding SIGHUP) to processes affected.
|
||||
*/
|
||||
void sm_reload(void)
|
||||
{
|
||||
sm.reload = 1;
|
||||
|
||||
dbg("Flushing pending .conf file events ...");
|
||||
conf_flush_events();
|
||||
|
||||
sm_step();
|
||||
}
|
||||
|
||||
/**
|
||||
* sm_runlevel - Change to a new runlevel
|
||||
* @newlevel: New runlevel to activate
|
||||
*
|
||||
* Stops all services not in @newlevel and starts, or lets continue to run,
|
||||
* those in @newlevel. Also updates @prevlevel and active @runlevel.
|
||||
*/
|
||||
void sm_runlevel(int newlevel)
|
||||
{
|
||||
if (!rescue && (runlevel == 1 || runlevel == INIT_LEVEL) && !IS_RESERVED_RUNLEVEL(newlevel))
|
||||
networking(1);
|
||||
|
||||
sm.newlevel = newlevel;
|
||||
|
||||
dbg("Flushing pending .conf file events ...");
|
||||
conf_flush_events();
|
||||
|
||||
sm_step();
|
||||
|
||||
if (!rescue && IS_RESERVED_RUNLEVEL(runlevel))
|
||||
networking(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* indent-tabs-mode: t
|
||||
|
||||
@@ -24,32 +24,12 @@
|
||||
#ifndef FINIT_SM_H_
|
||||
#define FINIT_SM_H_
|
||||
|
||||
typedef enum {
|
||||
SM_BOOTSTRAP_STATE = 0, /* Init state, bootstrap services */
|
||||
SM_BOOTSTRAP_WAIT_STATE, /* Waiting for bootstrap to complete */
|
||||
SM_RUNNING_STATE, /* Normal state, services running */
|
||||
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occurred */
|
||||
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped processes to halt */
|
||||
SM_RUNLEVEL_CLEAN_STATE, /* Wait for post:scripts and cleanup:scripts */
|
||||
SM_RELOAD_CHANGE_STATE, /* A reload event has occurred */
|
||||
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped processes to halt */
|
||||
SM_RELOAD_CLEAN_STATE, /* Wait for post:scripts and cleanup:scripts */
|
||||
} sm_state_t;
|
||||
void sm_init (void);
|
||||
void sm_step (void);
|
||||
|
||||
typedef struct sm {
|
||||
sm_state_t state; /* Running, Changed, Waiting, ... */
|
||||
int newlevel; /* Set on runlevel change to new runlevel, -1 if not change */
|
||||
int reload; /* Set on reload event, else 0 */
|
||||
int in_teardown; /* Set when waiting for all processes to be halted */
|
||||
} sm_t;
|
||||
|
||||
extern sm_t sm;
|
||||
|
||||
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);
|
||||
int sm_is_in_teardown(sm_t *sm);
|
||||
int sm_in_reload (void);
|
||||
void sm_reload (void);
|
||||
void sm_runlevel (int newlevel);
|
||||
|
||||
#endif /* FINIT_SM_H_ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user