aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-02-13 23:55:47 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-02-14 00:05:33 +0200
commit0a5eb4f65a20d37f2051dce8816485dd219fb735 (patch)
treeeadff6490ebf734431c354ac1ba40a4a8537fcb0
parentc9581808b72ff25623c87cf49c471ce7f017985d (diff)
downloadpies-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.c54
-rw-r--r--src/pies.h11
-rw-r--r--src/prog.h2
-rw-r--r--src/progman.c20
-rw-r--r--src/sysvinit.c59
5 files changed, 67 insertions, 79 deletions
diff --git a/src/pies.c b/src/pies.c
index 96e9281..3734b47 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -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);
diff --git a/src/pies.h b/src/pies.h
index 14ea7b7..bcce32a 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -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);
diff --git a/src/prog.h b/src/prog.h
index 1db2eee..4658518 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.