diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-05-24 12:45:25 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-05-24 13:50:39 +0300 |
commit | 6dd0ec08db301984b8f8f9082f28006d5915c183 (patch) | |
tree | e916ad37fbd3cbcaf85103667f28e0d47f3c2e45 | |
parent | 2a646ee7cbbcb6f4bbd8f38bb3c1e1418550f3fc (diff) | |
download | pies-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.
-rw-r--r-- | src/comp.c | 87 | ||||
-rw-r--r-- | src/pies.c | 115 | ||||
-rw-r--r-- | src/pies.h | 38 | ||||
-rw-r--r-- | src/progman.c | 291 | ||||
-rw-r--r-- | src/socket.c | 54 | ||||
-rw-r--r-- | tests/Makefile.am | 9 | ||||
-rw-r--r-- | tests/atlocal.in | 2 | ||||
-rwxr-xr-x | tests/aux/mailer (renamed from tests/mailer) | 0 | ||||
-rwxr-xr-x | tests/aux/respawn (renamed from tests/respawn) | 0 | ||||
-rwxr-xr-x | tests/aux/retcode (renamed from tests/retcode) | 0 | ||||
-rwxr-xr-x | tests/aux/startup | 7 | ||||
-rw-r--r-- | tests/redirect.at | 2 | ||||
-rw-r--r-- | tests/respawn.at | 2 | ||||
-rw-r--r-- | tests/ret-exec.at | 4 | ||||
-rw-r--r-- | tests/ret-notify.at | 6 | ||||
-rw-r--r-- | tests/startup.at | 84 | ||||
-rw-r--r-- | tests/testsuite.at | 1 |
17 files changed, 442 insertions, 260 deletions
@@ -15,39 +15,44 @@ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" #include "prog.h" #include <assert.h> 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 component_link (struct component *comp, struct component *ref) { if (!ref) { struct complist *list = &comp_list[comp->listidx]; @@ -76,24 +81,40 @@ component_link (struct component *comp, struct component *ref) ref->next = comp; } } 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)) x->next = comp->next; else list->head = comp->next; if ((x = comp->next)) x->prev = comp->prev; else @@ -192,25 +213,30 @@ component_free (struct component *comp) void component_ref_incr (struct component *comp) { ++comp->ref_count; } void component_ref_decr (struct component *comp) { assert (comp->ref_count > 0); if (--comp->ref_count == 0) - component_free (comp); + { + if (component_is_active (comp)) + comp_array_remove (comp->arridx); + else + component_free (comp); + } } static int argvcmp (char **a, char **b) { size_t i; if (!a != !b) return 1; for (i = 0; a[i]; i++) if (!b[i] || strcmp (b[i], a[i])) @@ -416,60 +442,48 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx) } depmap_end (pos); if (n == (size_t)-1) break; i = n; } 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); depmap = depmap_alloc (comp_count); for (i = 0; i < comp_count; ) { struct component *comp = comp_array[i]; struct grecs_list_entry *ep; if (comp->prereq) for (ep = comp->prereq->head; ep; ep = ep->next) { char const *tag = ep->data; ssize_t tgt = component_lookup_index (tag); if (tgt < 0) { 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) for (ep = comp->depend->head; ep; ep = ep->next) { char const *tag = ep->data; ssize_t tgt = component_lookup_index (tag); if (tgt < 0) { @@ -488,28 +502,25 @@ component_build_depmap (void) depmap_tc (dp); for (i = 0; i < comp_count; i++) if (!(comp_array[i]->flags & CF_REMOVE) && depmap_isset (dp, i, i)) { logmsg (LOG_ERR, _("component %s depends on itself"), comp_array[i]->tag); 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); - } + comp_array_remove (i); else i++; free (dp); } void component_config_commit (void) { struct complist *list = &comp_list[cur]; struct component *comp, *match; int prev = prev_index (); @@ -519,56 +530,72 @@ component_config_commit (void) for (comp = list->head, i = 0; comp; comp = comp->next, i++) /* nothing */; if (i == 0) { free (comp_array); 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; ) { - match = complist_find_match (prev, comp); - if (match) + struct component *next = comp->next; + if (loaded && comp->mode == pies_comp_startup) { - component_merge (match, comp); - component_unlink (match); - match->listidx = cur; - component_link (match, comp->prev); + /* Ignore startup components */ + component_unlink (comp); component_free (comp); - comp = match; } - comp_array[i] = comp; - comp->arridx = i; + else + { + match = complist_find_match (prev, comp); + if (match) + { + component_merge (match, comp); + component_unlink (match); + match->listidx = cur; + 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); pies_schedule_children (PIES_CHLD_GC); } /* Build dependency map */ 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; int i; #define COMPERR(func, fmt, arg) \ do \ { \ if (!header) \ { \ @@ -123,49 +123,49 @@ config_file_add (struct config_syntax *syntax, const char *name) } void config_file_add_type (enum config_syntax_type syntax, const char *name) { config_file_add (&config_syntax_tab[syntax], name); } int config_file_remove (const char *name) { struct grecs_list_entry *ep; - + for (ep = config_list->head; ep; ep = ep->next) { struct config_file *file = ep->data; if (strcmp (file->name, name) == 0) { grecs_list_remove_entry (config_list, ep); config_file_free (file); return 0; } } return 1; } void config_file_remove_all (void) { grecs_list_clear (config_list); } void config_file_list_serialize (struct json_value *ar) { struct grecs_list_entry *ep; - + for (ep = config_list->head; ep; ep = ep->next) { struct config_file *file = ep->data; struct json_value *obj = json_new_object (); json_object_set (obj, "syntax", json_new_string (file->syntax->name)); json_object_set (obj, "file", json_new_string (file->name)); json_array_append (ar, obj); } } /* Logging */ static int @@ -318,25 +318,25 @@ static struct tokendef sig_tokendef[] = { #undef S void action_free (struct action *act) { if (!act) return; if (act->nstat > 0) free (act->status); free (act->addr); free (act->message); free (act->command); - + free (act); } static void free_entry_action (void *act) { action_free (act); } static struct action * create_action (struct component *comp, grecs_locus_t *locus, @@ -350,25 +350,25 @@ create_action (struct component *comp, struct action *act; retv = grecs_calloc (argc, sizeof *retv); if (argc == 0 || (argc == 1 && strcmp (getarg (val, 0, locus), "*") == 0)) allflag = 1; else { for (i = 0; i < argc; i++) { unsigned n; const char *arg = getarg (val, i, locus); size_t len = strlen (arg); - + if (isdigit (arg[0])) { char *p; n = strtoul (arg, &p, 0); if (*p) { grecs_error (locus, 0, _("%s: not a number"), p); continue; } } else if (len > 3 && memcmp (arg, "SIG", 3) == 0) { @@ -385,30 +385,30 @@ create_action (struct component *comp, else if (strtotok_ci (sig_tokendef, arg, (int*) &n)) { grecs_error (locus, 0, _("%s: not a signal code"), arg); continue; } n |= STATUS_SIG_BIT; } else if (strtotok_ci (ex_tokendef, arg, (int *) &n)) { grecs_error (locus, 0, _("%s: not a return code"), arg); continue; } - + /* Alles in ordnung */ retv[retc++] = n; } } - + if (retc == 0 && !allflag) { free (retv); return NULL; } act = grecs_zalloc (sizeof *act); if (!allflag) { act->nstat = retc; act->status = retv; } @@ -463,45 +463,45 @@ return_code_section_parser (enum grecs_callback_command cmd, struct component *comp = varptr; size_t count; struct action *act; switch (cmd) { case grecs_callback_section_begin: if (GRECS_VALUE_EMPTY_P (value)) { grecs_error (locus, 0, _("missing tag")); return 1; } - + switch (value->type) { case GRECS_TYPE_STRING: act = create_action (comp, locus, value, 1, _get_string_arg); break; - + case GRECS_TYPE_ARRAY: act = create_action (comp, locus, value, value->v.arg.c, _get_array_arg); break; - + case GRECS_TYPE_LIST: count = grecs_list_size (value->v.list); act = create_action (comp, locus, value, count, _get_list_arg); } if (!act) return 1; *(struct action **) cb_data = act; break; - + case grecs_callback_section_end: break; case grecs_callback_set_value: grecs_error (locus, 0, _("invalid use of block statement")); } return 0; } static char ** config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus, size_t *pargc) { @@ -533,25 +533,25 @@ _cb_command (enum grecs_callback_command cmd, switch (value->type) { case GRECS_TYPE_STRING: if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS)) { grecs_error (locus, 0, "wordsplit: %s", strerror (errno)); return 1; } wordsplit_get_words (&ws, &comp->argc, &comp->argv); wordsplit_free (&ws); break; - + case GRECS_TYPE_ARRAY: comp->argv = config_array_to_argv (value, locus, &comp->argc); break; case GRECS_TYPE_LIST: grecs_error (locus, 0, _("unexpected list")); return 1; } return 0; } static int @@ -693,97 +693,97 @@ static int _cb_redir (enum grecs_callback_command cmd, grecs_locus_t *locus, void *varptr, grecs_value_t *value, void *cb_data) { struct redirector *rp = varptr; static struct tokendef redirtab[] = { {"null", redir_null}, {"syslog", redir_syslog}, {"file", redir_file}, {NULL} }; int res; - + switch (value->type) { case GRECS_TYPE_STRING: if (strcmp (value->v.string, "null") == 0) { rp->type = redir_null; break; } rp->type = redir_syslog; if (string_to_syslog_priority (value->v.string, &rp->v.prio)) { grecs_error (locus, 0, _("unknown syslog priority %s"), value->v.string); return 0; } break; - + case GRECS_TYPE_ARRAY: if (assert_grecs_value_type (locus, value->v.arg.v[0], GRECS_TYPE_STRING)) return 0; if (strtotok (redirtab, value->v.arg.v[0]->v.string, &res)) grecs_error (locus, 0, _("%s: unrecognised redirector type"), value->v.arg.v[0]->v.string); else { if (res != redir_null) { if (value->v.arg.c != 2) { grecs_error (locus, 0, _("wrong number of arguments")); return 0; } if (assert_grecs_value_type (locus, value->v.arg.v[1], GRECS_TYPE_STRING)) return 0; - + switch (res) { case redir_null: break; - + case redir_syslog: if (string_to_syslog_priority (value->v.arg.v[1]->v.string, &rp->v.prio)) { grecs_error (locus, 0, _("unknown syslog priority %s"), value->v.arg.v[1]->v.string); return 0; } break; - + case redir_file: rp->v.file = grecs_strdup (value->v.arg.v[1]->v.string); break; } } rp->type = res; } break; - + default: grecs_error (locus, 0, _("unexpected list")); } - + return 0; } static struct tokendef socktype_xtab[] = { - { "stream", SOCK_STREAM }, - { "dgram", SOCK_DGRAM }, + { "stream", SOCK_STREAM }, + { "dgram", SOCK_DGRAM }, { "seqpacket", SOCK_SEQPACKET }, { "raw", SOCK_RAW }, { "rdm", SOCK_RDM }, #ifdef SOCK_PACKET { "packet", SOCK_PACKET }, #endif { NULL } }; int str_to_socket_type (const char *str, int *pres) { @@ -811,30 +811,32 @@ _cb_socket_type (enum grecs_callback_command cmd, } static struct tokendef modetab[] = { {"exec", pies_comp_exec}, {"respawn", pies_comp_exec}, {"wait", pies_comp_wait}, {"once", pies_comp_once}, {"accept", pies_comp_accept}, {"inetd", pies_comp_inetd}, {"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}, {"powerwait", pies_comp_powerwait}, {"powerokwait", pies_comp_powerokwait}, - {"ctrlaltdel", pies_comp_ctrlaltdel}, + {"ctrlaltdel", pies_comp_ctrlaltdel}, {"ondemand", pies_comp_ondemand}, {"sysinit", pies_comp_sysinit}, {"powerfailnow", pies_comp_powerfailnow}, {"kbrequest", pies_comp_kbrequest}, {NULL} }; static int _cb_mode (enum grecs_callback_command cmd, grecs_locus_t *locus, void *varptr, grecs_value_t *value, void *cb_data) @@ -911,44 +913,44 @@ _cb_flags (enum grecs_callback_command cmd, { int *flags = varptr; switch (value->type) { case GRECS_TYPE_STRING: if (str_to_cf (value->v.string, flags)) { grecs_error (locus, 0, _("%s: unrecognised flag"), value->v.string); return 1; } break; - + case GRECS_TYPE_LIST: { struct grecs_list_entry *ep; - + for (ep = value->v.list->head; ep; ep = ep->next) { const grecs_value_t *vp = ep->data; if (assert_grecs_value_type (locus, vp, GRECS_TYPE_STRING)) return 1; if (str_to_cf (vp->v.string, flags)) { grecs_error (locus, 0, _("%s: unrecognised flag"), vp->v.string); return 1; } } } break; - + case GRECS_TYPE_ARRAY: grecs_error (locus, 0, _("too many arguments")); return 1; } return 0; } static int _cb_initdefault (enum grecs_callback_command cmd, grecs_locus_t *locus, void *varptr, grecs_value_t *value, void *cb_data) { @@ -1219,25 +1221,25 @@ struct grecs_keyword component_keywords[] = { N_("tag"), N_("Tag of master TCPMUX component."), grecs_type_string, GRECS_DFLT, NULL, offsetof (struct component, tcpmux), NULL }, {NULL} }; struct grecs_keyword * find_component_keyword (const char *ident) { struct grecs_keyword *kwp; - + for (kwp = component_keywords; kwp->ident; kwp++) if (strcmp (kwp->ident, ident) == 0) return kwp; return NULL; } static int component_section_parser (enum grecs_callback_command cmd, grecs_locus_t *locus, void *varptr, grecs_value_t *value, void *cb_data) { struct component *comp; @@ -1247,25 +1249,25 @@ component_section_parser (enum grecs_callback_command cmd, { case grecs_callback_section_begin: if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; comp = component_create (value->v.string); *section_data = comp; break; case grecs_callback_section_end: comp = *(struct component **) section_data; component_finish (comp, locus); break; - + case grecs_callback_set_value: grecs_error (locus, 0, _("expected block statement")); } return 0; } struct grecs_keyword control_keywords[] = { {"socket", N_("url: string"), N_("Listen on the given url."), grecs_type_string, GRECS_DFLT, &control.url, 0, conf_callback_url}, @@ -1525,77 +1527,77 @@ config_init (void) pies_identity_mechanism_register (&pam_identity_mechanism); #endif } int pies_config_parse (char const *name) { struct grecs_node *node; struct grecs_node *tree = grecs_parse (name); if (!tree) return 1; - + for (node = tree; node; node = node->next) { node = grecs_find_node (node, "identity-provider"); if (!node) break; pies_config_provider (node); } if (grecs_tree_process (tree, pies_keywords)) return 1; grecs_tree_free (tree); if (grecs_error_count) return 1; - + return 0; } void config_help (void) { static char docstring[] = /* TRANSLATORS: do not translate words in quotes */ N_("Configuration file structure for pies.\n" "For more information, use command \"info pies configuration\"."); grecs_print_docstring (docstring, 0, stdout); grecs_print_statement_array (pies_keywords, 1, 0, stdout); pies_config_identity_mechanisms_help (); } int pies_read_config (void) { struct grecs_list_entry *ep; int err = 0; component_config_begin (); - + for (ep = config_list->head; ep; ep = ep->next) { struct config_file *file = ep->data; if (file->syntax->parser (file->name)) ++err; } if (init_process) err = 0; - + if (err) component_config_rollback (); - + return err; } int pies_reread_config (void) { logmsg (LOG_INFO, _("reading configuration")); return pies_read_config (); } static struct config_syntax *current_syntax = &config_syntax_tab[CONF_PIES]; @@ -1647,25 +1649,25 @@ sig_handler (int sig) case SIGALRM: pies_schedule_children (PIES_CHLD_WAKEUP); break; } } void setsigvhan (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc) { int i; struct sigaction act; - + act.sa_flags = 0; sigemptyset (&act.sa_mask); for (i = 0; i < sigc; i++) sigaddset (&act.sa_mask, sigv[i]); act.sa_handler = handler; for (i = 0; i < sigc; i++) { sigaction (sigv[i], &act, NULL); } } @@ -1770,49 +1772,49 @@ pies_check_status (pid_t *ppid) return pies_status_stale; return pies_status_running; } #define pies_control_url() control.url->string int request_restart_components (size_t cc, char **cv) { char **argv; size_t i, j; - + argv = grecs_calloc (5 + 3 * cc - 1, sizeof (*argv)); argv[0] = "piesctl"; argv[1] = "--url"; argv[2] = (char*) pies_control_url (); argv[3] = "restart"; j = 4; for (i = 0; i < cc; i++) { if (i > 0) argv[j++] = "or"; argv[j++] = "component"; argv[j++] = cv[i]; } argv[j] = NULL; execvp (argv[0], argv); logmsg (LOG_ERR, "can't run piesctl: %s", strerror (errno)); return EX_OSFILE; } void list_components (void) { char *argv[5]; - + argv[0] = "piesctl"; argv[1] = "--url"; argv[2] = (char*) pies_control_url (); argv[3] = "list"; argv[4] = NULL; execvp (argv[0], argv); logmsg (LOG_ERR, "can't run piesctl: %s", strerror (errno)); exit (EX_OSFILE); } int @@ -1933,25 +1935,25 @@ void remove_pidfile (char *name) { if (unlink (name)) logfuncall ("unlink", name, errno); } static void set_mailer_argcv (void) { int i; struct wordsplit ws; - + if (wordsplit (mailer_command_line, &ws, WRDSF_DEFFLAGS)) { logmsg (LOG_CRIT, _("cannot parse mailer command line: %s"), strerror (errno)); exit (EX_CONFIG); } mailer_argc = ws.ws_wordc; mailer_argv = grecs_calloc (mailer_argc + 1, sizeof (mailer_argv[0])); for (i = 0; i < mailer_argc; i++) mailer_argv[i] = grecs_strdup (ws.ws_wordv[i]); mailer_argv[i] = NULL; wordsplit_free (&ws); @@ -2024,73 +2026,73 @@ set_state_file_names (const char *base) size_t pies_master_argc; char **pies_master_argv; int main (int argc, char **argv) { pid_t pid; extern char **environ; struct grecs_list_entry *ep; int diag_flags; int i; - + set_program_name (argv[0]); #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif mf_proctitle_init (argc, argv, environ); grecs_print_diag_fun = pies_diag_printer; - + pies_master_argc = argc; pies_master_argv = argv; - + set_quoting_style (NULL, shell_quoting_style); init_process = getpid () == 1; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "--no-init") == 0) { init_process = 0; break; } } - + /* Set default logging */ if (init_process) { log_facility = LOG_DAEMON; diag_flags = DIAG_TO_STDERR | DIAG_REOPEN_LOG; } else diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR); - + diag_setup (diag_flags); - + config_init (); parse_options (&argc, &argv); - + if (argc && !(command == COM_RESTART_COMPONENT || command == COM_TRACE_DEPEND || command == COM_TRACE_PREREQ)) { logmsg (LOG_ERR, "extra command line arguments"); exit (EX_USAGE); } - + if (!instance) { instance = strrchr (program_name, '/'); if (!instance) instance = (char*) program_name; else instance++; } setenv ("PIES_INSTANCE", instance, 1); log_tag = grecs_strdup (instance); set_conf_file_names (instance); @@ -2110,72 +2112,72 @@ main (int argc, char **argv) && grecs_preproc_run (file->name, grecs_preprocessor)) exit (EX_CONFIG); } exit (0); } else if (pies_read_config ()) exit (EX_CONFIG); component_config_commit (); set_state_file_names (instance); set_mailer_argcv (); - + if (lint_mode) exit (0); /* Re-setup logging: it might have been reset in the config file */ diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0); - + if (!control.url) { char const *str = default_control_url[init_process]; if (pies_url_create (&control.url, str)) { logmsg (LOG_CRIT, _("%s: cannot create control URL: %s"), str, strerror (errno)); if (!init_process) exit (EX_OSERR); } } - + switch (command) { case COM_RESTART_COMPONENT: pies_priv_setup (&pies_privs); if (pies_umask) umask (pies_umask); exit (request_restart_components (argc, argv)); - + case COM_RELOAD: exit (request_reload ()); case COM_STATUS: exit (request_status ()); case COM_STOP: exit (request_stop ()); case COM_DUMP_DEPMAP: components_dump_depmap (); exit (0); case COM_TRACE_DEPEND: components_trace (argv, depmap_row); exit (0); - - case COM_TRACE_PREREQ: + + case COM_TRACE_PREREQ: components_trace (argv, depmap_col); exit (0); - + default: pies_priv_setup (&pies_privs); if (pies_umask) umask (pies_umask); } if (init_process) { foreground = 1; sysvinit_begin (); } else @@ -2184,59 +2186,60 @@ main (int argc, char **argv) case pies_status_ctr: break; case pies_status_stale: case pies_status_noresp: if (!force_option) { logmsg (LOG_ERR, _("another pies instance may be running (pid %lu), " "use --force to override"), (unsigned long) pid); exit (EX_USAGE); } break; - + case pies_status_running: logmsg (LOG_ERR, _("another pies instance already running (pid %lu)"), (unsigned long) pid); exit (EX_USAGE); } - + if (!foreground) { check_pidfile (pidfile); if (daemon (0, 0) == -1) { logfuncall ("daemon", NULL, errno); exit (EX_SOFTWARE); } diag_setup (DIAG_TO_SYSLOG); } |