diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-02-13 23:55:47 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-02-14 00:05:33 +0200 |
commit | 0a5eb4f65a20d37f2051dce8816485dd219fb735 (patch) | |
tree | eadff6490ebf734431c354ac1ba40a4a8537fcb0 | |
parent | c9581808b72ff25623c87cf49c471ce7f017985d (diff) | |
download | pies-0a5eb4f65a20d37f2051dce8816485dd219fb735.tar.gz pies-0a5eb4f65a20d37f2051dce8816485dd219fb735.tar.bz2 |
Fix handling of wait components
* src/pies.h (PIES_COMP_WAIT): Remove.
(PIES_COMP_MASK): Save one bit.
(PIES_CHLD_NONE, PIES_CHLD_CLEANUP)
(PIES_CHLD_WAKEUP): New constants.
(pies_schedule_children): New proto.
(sysvinit_runlevel_setup): Change signature.
* src/pies.c (children_cleanup, got_alarm): Merge into
single static variable children_op. All uses updated.
(pies_schedule_children): New function.
(sig_handler): Update
(main): Don't call ctl_open for init process. It is done
by inittrans after transition from boot to normal state.
Update to use pies_schedule_children.
* src/prog.h (IS_ACTIVE_COMPONENT): New macro.
* src/progman.c (prog_start): Don't modify prog->v.p.wait.
(progman_wake_sleeping): Start usual components only after
all "wait" components have terminated.
(progman_cleanup): If a "wait" component has terminated,
request PIES_CHLD_WAKEUP.
* src/sysvinit.c (enstate) <wait>: Remove.
(enablecomp): Update.
(runlevel_setup_prog): Set prog->v.p.wait.
(sysvinit_runlevel_setup): Take only one parameter.
(inittrans): Remove "wait" and the related mess.
Call ctl_open after transition boot -> normal.
-rw-r--r-- | src/pies.c | 54 | ||||
-rw-r--r-- | src/pies.h | 11 | ||||
-rw-r--r-- | src/prog.h | 2 | ||||
-rw-r--r-- | src/progman.c | 20 | ||||
-rw-r--r-- | src/sysvinit.c | 59 |
5 files changed, 67 insertions, 79 deletions
@@ -1533,44 +1533,49 @@ pies_reload (void) { int rc = pies_read_config (); if (rc == 0) { component_config_commit (); if (init_process) - sysvinit_runlevel_setup (PIES_COMP_DEFAULT, NULL); + sysvinit_runlevel_setup (PIES_COMP_DEFAULT); progman_create_sockets (); progman_start (); } return rc; } static struct config_syntax *current_syntax = &config_syntax_tab[CONF_PIES]; #include "cmdline.h" -int action = ACTION_CONT; -int children_cleanup = 0; -int got_alarm = 0; +static int action = ACTION_CONT; +static int children_op = PIES_CHLD_NONE; void pies_schedule_action (int act) { action = act; } +void +pies_schedule_children (int op) +{ + children_op |= op; +} + RETSIGTYPE sig_handler (int sig) { if (init_process && sysvinit_sigtrans (sig, &action)) return; switch (sig) { case SIGCHLD: - children_cleanup = 1; + pies_schedule_children (PIES_CHLD_CLEANUP); break; case SIGINT: case SIGTERM: case SIGQUIT: logmsg (LOG_NOTICE, "received signal %d", sig); @@ -1585,13 +1590,13 @@ sig_handler (int sig) case SIGUSR1: logmsg (LOG_NOTICE, "received signal %d", sig); action = ACTION_RESTART; break; case SIGALRM: - got_alarm = 1; + pies_schedule_children (PIES_CHLD_WAKEUP); break; } } void setsigvhan (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc) @@ -2147,15 +2152,13 @@ main (int argc, char **argv) logmsg (LOG_ERR, _("cannot become a daemon: %s"), strerror (errno)); exit (EX_SOFTWARE); } diag_setup (DIAG_TO_SYSLOG); } - if (init_process) - ctl_open (); - else + if (!init_process) { if (ctl_open ()) exit (EX_UNAVAILABLE); create_pidfile (pidfile); } @@ -2170,16 +2173,16 @@ main (int argc, char **argv) progman_start (); do { if (init_process && inittrans ()) { - got_alarm = 1; + pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; } - else if (!children_cleanup) + else if (children_op == PIES_CHLD_NONE) pies_pause (); switch (action) { case ACTION_RESTART: if (argv[0][0] != '/' || init_process) { @@ -2187,13 +2190,13 @@ main (int argc, char **argv) action = ACTION_CONT; } break; case ACTION_RELOAD: pies_reload (); - got_alarm = 1; + pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; case ACTION_STOP: if (init_process) { @@ -2201,44 +2204,37 @@ main (int argc, char **argv) action = ACTION_CONT; } break; case ACTION_CTRLALTDEL: debug (1, ("ctrl-alt-del")); - sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_ctrlaltdel), - NULL); - got_alarm = 1; + sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_ctrlaltdel)); + pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; case ACTION_KBREQUEST: debug (1, ("kbrequest")); - sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_kbrequest), - NULL); - got_alarm = 1; + sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_kbrequest)); + pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; case ACTION_POWER: debug (1, ("SIGPWR")); sysvinit_power (); - got_alarm = 1; + pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; } if (action == ACTION_CONT) { - if (children_cleanup) - { - children_cleanup = 0; - progman_cleanup (0); - } - if (got_alarm) - { - progman_wake_sleeping (1); - got_alarm = 0; - } + if (children_op & PIES_CHLD_CLEANUP) + progman_cleanup (0); + if (children_op & PIES_CHLD_WAKEUP) + progman_wake_sleeping (1); + children_op = PIES_CHLD_NONE; } } while (init_process || action == ACTION_CONT); progman_stop (); remove_pidfile (pidfile); @@ -177,14 +177,13 @@ enum pies_comp_mode /* Restart the component wherever it terminates */ pies_comp_respawn = pies_comp_exec, }; #define PIES_COMP_DEFAULT 0 -#define PIES_COMP_WAIT 0x01 -#define PIES_COMP_MASK(m) (1 << ((m)+1)) +#define PIES_COMP_MASK(m) (1 << ((m))) #define CF_DISABLED 0x001 /* The componenet is disabled */ #define CF_PRECIOUS 0x002 /* The component is precious (should not be disabled) */ #define CF_WAIT 0x004 /* Wait for the component instance to terminate. */ @@ -314,12 +313,18 @@ void config_file_add_type (enum config_syntax_type syntax, const char *name); void free_redirector (struct redirector *rp); void pies_schedule_action (int act); void free_action (struct action *act); +#define PIES_CHLD_NONE 0 +#define PIES_CHLD_CLEANUP 0x01 +#define PIES_CHLD_WAKEUP 0x02 + +void pies_schedule_children (int op); + void register_prog (struct component *comp); int progman_waiting_p (void); void progman_start (void); void progman_wake_sleeping (int); void progman_stop (void); void progman_cleanup (int expect_term); @@ -509,13 +514,13 @@ int inittrans (void); int is_comp_wait (struct component *comp); int is_valid_runlevel (int c); int console_open (int mode); int telinit (const char *arg); int inittab_parse (const char *file); int sysvinit_sigtrans (int sig, int *pact); -void sysvinit_runlevel_setup (int mask, int *wait); +void sysvinit_runlevel_setup (int mask); void sysvinit_sysdep_begin (void); void sysvinit_power (void); void sysvinit_report (struct json_value *obj); int sysvinit_set_runlevel (int newlevel); @@ -78,12 +78,14 @@ struct prog char *command; } c; } v; }; #define IS_COMPONENT(p) ((p)->type == TYPE_COMPONENT) +#define IS_ACTIVE_COMPONENT(prog) \ + (IS_COMPONENT(prog) && !((prog)->v.p.comp->flags & CF_DISABLED)) struct prog *progman_locate (const char *name); int progman_foreach (int (*filter) (struct prog *, void *data), void *data); void prog_stop (struct prog *prog, int sig); void progman_stop_component (struct prog **prog); diff --git a/src/progman.c b/src/progman.c index 29b5331..8a5187c 100644 --- a/src/progman.c +++ b/src/progman.c @@ -1047,13 +1047,12 @@ prog_start (struct prog *prog) prog_tag (prog)); prog->v.p.status = status_stopped; prog->v.p.comp->flags |= CF_DISABLED; } return; } - prog->v.p.wait = is_comp_wait (prog->v.p.comp); } /* This call returns 1 in two cases: Either prog is marked as disabled, in which case there's nothing more to do, or one or more of its prerequisites are in status_stopping. In the latter case either the components in question will exit or a SIGALRM will get delivered. In @@ -1538,20 +1537,26 @@ check_stopping (struct prog *prog, time_t now) void progman_wake_sleeping (int onalrm) { struct prog *prog; time_t now = time (NULL); - if (progman_waiting_p ()) - /* Noting to do if there are processes left in the previous runlevel */ - return; + debug (1, (_("checking for components to start"))); - debug (1, (_("managing sleeping/stopping components"))); + for (prog = proghead; prog; prog = prog->next) + { + if (IS_ACTIVE_COMPONENT (prog) && prog->v.p.wait) + { + if (prog->v.p.status != status_running) + prog_start (prog); + return; + } + } for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog)) + if (IS_ACTIVE_COMPONENT (prog)) { switch (prog->v.p.status) { case status_sleeping: if (now - prog->v.p.timestamp >= SLEEPTIME) { @@ -2253,13 +2258,12 @@ react (struct prog *prog, int status, pid_t pid) if (!list && prog->v.p.comp->mode != pies_comp_inetd) /* Default action: */ prog_start (prog); } - void progman_cleanup (int expect_term) { pid_t pid; int status; @@ -2313,12 +2317,14 @@ progman_cleanup (int expect_term) if (prog->v.p.comp->mode >= pies_mark_sysvinit && prog->v.p.comp->mode != pies_comp_ondemand) { sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog), pid, ""); prog->v.p.status = status_finished; + if (prog->v.p.wait) + pies_schedule_children (PIES_CHLD_WAKEUP); prog->v.p.wait = 0; } else { if (is_sysvinit (prog->v.p.comp)) sysvinit_acct (SYSV_ACCT_PROC_STOP, "", diff --git a/src/sysvinit.c b/src/sysvinit.c index c9447ff..2d0671c 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -209,13 +209,12 @@ runlevel_index (int n) return p - valid_runlevels; } struct enstate { int mask; - int wait; }; static int enablecomp (struct prog *prog, void *data) { struct enstate *s = data; @@ -246,33 +245,27 @@ enablecomp (struct prog *prog, void *data) case pies_comp_powerwait: case pies_comp_powerokwait: case pies_comp_ctrlaltdel: case pies_comp_powerfailnow: case pies_comp_kbrequest: return s && (s->mask & PIES_COMP_MASK (comp->mode)); + default: break; } } + if (!comp->runlevels) + return -1; + if (!strchr (comp->runlevels, runlevel)) return 0; if (prog->v.p.status == status_finished) return -1; - if (s && s->mask & PIES_COMP_WAIT) - { - if (comp->mode == pies_comp_wait) - { - s->wait = 1; - return 1; - } - return 0; - } - return 1; } static int runlevel_setup_prog (struct prog *prog, void *data) { @@ -282,32 +275,28 @@ runlevel_setup_prog (struct prog *prog, void *data) if (rc < 0) return 0; if (rc) prog->v.p.comp->flags &= ~CF_DISABLED; else prog->v.p.comp->flags |= CF_DISABLED; - debug (2, ("%s: %s", prog_tag (prog), + prog->v.p.wait = is_comp_wait (prog->v.p.comp); + debug (2, ("%s: %s%s", prog_tag (prog), prog->v.p.comp->flags & CF_DISABLED ? - "disabled" : "enabled")); + "disabled" : "enabled", + !(prog->v.p.comp->flags & CF_DISABLED) && prog->v.p.wait + ? " (wait)" : "")); } return 0; } void -sysvinit_runlevel_setup (int mask, int *wait) +sysvinit_runlevel_setup (int mask) { struct enstate s; s.mask = mask; - if (wait) - { - s.mask |= PIES_COMP_WAIT; - s.wait = *wait; - } progman_foreach (runlevel_setup_prog, &s); - if (wait) - *wait = s.wait; } static int demand_prog (struct prog *prog, void *data) { int *rl = data; @@ -703,13 +692,13 @@ sysvinit_begin () close (1); close (2); set_console_dev (); console_stty (); setsid (); envsetup (); - sysvinit_runlevel_setup (PIES_COMP_DEFAULT, NULL); + sysvinit_runlevel_setup (PIES_COMP_DEFAULT); add_extra_sigv (sigv, ARRAY_SIZE (sigv)); sysvinit_sysdep_begin (); } #define IS_RUNNING_DISABLED_PROG(prog) \ (IS_COMPONENT (prog) \ @@ -740,13 +729,12 @@ int inittrans () { int n; int newlevel = 0; enum boot_state newstate; int trans = 0; - static int wait = 0; if (progman_waiting_p ()) /* Noting to do if there are processes left in the previous runlevel */ return 0; if (runlevel == 0) @@ -760,13 +748,12 @@ inittrans () if (newstate != boot_state) { debug (1, ("STATE TRANS: %s -> %s", boot_state_name[boot_state], boot_state_name[newstate])); boot_state = newstate; trans = 1; - wait = 0; } switch (boot_state) { case sysinit: break; @@ -776,53 +763,45 @@ inittrans () case single: newlevel = 'S'; break; case normal: newlevel = dfl_level ? dfl_level : getinitdefault (); if (trans) - /* boot -> normal */ - create_fifo (); + { + /* boot -> normal */ + create_fifo (); + ctl_open (); + } } if (newlevel && newlevel != runlevel) { prevlevel = runlevel ? runlevel : 'N'; debug (1, ("RL TRANS: %c -> %c", prevlevel, newlevel)); sysvinit_acct (SYSV_ACCT_RUNLEVEL, "runlevel", "~~", newlevel + 256 * runlevel, "~"); mf_proctitle_format ("init [%c]", newlevel); runlevel = newlevel; trans = 1; - wait = 0; } - if (wait) - trans = 1; + if (trans) { int sig; envsetup (); - if (wait == 0) - { - sysvinit_runlevel_setup (PIES_COMP_DEFAULT, &wait); - if (wait) - return 1; - } - sysvinit_runlevel_setup (PIES_COMP_DEFAULT, NULL); + sysvinit_runlevel_setup (PIES_COMP_DEFAULT); /* Stop disabled programs */ sig = SIGTERM; progman_foreach (terminate_disabled, &sig); if (progman_wait_until (running_disabled, NULL)) { sig = SIGKILL; progman_foreach (terminate_disabled, &sig); progman_wait_until (running_disabled, NULL); } - - /* Clear the wait flag */ - wait = 0; } return trans; } /* Return true if the progman should wait for the component to terminate. */ @@ -1144,13 +1123,13 @@ powerfailcmd (int power_stat) default: /* Power failure */ mask = PIES_COMP_MASK (pies_comp_powerfail) | PIES_COMP_MASK (pies_comp_powerwait); } - sysvinit_runlevel_setup (mask, NULL); + sysvinit_runlevel_setup (mask); } void sysvinit_report (struct json_value *obj) { json_object_set_string (obj, "runlevel", "%c", runlevel); |