aboutsummaryrefslogtreecommitdiff
path: root/src/comp.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-05-24 12:45:25 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-05-24 13:50:39 +0300
commit6dd0ec08db301984b8f8f9082f28006d5915c183 (patch)
treee916ad37fbd3cbcaf85103667f28e0d47f3c2e45 /src/comp.c
parent2a646ee7cbbcb6f4bbd8f38bb3c1e1418550f3fc (diff)
downloadpies-6dd0ec08db301984b8f8f9082f28006d5915c183.tar.gz
pies-6dd0ec08db301984b8f8f9082f28006d5915c183.tar.bz2
Initial implementation of "startup" components.
These are components that are run at program startup. Starting other components is delayed until all startup components terminate. This is similar to SysV "bootwait" components. Upon termination, startup components are removed from the configuration. They are not renewed upon configuratuion reload. * src/comp.c (comp_array_remove): Remove from the depmap as well. (component_ref_decr): Use comp_array_remove for active components and plain component_free for inactive ones. (component_build_depmap): Use comp_array_remove. (component_config_commit): Special handling for pies_comp_startup components. * src/pies.c (modetab): New component modes: "startup" and "shutdown". (main): Run program_init_startup. * src/pies.h (pies_comp_mode): New modes: pies_comp_startup and pies_comp_shutdown. (program_init_startup): New proto. * src/progman.c (progman_waiting_p): Return 1 if a startup component is still running. (program_init_startup): New function. (progman_cleanup): Handle pies_comp_startup termination. * src/socket.c (switch_eids): Avoid unnecessary calls to setegid and seteuid. * tests/atlocal.in (auxdir): New variable. * tests/mailer: Move to tests/aux/ * tests/respawn: Move to tests/aux/ * tests/retcode: Move to tests/aux/ * tests/aux/startup: New auxiliary program. * tests/redirect.at: Start components from $auxdir. * tests/respawn.at: Likewise. * tests/ret-exec.at: Likewise. * tests/ret-notify.at: Likewise. * tests/startup.at: New file. * tests/testsuite.at: Include startup.at * tests/Makefile.am: Add new tests.
Diffstat (limited to 'src/comp.c')
-rw-r--r--src/comp.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/src/comp.c b/src/comp.c
index c3e998a..2346306 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -21,27 +21,32 @@
struct complist
{
struct component *head;
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;
static struct component **comp_array;
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);
}
void
@@ -82,12 +87,28 @@ void
component_append (struct component *comp)
{
component_link (comp, comp_list[comp->listidx].tail);
}
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];
struct component *x;
if ((x = comp->prev))
@@ -198,14 +219,19 @@ component_ref_incr (struct component *comp)
void
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)
{
size_t i;
@@ -422,23 +448,12 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx)
}
while (i != idx);
logmsg_printf (LOG_NOTICE, "%s\n", comp_array[idx]->tag);
}
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;
pies_depmap_t dp;
free (depmap);
@@ -457,13 +472,12 @@ component_build_depmap (void)
{
logmsg (LOG_ERR,
_("component %s depends on %s, "
"which is not declared"),
comp->tag, tag);
comp_array_remove (i);
- depmap_remove (depmap, i);
continue;
}
depmap_set (depmap, i, tgt);
}
if (comp->depend)
@@ -494,16 +508,13 @@ component_build_depmap (void)
report_cyclic_dependency (dp, i);
}
for (i = 0; i < comp_count;)
if (comp_array[i]->flags & CF_REMOVE)
- {
comp_array_remove (i);
- depmap_remove (depmap, i);
- }
else
i++;
free (dp);
}
@@ -525,14 +536,23 @@ component_config_commit (void)
comp_array = NULL;
}
else
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)
{
component_merge (match, comp);
component_unlink (match);
@@ -540,13 +560,18 @@ component_config_commit (void)
component_link (match, comp->prev);
component_free (comp);
comp = match;
}
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];
if (list->head)
{
progman_foreach (mark_prog, NULL);
@@ -557,12 +582,14 @@ component_config_commit (void)
component_build_depmap ();
/* Register new progs */
for (comp = comp_list[cur].head; comp; comp = comp->next)
if (!comp->prog)
register_prog (comp);
+
+ loaded = 1;
}
static int
component_verify (struct component *comp, grecs_locus_t *locus)
{
int header = 0;

Return to:

Send suggestions and report system problems to the System administrator.