aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-01-04 15:33:00 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-01-04 22:11:21 +0200
commitd8221ce9bdd2d7ae6162bed0e1c85e9f7a3ff8f2 (patch)
tree5fab301e38fede054aa85708c6c8590c1825e541
parent95bc9b24928eb9951f0644307e417df0bc8c53b4 (diff)
downloadpies-d8221ce9bdd2d7ae6162bed0e1c85e9f7a3ff8f2.tar.gz
pies-d8221ce9bdd2d7ae6162bed0e1c85e9f7a3ff8f2.tar.bz2
Fix sysvinit transition logic.
* src/pies.c (main): Call sysvinit_begin to initialize sysvinit subsystem. In the main loop, force wakeup if inittrans returns 1. * src/pies.h (is_sysvinit): Rewrite macro. (progman_sysvinit_enable): New proto. (inittrans): Change return type. * src/progman.c (progman_sysvinit_enable): New function. (progman_running_p): Additional debugging. (prog_start): Special handling for sysvinit components. Remove calls to runlevel_match * src/sysvinit.c (runlevel_match): Remove function. (sysvinit_begin): New function. (inittrans): Return boolean value indicating whether a transition has been made. Call progman_sysvinit_enable to change the status of sysvinit components as appropriate.
-rw-r--r--src/pies.c12
-rw-r--r--src/pies.h11
-rw-r--r--src/progman.c55
-rw-r--r--src/sysvinit.c124
4 files changed, 142 insertions, 60 deletions
diff --git a/src/pies.c b/src/pies.c
index 713ae8e..a2dc5e0 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -959,7 +959,7 @@ _cb_flags (enum grecs_callback_command cmd,
return 0;
}
-static const char valid_runlevels[] = "0123456Ss";
+static const char valid_runlevels[] = "0123456789Ss";
static int
_cb_initdefault (enum grecs_callback_command cmd,
@@ -2309,6 +2309,7 @@ main (int argc, char **argv)
{
foreground = 1;
set_console_dev ();
+ sysvinit_begin ();
}
else
switch (pies_check_status (&pid))
@@ -2360,9 +2361,12 @@ main (int argc, char **argv)
do
{
- if (init_process)
- inittrans ();
- if (!children_cleanup)
+ if (init_process && inittrans ())
+ {
+ got_alarm = 1;
+ action = ACTION_CONT;
+ }
+ else if (!children_cleanup)
pies_pause ();
switch (action)
{
diff --git a/src/pies.h b/src/pies.h
index a679afd..fc4f59c 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -183,8 +183,6 @@ enum pies_comp_mode
pies_comp_respawn = pies_comp_exec,
};
-#define is_sysvinit(m) ((m)>=pies_mark_sysvinit)
-
#define CF_DISABLED 0x001 /* The componenet is disabled */
#define CF_PRECIOUS 0x002 /* The component is precious (should not
be disabled) */
@@ -253,6 +251,8 @@ struct component
struct action act_temp; /* Auxiliary object used during configuration */
};
+#define is_sysvinit(cp) ((cp)->mode >= pies_mark_sysvinit || (cp)->runlevels)
+
union pies_sockaddr_storage
{
struct sockaddr s;
@@ -301,6 +301,9 @@ void progman_run_comp (struct component *comp, int fd,
void progman_iterate_comp (int (*fun) (struct component *, void *),
void *data);
+void progman_sysvinit_enable (int (*fun) (struct component *, int, void *),
+ void *data);
+
void fd_report (int fd, const char *msg);
int check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen);
@@ -450,8 +453,8 @@ struct inetd_builtin
struct inetd_builtin *inetd_builtin_lookup (const char *service, int socktype);
/* sysvinit.c */
-int runlevel_match (struct component *comp);
-void inittrans (void);
+void sysvinit_begin (void);
+int inittrans (void);
int is_comp_wait (struct component *comp);
diff --git a/src/progman.c b/src/progman.c
index f0d0de6..15b8c44 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -106,6 +106,29 @@ progman_iterate_comp (int (*fun) (struct component *, void *), void *data)
break;
}
+void
+progman_sysvinit_enable (int (*fun) (struct component *, int, void *),
+ void *data)
+{
+ struct prog *prog;
+
+ for (prog = proghead; prog; prog = prog->next)
+ if (IS_COMPONENT (prog) && is_sysvinit (prog->v.p.comp))
+ {
+ int rc = fun (prog->v.p.comp, prog->v.p.status == status_finished,
+ data);
+ if (rc < 0)
+ continue;
+ if (rc)
+ prog->v.p.status = status_enabled;
+ else
+ prog->v.p.status = status_disabled;
+ debug (1, ("%s: %s", prog->tag,
+ prog->v.p.status == status_enabled ?
+ "enabled" : "disabled"));
+ }
+}
+
static struct prog *
prog_lookup_by_pid (pid_t pid)
{
@@ -412,7 +435,10 @@ progman_running_p ()
{
if (IS_COMPONENT (prog) && is_comp_wait (prog->v.p.comp) &&
prog->pid > 0)
- return 1;
+ {
+ debug (1, ("COMP %s still running", prog->tag));
+ return 1;
+ }
}
return 0;
}
@@ -1185,14 +1211,21 @@ prog_start (struct prog *prog)
if (prog->pid > 0 || !IS_COMPONENT (prog))
return;
- if (is_sysvinit (prog->v.p.comp->mode) && !init_process &&
- prog->v.p.status != status_disabled)
+ if (is_sysvinit (prog->v.p.comp))
{
- logmsg (LOG_NOTICE, "disabling sysvinit component %s", prog->tag);
- prog->v.p.status = status_disabled;
- return;
+ if (!init_process)
+ {
+ if (prog->v.p.status != status_disabled)
+ {
+ logmsg (LOG_NOTICE, "disabling sysvinit component %s",
+ prog->tag);
+ prog->v.p.status = status_disabled;
+ }
+ return;
+ }
+ debug (1, ("ok to start %s", prog->v.p.comp->tag));
}
-
+
/* 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
@@ -1782,8 +1815,7 @@ progman_start ()
{
if (prog->v.p.comp->mode == pies_comp_inetd)
{
- if ((prog->v.p.comp->flags & CF_DISABLED)
- || !runlevel_match (prog->v.p.comp))
+ if (prog->v.p.comp->flags & CF_DISABLED)
disable_socket (prog->v.p.socket);
else
{
@@ -1791,8 +1823,7 @@ progman_start ()
enable_socket (prog->v.p.socket);
}
}
- else if ((prog->v.p.status == status_enabled && prog->pid == 0
- && runlevel_match (prog->v.p.comp))
+ else if ((prog->v.p.status == status_enabled && prog->pid == 0)
|| prog->v.p.status == status_sleeping)
prog_start (prog);
}
@@ -2459,7 +2490,7 @@ progman_cleanup (int expect_term)
if (listener->v.p.comp->flags & CF_WAIT)
enable_socket (listener->v.p.socket);
}
- else if (is_sysvinit(prog->v.p.comp->mode))
+ else if (prog->v.p.comp->mode >= pies_mark_sysvinit)
{
prog->v.p.status = status_finished;
}
diff --git a/src/sysvinit.c b/src/sysvinit.c
index e09802f..5a0d98a 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -54,7 +54,7 @@ static int boot_trans_tab[max_boot_state][sizeof(valid_runlevels)-1] = {
};
enum boot_state boot_state;
-int runlevel;
+int runlevel = 0;
int initdefault; /* Default runlevel */
int dfl_level;
@@ -62,75 +62,104 @@ int dfl_level;
static int
runlevel_index (int n)
{
- char *p = strchr (valid_runlevels, n);
+ char *p;
+
+ if (n == 0)
+ return -1;
+
+ p = strchr (valid_runlevels, n);
if (!p)
return -1;
return p - valid_runlevels;
}
-int
-runlevel_match (struct component *comp)
+static int
+enablecomp (struct component *comp, int finished, void *data)
{
- if (init_process)
+ int *wait = data;
+ int rc;
+
+ switch (boot_state)
{
- switch (boot_state)
- {
- case sysinit:
- return comp->mode == pies_comp_sysinit;
-
- case boot:
- return comp->mode == pies_comp_boot ||
- comp->mode == pies_comp_bootwait;
+ case sysinit:
+ return comp->mode == pies_comp_sysinit;
- case single0:
- case single1:
- case normal:
- switch (comp->mode)
- {
- case pies_comp_sysinit:
- case pies_comp_boot:
- case pies_comp_bootwait:
- return 0;
- case pies_comp_powerfail:
- case pies_comp_powerwait:
- case pies_comp_powerokwait:
- case pies_comp_ctrlaltdel:
- case pies_comp_ondemand:
- case pies_comp_powerfailnow:
- case pies_comp_kbrequest:
- /* FIXME */
- return 0;
- }
+ case boot:
+ return comp->mode == pies_comp_boot || comp->mode == pies_comp_bootwait;
- if (!comp->runlevels)
- return 1;
- return !!strchr (comp->runlevels, runlevel);
+ case single0:
+ case single1:
+ case normal:
+ switch (comp->mode)
+ {
+ case pies_comp_sysinit:
+ case pies_comp_boot:
+ case pies_comp_bootwait:
+ return 0;
+ case pies_comp_powerfail:
+ case pies_comp_powerwait:
+ case pies_comp_powerokwait:
+ case pies_comp_ctrlaltdel:
+ case pies_comp_ondemand:
+ case pies_comp_powerfailnow:
+ case pies_comp_kbrequest:
+ /* FIXME */
+ return 0;
}
}
- return 1;
+ rc = !!strchr (comp->runlevels, runlevel);
+ if (!rc)
+ return rc;
+ if (finished)
+ return -1;
+ if (wait)
+ {
+ if (comp->mode == pies_comp_wait)
+ {
+ *wait = 1;
+ return 1;
+ }
+ return 0;
+ }
+ return rc;
}
void
+sysvinit_begin ()
+{
+ progman_sysvinit_enable (enablecomp, NULL);
+}
+
+int
inittrans ()
{
int n;
int newlevel = 0;
enum boot_state newstate;
-
+ int trans = 0;
+ static int wait = 0;
+
if (progman_running_p ())
/* Noting to do if there are processes left in the previous runlevel */
- return;
+ return 0;
- n = runlevel_index (runlevel);
+ if (runlevel == 0)
+ n = runlevel_index (dfl_level ? dfl_level : initdefault);
+ else
+ n = runlevel_index (runlevel);
if (n == -1)
- n = 11; /* assume S */
+ n = runlevel_index ('S');
newstate = boot_trans_tab[boot_state][n];
+ debug (1, ("STATE TRANS: %s(%c,%d) -> %s", boot_state_name[boot_state],
+ runlevel,n,
+ boot_state_name[newstate]));
if (newstate != boot_state)
{
debug (1, ("STATE TRANS: %s -> %s", boot_state_name[boot_state],
boot_state_name[newstate]));
boot_state = newstate;
+ trans = 1;
}
switch (boot_state)
@@ -150,7 +179,22 @@ inittrans ()
{
debug (1, ("RL TRANS: %c -> %c", runlevel, newlevel));
runlevel = newlevel;
+ trans = 1;
+ wait = 0;
+ }
+ if (wait)
+ trans = 1;
+ if (trans)
+ {
+ if (wait == 0)
+ {
+ progman_sysvinit_enable (enablecomp, &wait);
+ if (wait)
+ return 1;
+ }
+ progman_sysvinit_enable (enablecomp, NULL);
}
+ return trans;
}
/* Return true if the progman should wait for the component to

Return to:

Send suggestions and report system problems to the System administrator.