summaryrefslogtreecommitdiffabout
path: root/src/progman.c
authorSergey Poznyakoff <gray@gnu.org>2019-05-24 09:45:25 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-05-24 10:50:39 (GMT)
commit6dd0ec08db301984b8f8f9082f28006d5915c183 (patch) (side-by-side diff)
treee916ad37fbd3cbcaf85103667f28e0d47f3c2e45 /src/progman.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/progman.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/progman.c291
1 files changed, 167 insertions, 124 deletions
diff --git a/src/progman.c b/src/progman.c
index 1b09cd5..5bc4eb3 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -65,7 +65,7 @@ progman_lookup_component (const char *tag)
if (IS_COMPONENT (prog) && strcmp (prog_tag (prog), tag) == 0)
return prog->v.p.comp;
return NULL;
-}
+}
struct component *
progman_lookup_tcpmux (const char *service, const char *master)
@@ -122,7 +122,7 @@ link_prog (struct prog *prog, struct prog *ref)
prog->prev = ref;
prog->next = ref->next;
-
+
if ((x = ref->next))
x->prev = prog;
else
@@ -151,21 +151,21 @@ void
destroy_prog (struct prog **pp)
{
struct prog *p = *pp;
-
+
unlink_prog (p);
switch (p->type)
{
case TYPE_COMPONENT:
component_ref_decr (p->v.p.comp);
if (p->v.p.status == status_listener && p->v.p.socket != -1)
- deregister_socket (p->v.p.socket);
- /* FIXME: Remove also all dependent progs (esp. tcpmux) */
+ deregister_socket (p->v.p.socket);
+ /* FIXME: Remove also all dependent progs (esp. tcpmux) */
if (p->v.p.redir[RETR_OUT])
p->v.p.redir[RETR_OUT]->v.r.master = NULL;
if (p->v.p.redir[RETR_ERR])
p->v.p.redir[RETR_ERR]->v.r.master = NULL;
break;
-
+
case TYPE_REDIRECTOR:
{
struct prog *master = p->v.r.master;
@@ -182,7 +182,7 @@ destroy_prog (struct prog **pp)
free (p->v.r.tag);
}
break;
-
+
case TYPE_COMMAND:
free (p->v.c.tag);
free (p->v.c.command);
@@ -256,7 +256,7 @@ find_prog_ref (struct component *comp)
if (!comp)
return NULL; /* FIXME: Skip redirectors? */
}
-
+
if (comp->prog)
{
for (prog = comp->prog;
@@ -270,12 +270,12 @@ find_prog_ref (struct component *comp)
prog = NULL;
return prog;
}
-
+
static struct prog *
register_prog0 (struct component *comp)
{
struct prog *newp;
-
+
newp = grecs_zalloc (sizeof (*newp));
newp->type = TYPE_COMPONENT;
newp->pid = 0;
@@ -291,7 +291,7 @@ register_prog0 (struct component *comp)
newp->active = 0;
else
newp->active = 1;
-
+
if (comp->mode != pies_comp_exec)
comp->redir[RETR_OUT].type = redir_null;
@@ -317,14 +317,29 @@ 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)
{
struct prog *prog;
-
+
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),
@@ -406,17 +421,17 @@ open_redirector (struct prog *master, int stream)
case redir_file:
return redirect_to_file (master, stream);
-
+
case redir_syslog:
break;
}
-
+
if (pipe (p))
{
logmsg (LOG_CRIT, "pipe: %s", strerror (errno));
return -1;
}
-
+
switch (pid = fork ())
{
case 0:
@@ -428,10 +443,10 @@ open_redirector (struct prog *master, int stream)
FD_ZERO (&fdset);
FD_SET (p[0], &fdset);
close_fds (&fdset);
-
+
diag_setup (0);
signal_setup (redir_exit);
-
+
close (p[1]);
fp = fdopen (p[0], "r");
if (fp == NULL)
@@ -441,7 +456,7 @@ open_redirector (struct prog *master, int stream)
while (getline (&buf, &size, fp) > 0)
syslog (prio, "%s", buf);
_exit (0);
-
+
case -1:
logmsg (LOG_CRIT,
_("cannot run redirector `%s': fork failed: %s"),
@@ -466,7 +481,7 @@ conn_class_hasher (void *data, unsigned long n_buckets)
size_t value = 0;
unsigned char ch;
size_t len;
-
+
while ((ch = *tag++))
value = (value * 31 + ch) % n_buckets;
@@ -530,7 +545,7 @@ conn_class_lookup (const char *tag,
probe->sa_storage.s.sa_family);
break;
}
-
+
probe->count = 0;
if (!conn_tab)
{
@@ -725,7 +740,7 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
{
char *res;
size_t len;
-
+
if (a && b)
{
res = grecs_malloc (namelen + 1 + strlen (a) + strlen (b) + 1);
@@ -753,14 +768,14 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
res[namelen] = '=';
return res;
}
-
+
static void
environ_setup (char **hint)
{
char **old_env = environ;
char **new_env;
size_t count, i, j, n;
-
+
if (!hint)
return;
@@ -769,22 +784,22 @@ environ_setup (char **hint)
old_env = NULL;
hint++;
}
-
+
/* Count new environment size */
count = 0;
if (old_env)
for (i = 0; old_env[i]; i++)
count++;
-
+
for (i = 0; hint[i]; i++)
count++;
/* Allocate new environment. */
new_env = grecs_calloc (count + 1, sizeof new_env[0]);
-
+
/* Populate the environment. */
n = 0;
-
+
if (old_env)
for (i = 0; old_env[i]; i++)
{
@@ -795,7 +810,7 @@ environ_setup (char **hint)
for (i = 0; hint[i]; i++)
{
char *p;
-
+
if (hint[i][0] == '-')
{
/* Skip unset directives. */
@@ -806,12 +821,12 @@ environ_setup (char **hint)
slot if there's no such variable in new_env */
if (find_env_pos (new_env, hint[i], &j, NULL))
j = n;
-
+
if ((p = strchr (hint[i], '=')))
{
if (p == hint[i])
continue; /* Ignore erroneous entry */
- if (p[-1] == '+')
+ if (p[-1] == '+')
new_env[j] = env_concat (hint[i], p - hint[i] - 1,
find_env_ptr (environ, hint[i], 1),
p + 1);
@@ -835,7 +850,7 @@ environ_setup (char **hint)
if (envsize)
free (environ);
-
+
environ = new_env;
envsize = count + 1;
}
@@ -852,14 +867,14 @@ prog_sockenv (struct prog *prog)
union pies_sockaddr_storage *sa_client = &prog->v.p.sa_storage;
socklen_t cltlen = prog->v.p.sa_len;
const char *proto = NULL;
-
+
if (!(prog->v.p.comp->flags & CF_SOCKENV))
return;
if (socket_type_to_str (prog->v.p.comp->socket_type, &proto))
proto = umaxtostr (prog->v.p.comp->socket_type, buf);
add_env (ENV_SOCKTYPE, proto);
-
+
if (prog->v.p.comp->socket_url)
proto = prog->v.p.comp->socket_url->proto_s;
else if (prog->v.p.listener)
@@ -868,7 +883,7 @@ prog_sockenv (struct prog *prog)
proto = "TCP";
add_env (ENV_PROTO, proto);
-
+
if (getsockname (prog->v.p.socket,
(struct sockaddr *) &sa_server, &len) < 0)
logmsg (LOG_WARNING, "getsockname(): %s", strerror (errno));
@@ -920,7 +935,7 @@ static int
check_rate (struct prog *prog, unsigned testtime, size_t max_count)
{
time_t now;
-
+
time (&now);
if (prog->v.p.timestamp + testtime > now)
@@ -930,7 +945,7 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
prog->v.p.failcount = 0;
prog->v.p.timestamp = now;
}
-
+
if (prog->v.p.failcount > max_count)
{
prog->v.p.timestamp = now;
@@ -938,7 +953,7 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM);
return 1;
}
-
+
return 0;
}
@@ -961,7 +976,7 @@ static int
check_connection_rate (struct prog *prog)
{
size_t max_rate = prog->v.p.comp->max_rate
- ? prog->v.p.comp->max_rate : default_max_rate;
+ ? prog->v.p.comp->max_rate : default_max_rate;
if (max_rate && check_rate (prog, 60, max_rate))
{
logmsg (LOG_NOTICE,
@@ -1009,7 +1024,7 @@ prog_start_prologue (struct prog *prog)
logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"),
prog_tag (prog), prog->v.p.comp->dir, strerror (errno));
}
-
+
environ_setup (prog->v.p.comp->env ?
prog->v.p.comp->env :
((prog->v.p.comp->flags & CF_SOCKENV) ? sockenv_hint : NULL));
@@ -1020,16 +1035,16 @@ prog_start_prologue (struct prog *prog)
pies_priv_setup (&prog->v.p.comp->privs);
if (prog->v.p.comp->umask)
umask (prog->v.p.comp->umask);
-
+
set_limits (prog_tag (prog),
prog->v.p.comp->limits ?
prog->v.p.comp->limits : pies_limits);
-
+
if (debug_level >= 1)
{
int i;
struct component *comp = prog->v.p.comp;
-
+
logmsg_printf (LOG_DEBUG, "executing");
for (i = 0; i < comp->argc; i++)
logmsg_printf (LOG_DEBUG, " %s", quotearg (comp->argv[i]));
@@ -1047,7 +1062,7 @@ prog_execute (struct prog *prog)
prog->v.p.comp->builtin->fun (0, prog->v.p.comp);
_exit (0);
}
-
+
execvp (prog->v.p.comp->program ?
prog->v.p.comp->program : prog->v.p.comp->argv[0],
prog->v.p.comp->argv);
@@ -1077,7 +1092,7 @@ prog_start (struct prog *prog)
pid_t pid;
int redir[2];
fd_set fdset;
-
+
if (prog->pid > 0 || !IS_COMPONENT (prog))
return;
@@ -1123,7 +1138,7 @@ prog_start (struct prog *prog)
if (prog_open_socket (prog))
return;
break;
-
+
case pies_comp_accept:
if (check_spawn_rate (prog))
return;
@@ -1139,9 +1154,9 @@ prog_start (struct prog *prog)
default:
break;
}
-
+
debug (1, (_("starting %s"), prog_tag (prog)));
-
+
if (prog->v.p.comp->rmfile)
{
debug (1, (_("unlinking %s"), prog->v.p.comp->rmfile));
@@ -1158,7 +1173,7 @@ prog_start (struct prog *prog)
redir[RETR_OUT] = open_redirector (prog, RETR_OUT);
redir[RETR_ERR] = open_redirector (prog, RETR_ERR);
-
+
switch (pid = fork ())
{
/* The child branch. */
@@ -1167,22 +1182,22 @@ prog_start (struct prog *prog)
setsid ();
prog_start_prologue (prog);
switch (prog->v.p.comp->mode)
- {
- case pies_comp_accept:
- case pies_comp_inetd:
+ {
+ case pies_comp_accept:
+ case pies_comp_inetd:
prog_sockenv (prog);
- dup2 (prog->v.p.socket, 0);
- dup2 (prog->v.p.socket, 1);
- close (prog->v.p.socket);
+ dup2 (prog->v.p.socket, 0);
+ dup2 (prog->v.p.socket, 1);
+ close (prog->v.p.socket);
prog->v.p.socket = -1;
- break;
+ break;
default:
if (init_process)
{
int fd = console_open (O_RDWR|O_NOCTTY);
- if (fd < 0)
+ if (fd < 0)
{
logmsg (LOG_CRIT, "open(%s): %s",
console_device, strerror (errno));
@@ -1218,8 +1233,8 @@ prog_start (struct prog *prog)
dup2 (redir[RETR_OUT], 1);
}
}
- break;
- }
+ break;
+ }
if (!init_process)
{
@@ -1236,7 +1251,7 @@ prog_start (struct prog *prog)
dup2 (redir[RETR_ERR], 2);
}
}
-
+
/* Close unneeded descripitors */
FD_ZERO (&fdset);
FD_SET (0, &fdset);
@@ -1247,8 +1262,8 @@ prog_start (struct prog *prog)
close_fds (&fdset);
prog_execute (prog);
-
-
+
+
case -1:
logmsg (LOG_CRIT,
_("cannot run `%s': fork failed: %s"),
@@ -1291,14 +1306,14 @@ check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen,
{
struct acl_input input;
int rc;
-
+
if (!acl)
return 0;
input.addr = s;
input.addrlen = salen;
input.identity = identity;
-
+
rc = pies_acl_check (acl, &input, 1);
if (rc == 0)
{
@@ -1315,7 +1330,7 @@ void
fd_report (int fd, const char *msg)
{
size_t len;
-
+
if (!msg)
return;
@@ -1334,7 +1349,7 @@ fd_report (int fd, const char *msg)
len -= rc;
msg += rc;
}
-}
+}
static int
_prog_accept (struct prog *p)
@@ -1344,14 +1359,14 @@ _prog_accept (struct prog *p)
union pies_sockaddr_storage addr;
socklen_t addrlen = sizeof addr;
struct conn_class *pcclass;
-
+
fd = accept (p->v.p.socket, (struct sockaddr*) &addr, &addrlen);
if (fd == -1)
{
logfuncall ("accept", NULL, errno);
return 1;
}
-
+
if (debug_level >= 1)
{
char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
@@ -1394,7 +1409,7 @@ _prog_accept (struct prog *p)
close (fd);
return 1;
}
-
+
if (check_connection_rate (p))
{
disable_socket (p->v.p.socket);
@@ -1447,7 +1462,7 @@ _prog_wait (struct prog *p)
p->v.p.num_instances++;
return 0;
}
-
+
int
progman_accept (int socket, void *data)
{
@@ -1456,7 +1471,7 @@ progman_accept (int socket, void *data)
if (p->v.p.comp->socket_type == SOCK_STREAM
&& !(p->v.p.comp->flags & CF_WAIT))
return _prog_accept (p);
-
+
return _prog_wait (p);
}
@@ -1526,14 +1541,34 @@ 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"));
for (prog = proghead; prog; prog = prog->next)
if (IS_COMPONENT (prog))
@@ -1565,8 +1600,8 @@ check_stopping (struct prog *prog, time_t now)
if (now - prog->v.p.timestamp >= shutdown_timeout)
{
if (prog->pid == 0)
- logmsg (LOG_EMERG,
- _("INTERNAL ERROR: attempting to kill unexisting process %s"),
+ logmsg (LOG_EMERG,
+ _("INTERNAL ERROR: attempting to kill unexisting process %s"),
prog_tag (prog));
else if (prog->v.p.comp->flags & CF_SIGGROUP)
kill (-prog->pid, SIGKILL);
@@ -1625,7 +1660,7 @@ progman_wake_sleeping (int onalrm)
pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM);
}
break;
-
+
case status_stopping:
check_stopping (prog, now);
break;
@@ -1634,7 +1669,7 @@ progman_wake_sleeping (int onalrm)
if (IS_ACTIVE_COMPONENT (prog))
prog_start (prog);
break;
-
+
default:
break;
}
@@ -1647,7 +1682,7 @@ prog_start_prerequisites (struct prog *prog)
pies_depmap_pos_t pos;
struct component *comp;
int warned = 0;
-
+
if (!prog->active)
return 1;
for (comp = component_depmap_first (depmap_col, prog->v.p.comp->arridx, &pos);
@@ -1655,7 +1690,7 @@ prog_start_prerequisites (struct prog *prog)
comp = component_depmap_next (pos))
{
struct prog *p;
-
+
if (!comp->prog || comp->flags & CF_PRECIOUS)
continue;
if (!warned)
@@ -1669,16 +1704,16 @@ prog_start_prerequisites (struct prog *prog)
prog->active = 0;
return 1;
}
-
+
p = comp->prog;
switch (p->v.p.status)
{
case status_running:
continue;
-
+
case status_stopped:
break;
-
+
case status_listener:
continue;
@@ -1700,7 +1735,7 @@ prog_start_prerequisites (struct prog *prog)
ret = 1;
}
depmap_end (pos);
-
+
return ret;
}
@@ -1757,7 +1792,7 @@ prog_stop (struct prog *prog, int sig)
kill (-prog->pid, sig);
else
kill (prog->pid, sig);
-}
+}
static int
mark_for_stopping (struct prog *prog, void *data)
@@ -1787,7 +1822,7 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
}
else
prio = LOG_ERR;
-
+
if (WIFEXITED (status))
{
if (WEXITSTATUS (status) == 0)
@@ -1801,7 +1836,7 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
else if (WIFSIGNALED (status))
{
char const *coremsg = "";
-
+
if (expect_term && WTERMSIG (status) == SIGTERM)
prio = LOG_DEBUG;
@@ -1823,7 +1858,7 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
}
static void propagate_child_exit (pid_t) ATTRIBUTE_NORETURN;
-
+
static void
propagate_child_exit (pid_t pid)
{
@@ -1855,7 +1890,7 @@ wordsplit_string (struct wordsplit const *ws)
char **argv = grecs_calloc (count, sizeof (argv[0]));
size_t i;
size_t len = 0;
-
+
for (i = 0; i < count; i++)
{
argv[i] = quotearg_n (i, ws->ws_wordv[i]);
@@ -1883,7 +1918,7 @@ send_msg (char *rcpts, const char *msg_text)
struct wordsplit ws;
int p[2];
size_t size;
-
+
ws.ws_offs = mailer_argc;
ws.ws_delim = ",";
if (wordsplit (rcpts, &ws,
@@ -1896,7 +1931,7 @@ send_msg (char *rcpts, const char *msg_text)
}
debug (1, (_("sending notification to %s"), rcpts));
-
+
/* Copy mailer arguments */
for (i = 0; i < mailer_argc; i++)
ws.ws_wordv[i] = mailer_argv[i];
@@ -1911,7 +1946,7 @@ send_msg (char *rcpts, const char *msg_text)
{
char *arg = ws.ws_wordv[i];
size_t len;
-
+
while (*arg && c_isblank (*arg))
arg++;
len = strlen (arg);
@@ -1934,10 +1969,10 @@ send_msg (char *rcpts, const char *msg_text)
k++;
}
ws.ws_wordv[k] = NULL;
-
+
/* Fork a child: */
child_pid = fork ();
-
+
if (child_pid < 0)
{
wordsplit_free (&ws);
@@ -1955,7 +1990,7 @@ send_msg (char *rcpts, const char *msg_text)
register_command (mailer_program, cmd, child_pid);
return;
}
-
+
/* Child process */
/* ============= */
signal_setup (SIG_DFL);
@@ -1967,7 +2002,7 @@ send_msg (char *rcpts, const char *msg_text)
wordsplit_free (&ws);
exit (EX_OSERR);
}
-
+
grand_child_pid = fork ();
if (grand_child_pid < 0)
{
@@ -2030,7 +2065,7 @@ notify_get_tag (char **ret, void *data)
if (!s)
return WRDSE_NOSPACE;
*ret = s;
- return WRDSE_OK;
+ return WRDSE_OK;
}
static int
@@ -2039,7 +2074,7 @@ notify_get_termination (char **ret, void *data)
struct notify_closure const *clos = data;
char const *msg;
char *s;
-
+
if (WIFEXITED (clos->status))
/* TRANSLATORS: The subject of this statement is 'component' */
msg = _("exited with code");
@@ -2053,16 +2088,16 @@ notify_get_termination (char **ret, void *data)
if (!s)
return WRDSE_NOSPACE;
*ret = s;
- return WRDSE_OK;
+ return WRDSE_OK;
}
-
+
static int
notify_get_retcode (char **ret, void *data)
{
struct notify_closure const *clos = data;
char *s = NULL;
size_t l = 0;
-
+
if (WIFEXITED (clos->status))
grecs_asprintf (&s, &l, "%d", WEXITSTATUS (clos->status));
else if (WIFSIGNALED (clos->status))
@@ -2072,9 +2107,9 @@ notify_get_retcode (char **ret, void *data)
if (!s)
return WRDSE_NOSPACE;
*ret = s;
- return WRDSE_OK;
-}
-
+ return WRDSE_OK;
+}
+
struct notify_variable
{
char *name;
@@ -2090,7 +2125,7 @@ static struct notify_variable notify_vartab[] = {
#undef S
{ NULL }
};
-
+
static int
notify_getvar (char **ret, const char *vptr, size_t vlen, void *data)
{
@@ -2100,7 +2135,7 @@ notify_getvar (char **ret, const char *vptr, size_t vlen, void *data)
return var->get (ret, data);
return WRDSE_UNDEF;
}
-
+
static void
notify (const char *tag, int status, struct action *act)
{
@@ -2120,7 +2155,7 @@ notify (const char *tag, int status, struct action *act)
closure.tag = tag;
closure.status = status;
closure.act = act;
-
+
env[PROGRAM_NAME_IDX] = program_name;
env[INSTANCE_IDX] = instance;
@@ -2144,7 +2179,7 @@ static int
status_matches_p (struct action *act, unsigned status)
{
int i;
-
+
if (act->nstat == 0)
return 1;
for (i = 0; i < act->nstat; i++)
@@ -2184,7 +2219,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
setenv ("PIES_STATUS", umaxtostr (STATUS_CODE (retcode), buf), 1);
close_fds (NULL);
-
+
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = act->command;
@@ -2208,7 +2243,7 @@ react (struct prog *prog, int status, pid_t pid)
if (!list)
list = default_component.act_list;
-
+
if (WIFEXITED (status))
{
retcode = WEXITSTATUS (status);
@@ -2233,21 +2268,21 @@ react (struct prog *prog, int status, pid_t pid)
for (ep = list->head; ep; ep = ep->next)
{
struct action *act = ep->data;
-
+
if (status_matches_p (act, retcode))
{
if (act->command)
{
run_command (act, prog, retcode, pid);
}
-
+
switch (act->act)
{
case action_restart:
if (prog->v.p.comp->mode != pies_comp_inetd)
prog_start (prog);
break;
-
+
case action_disable:
logmsg (LOG_NOTICE, _("disabling component %s"),
prog_tag (prog));
@@ -2263,7 +2298,7 @@ react (struct prog *prog, int status, pid_t pid)
}
}
}
-
+
if (!list && prog->v.p.comp->mode != pies_comp_inetd)
/* Default action: */
prog_start (prog);
@@ -2294,7 +2329,7 @@ progman_cleanup (int expect_term)
if (prog->v.p.comp->mode == pies_comp_inetd)
{
struct prog *listener = prog->v.p.listener;
-
+
listener->v.p.num_instances--;
if (prog->v.p.cclass)
{
@@ -2307,7 +2342,7 @@ progman_cleanup (int expect_term)
prog->v.p.cclass = NULL;
}
}
-
+
prog_stop_redirectors (prog);
if (listener->v.p.num_instances == 0
&& !component_is_active (prog->v.p.comp))
@@ -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
@@ -2329,7 +2372,7 @@ progman_cleanup (int expect_term)
sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog),
pid, "");
prog->v.p.status = status_finished;
-
+
if (prog->wait)
{
pies_schedule_children (PIES_CHLD_WAKEUP);
@@ -2351,7 +2394,7 @@ progman_cleanup (int expect_term)
if (!component_is_active (prog->v.p.comp))
destroy_prog (&prog);
}
-
+
break;
case TYPE_REDIRECTOR:
@@ -2371,7 +2414,7 @@ progman_cleanup (int expect_term)
break;
}
}
-
+
if (!expect_term)
/* This will also recompute alarm settings, if necessary */
progman_wake_sleeping (0);
@@ -2389,7 +2432,7 @@ progman_stop_component (struct prog **progptr)
logmsg (LOG_INFO, _("stopping component %s"), prog_tag (prog));
prog_stop (prog, SIGTERM);
break;
-
+
case status_listener:
prog_deactivate_listener (prog);
/* fall through */
@@ -2413,7 +2456,7 @@ progman_stop_component (struct prog **progptr)
case status_stopping:
break;
-
+
case status_finished:
prog->stop = 0;
if (!component_is_active (prog->v.p.comp))
@@ -2441,7 +2484,7 @@ int
prog_activate_listener (struct prog *prog)
{
struct component *comp = prog->v.p.comp;
-
+
logmsg (LOG_INFO, _("activating listener %s"), prog_tag (prog));
if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags)
&& prog->v.p.socket == -1)
@@ -2535,9 +2578,9 @@ progman_gc (void)
else
break;
}
-
+
/* FIXME: Report remaining programs */
-
+
}
-
+
/* EOF */

Return to:

Send suggestions and report system problems to the System administrator.