aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/comp.c65
-rw-r--r--src/pies.c3
-rw-r--r--src/pies.h8
-rw-r--r--src/progman.c47
-rw-r--r--src/socket.c4
5 files changed, 105 insertions, 22 deletions
diff --git a/src/comp.c b/src/comp.c
index c3e998a..2346306 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -24,6 +24,11 @@ struct complist
struct component *tail;
};
+/* 0 on the first load, and 1 on all subsequent reloads. Tells the
+ component_config_commit whether we're starting from scratch or just
+ updating an already loaded configuration */
+static int loaded;
+
static struct complist comp_list[2];
static int cur;
@@ -32,13 +37,13 @@ static size_t comp_count;
static pies_depmap_t depmap;
-static int
+static inline int
next_index (void)
{
return (cur + 1) % ARRAY_SIZE (comp_list);
}
-static int
+static inline int
prev_index (void)
{
return (cur + ARRAY_SIZE (comp_list) - 1) % ARRAY_SIZE (comp_list);
@@ -85,6 +90,22 @@ component_append (struct component *comp)
}
void
+comp_array_remove (size_t i)
+{
+ struct component *comp = comp_array[i];
+
+ depmap_remove (depmap, i);
+ while (i < comp_count -1)
+ {
+ comp_array[i] = comp_array[i+1];
+ comp_array[i]->arridx = i;
+ i++;
+ }
+ component_free (comp);
+ comp_count--;
+}
+
+void
component_unlink (struct component *comp)
{
struct complist *list = &comp_list[comp->listidx];
@@ -201,8 +222,13 @@ component_ref_decr (struct component *comp)
{
assert (comp->ref_count > 0);
if (--comp->ref_count == 0)
+ {
+ if (component_is_active (comp))
+ comp_array_remove (comp->arridx);
+ else
component_free (comp);
}
+}
static int
argvcmp (char **a, char **b)
@@ -425,17 +451,6 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx)
}
void
-comp_array_remove (size_t i)
-{
- struct component *comp = comp_array[i];
- if (i < comp_count - 1)
- memmove (&comp_array[i], &comp_array[i+1],
- (comp_count - i - 1) * sizeof comp_array[0]);
- component_free (comp);
- comp_count--;
-}
-
-void
component_build_depmap (void)
{
size_t i;
@@ -460,7 +475,6 @@ component_build_depmap (void)
"which is not declared"),
comp->tag, tag);
comp_array_remove (i);
- depmap_remove (depmap, i);
continue;
}
depmap_set (depmap, i, tgt);
@@ -497,10 +511,7 @@ component_build_depmap (void)
for (i = 0; i < comp_count;)
if (comp_array[i]->flags & CF_REMOVE)
- {
comp_array_remove (i);
- depmap_remove (depmap, i);
- }
else
i++;
@@ -528,8 +539,17 @@ component_config_commit (void)
comp_array = grecs_realloc (comp_array, i * sizeof (comp_array[0]));
comp_count = i;
- /* Rearrange components, registering prog entries for the new ones */
- for (comp = list->head, i = 0; comp; comp = comp->next, i++)
+ /* Rearrange components, registering entries for the new ones */
+ for (comp = list->head, i = 0; comp; )
+ {
+ struct component *next = comp->next;
+ if (loaded && comp->mode == pies_comp_startup)
+ {
+ /* Ignore startup components */
+ component_unlink (comp);
+ component_free (comp);
+ }
+ else
{
match = complist_find_match (prev, comp);
if (match)
@@ -543,7 +563,12 @@ component_config_commit (void)
}
comp_array[i] = comp;
comp->arridx = i;
+ i++;
+ }
+ comp = next;
}
+ /* Adjust comp_count */
+ comp_count = i;
/* Mark orphaned progs for termination */
list = &comp_list[prev];
@@ -560,6 +585,8 @@ component_config_commit (void)
for (comp = comp_list[cur].head; comp; comp = comp->next)
if (!comp->prog)
register_prog (comp);
+
+ loaded = 1;
}
static int
diff --git a/src/pies.c b/src/pies.c
index 89c0b7e..98488a6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -820,6 +820,8 @@ static struct tokendef modetab[] = {
{"nostartaccept", pies_comp_inetd},
{"pass-fd", pies_comp_pass_fd},
{"pass", pies_comp_pass_fd},
+ {"startup", pies_comp_startup},
+ {"shutdown", pies_comp_shutdown},
{"boot", pies_comp_boot},
{"bootwait", pies_comp_boot},
{"powerfail", pies_comp_powerfail},
@@ -2228,6 +2230,7 @@ main (int argc, char **argv)
signal_setup (sig_handler);
progman_create_sockets ();
+ program_init_startup ();
progman_start ();
do
diff --git a/src/pies.h b/src/pies.h
index a7f6567..bdc406b 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -138,6 +138,13 @@ enum pies_comp_mode
`start_action = pass' in MeTA1. */
pies_comp_pass_fd,
+ /* Components of this type runs once on program startup. Running other
+ components is delayed until the last startup component finishes. */
+ pies_comp_startup,
+
+ /* FIXME: Runs before program termination */
+ pies_comp_shutdown,
+
/*
** Init-style components
*/
@@ -334,6 +341,7 @@ int pies_read_config (void);
int pies_reread_config (void);
void register_prog (struct component *comp);
+void program_init_startup (void);
int progman_waiting_p (void);
void progman_start (void);
void progman_gc (void);
diff --git a/src/progman.c b/src/progman.c
index 1b09cd5..5bc4eb3 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -317,6 +317,19 @@ register_command (char *tag, char *command, pid_t pid)
link_prog (newp, progtail);
}
+static inline int
+progman_startup_phase (void)
+{
+ struct prog *prog;
+
+ for (prog = proghead; prog; prog = prog->next)
+ {
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
+ return 1;
+ }
+ return 0;
+}
+
int
progman_waiting_p (void)
{
@@ -324,7 +337,9 @@ progman_waiting_p (void)
for (prog = proghead; prog; prog = prog->next)
{
- if (IS_COMPONENT (prog) && prog->wait && prog->pid > 0)
+ if (IS_COMPONENT (prog)
+ && prog->pid > 0
+ && (prog->wait || prog->v.p.comp->mode == pies_comp_startup))
{
debug (3, ("%s: waiting for %s (%lu)",
__FUNCTION__, prog_tag (prog),
@@ -1526,12 +1541,32 @@ progman_recompute_alarm (void)
}
void
+program_init_startup (void)
+{
+ struct prog *prog;
+
+ for (prog = proghead; prog; prog = prog->next)
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
+ {
+ debug (1, ("running startup components"));
+ break;
+ }
+
+ for (; prog; prog = prog->next)
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
+ {
+ prog_start (prog);
+ }
+}
+
+void
progman_start (void)
{
struct prog *prog;
if (progman_waiting_p ())
- /* Noting to do if there are processes left in the previous runlevel */
+ /* Noting to do if there are processes left in the previous runlevel
+ (in sysv-init mode) or startup components running. */
return;
debug (1, ("starting components"));
@@ -2321,6 +2356,14 @@ progman_cleanup (int expect_term)
}
destroy_prog (&prog);
}
+ else if (prog->v.p.comp->mode == pies_comp_startup)
+ {
+ debug (1, (_("removing startup component %s, pid=%lu"),
+ prog_tag (prog), (unsigned long)pid));
+ destroy_prog (&prog);
+ if (!progman_startup_phase ())
+ pies_schedule_children (PIES_CHLD_WAKEUP);
+ }
else
{
if (prog->v.p.comp->mode >= pies_mark_sysvinit
diff --git a/src/socket.c b/src/socket.c
index aa01543..40c7aa7 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -24,12 +24,15 @@ switch_eids (uid_t *puid, gid_t *pgid, mode_t *pumask)
gid_t ogid = getegid ();
mode_t omask = umask (*pumask);
+ if ((*puid && *puid != ouid) || (*pgid && *pgid != ogid))
+ {
if (setegid (*pgid))
logmsg (LOG_ERR, _("cannot switch to EGID %lu: %s"),
(unsigned long) *pgid, strerror (errno));
if (seteuid (*puid))
logmsg (LOG_ERR, _("cannot switch to EUID %lu: %s"),
(unsigned long) *puid, strerror (errno));
+ }
*puid = ouid;
*pgid = ogid;
*pumask = omask;
@@ -637,4 +640,3 @@ pies_pause (void)
}
}
}
-

Return to:

Send suggestions and report system problems to the System administrator.