diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/comp.c | 65 | ||||
-rw-r--r-- | src/pies.c | 3 | ||||
-rw-r--r-- | src/pies.h | 8 | ||||
-rw-r--r-- | src/progman.c | 47 | ||||
-rw-r--r-- | src/socket.c | 4 |
5 files changed, 105 insertions, 22 deletions
@@ -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 @@ -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 @@ -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) } } } - |