aboutsummaryrefslogtreecommitdiff
path: root/src/pies.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/pies.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/pies.c')
-rw-r--r--src/pies.c115
1 files changed, 59 insertions, 56 deletions
diff --git a/src/pies.c b/src/pies.c
index 89c0b7e..98488a6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -132,7 +132,7 @@ 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;
@@ -156,7 +156,7 @@ 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;
@@ -327,7 +327,7 @@ action_free (struct action *act)
free (act->addr);
free (act->message);
free (act->command);
-
+
free (act);
}
@@ -359,7 +359,7 @@ create_action (struct component *comp,
unsigned n;
const char *arg = getarg (val, i, locus);
size_t len = strlen (arg);
-
+
if (isdigit (arg[0]))
{
char *p;
@@ -394,12 +394,12 @@ create_action (struct component *comp,
grecs_error (locus, 0, _("%s: not a return code"), arg);
continue;
}
-
+
/* Alles in ordnung */
retv[retc++] = n;
}
}
-
+
if (retc == 0 && !allflag)
{
free (retv);
@@ -472,18 +472,18 @@ return_code_section_parser (enum grecs_callback_command cmd,
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);
@@ -492,7 +492,7 @@ return_code_section_parser (enum grecs_callback_command cmd,
return 1;
*(struct action **) cb_data = act;
break;
-
+
case grecs_callback_section_end:
break;
@@ -542,7 +542,7 @@ _cb_command (enum grecs_callback_command cmd,
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;
@@ -702,7 +702,7 @@ _cb_redir (enum grecs_callback_command cmd,
{NULL}
};
int res;
-
+
switch (value->type)
{
case GRECS_TYPE_STRING:
@@ -719,7 +719,7 @@ _cb_redir (enum grecs_callback_command cmd,
return 0;
}
break;
-
+
case GRECS_TYPE_ARRAY:
if (assert_grecs_value_type (locus, value->v.arg.v[0],
GRECS_TYPE_STRING))
@@ -739,12 +739,12 @@ _cb_redir (enum grecs_callback_command cmd,
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))
@@ -755,7 +755,7 @@ _cb_redir (enum grecs_callback_command cmd,
return 0;
}
break;
-
+
case redir_file:
rp->v.file = grecs_strdup (value->v.arg.v[1]->v.string);
break;
@@ -764,17 +764,17 @@ _cb_redir (enum grecs_callback_command cmd,
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 },
@@ -820,12 +820,14 @@ 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},
{"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},
@@ -920,11 +922,11 @@ _cb_flags (enum grecs_callback_command cmd,
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;
@@ -939,7 +941,7 @@ _cb_flags (enum grecs_callback_command cmd,
}
}
break;
-
+
case GRECS_TYPE_ARRAY:
grecs_error (locus, 0, _("too many arguments"));
return 1;
@@ -1228,7 +1230,7 @@ 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;
@@ -1256,7 +1258,7 @@ component_section_parser (enum grecs_callback_command cmd,
comp = *(struct component **) section_data;
component_finish (comp, locus);
break;
-
+
case grecs_callback_set_value:
grecs_error (locus, 0, _("expected block statement"));
}
@@ -1534,7 +1536,7 @@ pies_config_parse (char const *name)
if (!tree)
return 1;
-
+
for (node = tree; node; node = node->next)
{
node = grecs_find_node (node, "identity-provider");
@@ -1550,7 +1552,7 @@ pies_config_parse (char const *name)
if (grecs_error_count)
return 1;
-
+
return 0;
}
@@ -1573,7 +1575,7 @@ pies_read_config (void)
int err = 0;
component_config_begin ();
-
+
for (ep = config_list->head; ep; ep = ep->next)
{
struct config_file *file = ep->data;
@@ -1583,10 +1585,10 @@ pies_read_config (void)
if (init_process)
err = 0;
-
+
if (err)
component_config_rollback ();
-
+
return err;
}
@@ -1656,7 +1658,7 @@ 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++)
@@ -1779,7 +1781,7 @@ 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";
@@ -1803,7 +1805,7 @@ void
list_components (void)
{
char *argv[5];
-
+
argv[0] = "piesctl";
argv[1] = "--url";
argv[2] = (char*) pies_control_url ();
@@ -1942,7 +1944,7 @@ 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"),
@@ -2033,7 +2035,7 @@ main (int argc, char **argv)
struct grecs_list_entry *ep;
int diag_flags;
int i;
-
+
set_program_name (argv[0]);
#ifdef ENABLE_NLS
setlocale (LC_ALL, "");
@@ -2043,10 +2045,10 @@ main (int argc, char **argv)
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;
@@ -2058,7 +2060,7 @@ main (int argc, char **argv)
break;
}
}
-
+
/* Set default logging */
if (init_process)
{
@@ -2067,13 +2069,13 @@ main (int argc, char **argv)
}
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))
@@ -2081,7 +2083,7 @@ main (int argc, char **argv)
logmsg (LOG_ERR, "extra command line arguments");
exit (EX_USAGE);
}
-
+
if (!instance)
{
instance = strrchr (program_name, '/');
@@ -2119,13 +2121,13 @@ main (int argc, char **argv)
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];
@@ -2137,7 +2139,7 @@ main (int argc, char **argv)
exit (EX_OSERR);
}
}
-
+
switch (command)
{
case COM_RESTART_COMPONENT:
@@ -2145,7 +2147,7 @@ main (int argc, char **argv)
if (pies_umask)
umask (pies_umask);
exit (request_restart_components (argc, argv));
-
+
case COM_RELOAD:
exit (request_reload ());
@@ -2162,11 +2164,11 @@ main (int argc, char **argv)
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)
@@ -2193,13 +2195,13 @@ main (int argc, char **argv)
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);
@@ -2212,14 +2214,14 @@ main (int argc, char **argv)
}
logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version);
-
+
if (!init_process)
{
if (ctl_open ())
exit (EX_UNAVAILABLE);
create_pidfile (pidfile);
}
-
+
if (pies_master_argv[0][0] != '/')
logmsg (LOG_NOTICE,
_("not started as an absolute pathname; "
@@ -2228,6 +2230,7 @@ main (int argc, char **argv)
signal_setup (sig_handler);
progman_create_sockets ();
+ program_init_startup ();
progman_start ();
do
@@ -2261,7 +2264,7 @@ main (int argc, char **argv)
pies_schedule_children (PIES_CHLD_WAKEUP);
action = ACTION_CONT;
break;
-
+
case ACTION_STOP:
if (init_process)
{
@@ -2276,7 +2279,7 @@ main (int argc, char **argv)
pies_schedule_children (PIES_CHLD_WAKEUP);
action = ACTION_CONT;
break;
-
+
case ACTION_KBREQUEST:
debug (1, ("kbrequest"));
sysvinit_runlevel_setup (PIES_COMP_MASK (pies_comp_kbrequest));

Return to:

Send suggestions and report system problems to the System administrator.