aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/pies.c22
-rw-r--r--src/pies.h13
-rw-r--r--src/progman.c58
-rw-r--r--src/sysvinit.c172
5 files changed, 226 insertions, 40 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 44e0a8d..0fca105 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,7 @@ pies_SOURCES = \
pies.c\
progman.c\
socket.c\
+ sysvinit.c\
url.c\
userprivs.c
diff --git a/src/pies.c b/src/pies.c
index ded1a10..142b7f9 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -39,8 +39,6 @@ enum pies_command {
};
enum pies_command command;
-int initdefault; /* Default runlevel */
-int dfl_level;
char *statedir = DEFAULT_STATE_DIR;
char *instance;
char *pidfile;
@@ -834,6 +832,17 @@ static struct tokendef modetab[] = {
{"nostartaccept", pies_comp_inetd},
{"pass-fd", pies_comp_pass_fd},
{"pass", pies_comp_pass_fd},
+ {"boot", pies_comp_boot},
+ {"bootwait", pies_comp_boot},
+ {"powerfail", pies_comp_powerfail},
+ {"powerwait", pies_comp_powerwait},
+ {"powerokwait", pies_comp_powerokwait},
+ {"ctrlaltdel", pies_comp_ctrlaltdel},
+ {"ondemand", pies_comp_ondemand},
+ {"sysinit", pies_comp_sysinit},
+ {"powerfailnow", pies_comp_powerfailnow},
+ {"kbrequest", pies_comp_kbrequest},
+
{NULL}
};
@@ -2132,15 +2141,6 @@ set_console_dev ()
console_device = "/dev/null";
}
-static void
-inittrans ()
-{
- if (progman_running_p ())
- /* Noting to do if there are processes left in the previous runlevel */
- return;
-
-}
-
int
main (int argc, char **argv)
{
diff --git a/src/pies.h b/src/pies.h
index 9b3ae9d..a679afd 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -145,10 +145,10 @@ enum pies_comp_mode
/*
** Init-style components
*/
-
+ pies_mark_sysvinit,
/* Start the process when the specified runlevel is entered and wait
for its termination */
- pies_comp_wait,
+ pies_comp_wait = pies_mark_sysvinit,
/* Execute the component once, when the specified runlevel is entered */
pies_comp_once,
/* Execute the component during system boot. Ignore runlevel settings. */
@@ -183,6 +183,8 @@ 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) */
@@ -274,6 +276,7 @@ extern char *qotdfile;
extern int init_process;
extern char *console_device;
extern int initdefault;
+extern int dfl_level;
void register_prog (struct component *comp);
int progman_running_p (void);
@@ -445,5 +448,11 @@ 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);
+int is_comp_wait (struct component *comp);
+
diff --git a/src/progman.c b/src/progman.c
index 639c22f..e25219a 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -409,8 +409,11 @@ progman_running_p ()
struct prog *prog;
for (prog = proghead; prog; prog = prog->next)
- if (prog->pid > 0)
- return 1;
+ {
+ if (IS_COMPONENT (prog) && is_comp_wait (prog->v.p.comp) &&
+ prog->pid > 0)
+ return 1;
+ }
return 0;
}
@@ -1181,6 +1184,14 @@ 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)
+ {
+ logmsg (LOG_NOTICE, "disabling sysvinit component %s", prog->tag);
+ prog->v.p.status = status_disabled;
+ return;
+ }
/* 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
@@ -1256,9 +1267,17 @@ prog_start (struct prog *prog)
prog_start_prologue (prog);
switch (prog->v.p.comp->mode)
{
- case pies_comp_pass_fd:
- case pies_comp_exec:
- case pies_comp_once:
+ case pies_comp_accept:
+ case pies_comp_inetd:
+ prog_sockenv (prog);
+
+ dup2 (prog->v.p.socket, 0);
+ dup2 (prog->v.p.socket, 1);
+ close (prog->v.p.socket);
+ prog->v.p.socket = -1;
+ break;
+
+ default:
if (init_process)
{
int fd = console_open (O_RDWR|O_NOCTTY);
@@ -1288,16 +1307,6 @@ prog_start (struct prog *prog)
}
}
break;
-
- case pies_comp_accept:
- case pies_comp_inetd:
- prog_sockenv (prog);
-
- dup2 (prog->v.p.socket, 0);
- dup2 (prog->v.p.socket, 1);
- close (prog->v.p.socket);
- prog->v.p.socket = -1;
- break;
}
if (!init_process)
@@ -1346,8 +1355,9 @@ prog_start (struct prog *prog)
{
disable_socket (prog->v.p.socket);
}
- else if (prog->v.p.comp->mode != pies_comp_exec &&
- prog->v.p.comp->mode != pies_comp_once)
+ else if (prog->v.p.comp->mode == pies_comp_accept ||
+ prog->v.p.comp->mode == pies_comp_inetd ||
+ prog->v.p.comp->mode == pies_comp_pass_fd)
close (prog->v.p.socket);
prog->pid = pid;
prog->v.p.status = status_enabled;
@@ -1760,14 +1770,6 @@ progman_recompute_alarm ()
-static int
-runlevel_match (struct prog *prog)
-{
- if (!initdefault || !prog->v.p.comp->runlevels)
- return 1;
- return !!strchr (prog->v.p.comp->runlevels, initdefault);
-}
-
void
progman_start ()
{
@@ -1781,7 +1783,7 @@ progman_start ()
if (prog->v.p.comp->mode == pies_comp_inetd)
{
if ((prog->v.p.comp->flags & CF_DISABLED)
- || !runlevel_match (prog))
+ || !runlevel_match (prog->v.p.comp))
disable_socket (prog->v.p.socket);
else
{
@@ -1790,7 +1792,7 @@ progman_start ()
}
}
else if ((prog->v.p.status == status_enabled && prog->pid == 0
- && runlevel_match (prog))
+ && runlevel_match (prog->v.p.comp))
|| prog->v.p.status == status_sleeping)
prog_start (prog);
}
@@ -1872,6 +1874,8 @@ prog_start_prerequisites (struct prog *prog)
int i;
int ret;
+ if (prog->v.p.status == status_disabled)
+ return 1;
if (!prog->prereq)
return 0; /* Ok to startup */
debug (1, ("starting prerequisites of %s", prog->tag));
diff --git a/src/sysvinit.c b/src/sysvinit.c
new file mode 100644
index 0000000..cfef974
--- /dev/null
+++ b/src/sysvinit.c
@@ -0,0 +1,172 @@
+/* This file is part of GNU Pies.
+ Copyright (C) 2013 Sergey Poznyakoff
+
+ GNU Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Pies is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "pies.h"
+
+enum boot_state
+ {
+ sysinit,
+ boot,
+ single0,
+ single1,
+ normal,
+ max_boot_state
+ };
+
+static char *boot_state_name[] = {
+ "sysinit",
+ "boot",
+ "single0",
+ "single1",
+ "normal"
+};
+
+static char boot_state_str[] = "#*sS ";
+
+static const char valid_runlevels[] = "0123456789S";
+
+static int boot_trans_tab[max_boot_state][sizeof(valid_runlevels)-1] = {
+ /* 0, 1, 2, 3, 4, */
+ /* 5, 6, 7, 8, 9, S */
+ /* sysinit */ { boot, boot, boot, boot, boot,
+ boot, boot, boot, boot, boot, single0 },
+ /* boot */ { normal, normal, normal, normal, normal,
+ normal, normal, normal, normal, normal, single1 },
+ /* single0 */ { normal, normal, normal, normal, normal,
+ normal, normal, normal, normal, normal, single0 },
+ /* single1 */ { normal, normal, normal, normal, normal,
+ normal, normal, normal, normal, normal, single1 },
+ /* normal */ { normal, normal, normal, normal, normal,
+ normal, normal, normal, normal, normal, single1 },
+};
+
+enum boot_state boot_state;
+int runlevel;
+
+int initdefault; /* Default runlevel */
+int dfl_level;
+
+static int
+runlevel_index (int n)
+{
+ char *p = strchr (valid_runlevels, n);
+ if (!p)
+ return -1;
+ return p - valid_runlevels;
+}
+
+int
+runlevel_match (struct component *comp)
+{
+ if (init_process)
+ {
+ 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 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;
+ }
+
+ if (!comp->runlevels)
+ return 1;
+ return !!strchr (comp->runlevels, runlevel);
+ }
+ }
+ return 1;
+}
+
+void
+inittrans ()
+{
+ int n;
+ int newlevel = 0;
+ enum boot_state newstate;
+
+ if (progman_running_p ())
+ /* Noting to do if there are processes left in the previous runlevel */
+ return;
+
+ n = runlevel_index (runlevel);
+ if (n == -1)
+ n = 11; /* assume S */
+
+ newstate = boot_trans_tab[boot_state][n];
+ if (newstate != boot_state)
+ {
+ debug (1, ("STATE TRANS: %s -> %s", boot_state_name[boot_state],
+ boot_state_name[newstate]));
+ boot_state = newstate;
+ }
+
+ switch (boot_state)
+ {
+ case sysinit:
+ case boot:
+ break;
+ case single0:
+ case single1:
+ newlevel = 'S';
+ break;
+ case normal:
+ /* boot -> normal */
+ newlevel = dfl_level ? dfl_level : initdefault;
+ }
+ if (newlevel && newlevel != runlevel)
+ {
+ debug (1, ("RL TRANS: %c -> %c", runlevel, newlevel));
+ runlevel = newlevel;
+ }
+}
+
+/* Return true if the progman should wait for the component to
+ terminate. */
+int
+is_comp_wait (struct component *comp)
+{
+ switch (comp->mode)
+ {
+ case pies_comp_boot:
+ case pies_comp_powerfail:
+ case pies_comp_ctrlaltdel:
+ case pies_comp_powerfailnow:
+ case pies_comp_kbrequest:
+ return 0;
+ }
+ return 1;
+}
+

Return to:

Send suggestions and report system problems to the System administrator.