diff options
Diffstat (limited to 'src/progman.c')
-rw-r--r-- | src/progman.c | 538 |
1 files changed, 190 insertions, 348 deletions
diff --git a/src/progman.c b/src/progman.c index 0079149..4f63d9a 100644 --- a/src/progman.c +++ b/src/progman.c @@ -17,9 +17,7 @@ #include "pies.h" #include "prog.h" -static size_t numcomp; static struct prog *proghead, *progtail; -static pies_depmap_t depmap; static int recompute_alarm; static struct grecs_symtab *conn_tab; @@ -29,7 +27,7 @@ progman_locate (const char *name) struct prog *prog; for (prog = proghead; prog; prog = prog->next) - if (strcmp (prog->tag, name) == 0) + if (strcmp (prog_tag (prog), name) == 0) break; return prog; } @@ -73,7 +71,7 @@ prog_lookup_by_tag (const char *tag) { struct prog *prog; for (prog = proghead; prog; prog = prog->next) - if (strcmp (prog->tag, tag) == 0) + if (strcmp (prog_tag (prog), tag) == 0) break; return prog; } @@ -95,7 +93,7 @@ progman_lookup_component (const char *tag) { struct prog *prog; for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog) && strcmp (prog->tag, tag) == 0) + if (IS_COMPONENT (prog) && strcmp (prog_tag (prog), tag) == 0) return prog->v.p.comp; return NULL; } @@ -129,6 +127,23 @@ prog_lookup_by_idx (unsigned idx) void prog_stop (struct prog *prog, int sig); static int prog_start_prerequisites (struct prog *prog); +char const * +prog_tag (struct prog const *prog) +{ + switch (prog->type) + { + case TYPE_COMPONENT: + return prog->v.p.comp->tag; + + case TYPE_REDIRECTOR: + return prog->v.r.tag; + + case TYPE_COMMAND: + return prog->v.c.tag; + } + abort (); + } + void link_prog (struct prog *pp, int prepend) { @@ -158,6 +173,7 @@ void unlink_prog (struct prog *pp) { struct prog *x; + if ((x = pp->prev)) x->next = pp->next; else @@ -172,28 +188,35 @@ 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) + deregister_socket (p->v.p.socket); break; - + case TYPE_REDIRECTOR: { struct prog *master = p->v.r.master; + component_ref_decr (master->v.p.comp); if (p == master->v.p.redir[0]) master->v.p.redir[0] = NULL; else if (p == master->v.p.redir[1]) master->v.p.redir[1] = NULL; /* else logmsg (LOG_NOTICE, _("orphan redirector: %s"), p->tag);*/ + free (p->v.r.tag); } break; - + case TYPE_COMMAND: + free (p->v.c.tag); free (p->v.c.command); } - unlink_prog (*pp); - free (*pp); + free (p); *pp = NULL; } @@ -203,10 +226,11 @@ redir_tag (struct prog *master, int type) static char *redirstr[2] = { "stdout", "stderr" }; char *str = NULL; size_t len = 0; + char const *tag = prog_tag (master); if (type < ARRAY_SIZE(redirstr)) - grecs_asprintf (&str, &len, "%s/%s", master->tag, redirstr[type]); + grecs_asprintf (&str, &len, "%s/%s", tag, redirstr[type]); else - grecs_asprintf (&str, &len, "%s/%d", master->tag, type); + grecs_asprintf (&str, &len, "%s/%d", tag, type); return str; } @@ -214,21 +238,13 @@ static struct prog * register_redir (int type, struct prog *master) { char *tag = redir_tag (master, type); - char *pstr; - struct prog *pp = grecs_zalloc (sizeof (*pp) + strlen (tag) + 1 + - 2 * sizeof (char**)); + struct prog *pp = grecs_zalloc (sizeof (*pp)); pp->type = TYPE_REDIRECTOR; - pstr = (char *) (pp + 1); - pp->tag = pstr; - strcpy (pp->tag, tag); - pstr += strlen (pp->tag) + 1; - free (tag); + pp->v.r.tag = tag; pp->v.r.master = master; - pp->prereq = (char**)pstr; - pp->prereq[0] = master->tag; - pp->prereq[1] = NULL; link_prog (pp, 1); + component_ref_incr (master->v.p.comp); return pp; } @@ -248,17 +264,15 @@ update_redir (int type, struct prog *master, pid_t pid) } static struct prog * -register_prog0 (struct component *comp, unsigned index) +register_prog0 (struct component *comp) { struct prog *newp; newp = grecs_zalloc (sizeof (*newp)); newp->type = TYPE_COMPONENT; - newp->tag = comp->tag; newp->pid = 0; newp->facility = comp->facility; newp->v.p.comp = comp; - newp->v.p.idx = index; newp->v.p.socket = -1; if (comp->flags & CF_DISABLED) newp->v.p.status = status_disabled; @@ -269,13 +283,14 @@ register_prog0 (struct component *comp, unsigned index) comp->redir[RETR_OUT].type = redir_null; link_prog (newp, 0); + component_ref_incr (comp); return newp; } void register_prog (struct component *comp) { - register_prog0 (comp, numcomp++); + comp->prog = register_prog0 (comp); } void @@ -283,66 +298,12 @@ register_command (char *tag, char *command, pid_t pid) { struct prog *newp = grecs_zalloc (sizeof (*newp)); newp->type = TYPE_COMMAND; - newp->tag = tag; newp->pid = pid; + newp->v.c.tag = grecs_strdup (tag); newp->v.c.command = command; link_prog (newp, 0); } -void -prog_rebuild_prerequisites (struct prog *prog) -{ - struct component *comp = prog->v.p.comp; - struct prog *p; - int dep_all = 0; - size_t depc = 0; - - if (comp->prereq) - { - depc = grecs_list_size (comp->prereq); - if (depc == 1) - { - const char *item = grecs_list_index (comp->prereq, 0); - if (strcmp (item, "all") == 0) - { - dep_all = 1; - for (p = proghead; p; p = p->next) - if (p->type == TYPE_COMPONENT) - depc++; - } - else if (strcmp (item, "none") == 0) - { - grecs_list_free (comp->prereq); - comp->prereq = NULL; - } - } - } - - if (depc == 0) - return; - - prog->prereq = grecs_calloc (depc + 1, sizeof (prog->prereq[0])); - - depc = 0; - if (comp->prereq) - { - if (dep_all) - { - for (p = proghead; p; p = p->next) - if (p->type == TYPE_COMPONENT) - prog->prereq[depc++] = p->tag; - } - else - { - struct grecs_list_entry *ep; - - for (ep = comp->prereq->head; ep; ep = ep->next) - prog->prereq[depc++] = (char*) ep->data; - } - } - prog->prereq[depc] = NULL; -} - int progman_running_p () { @@ -473,7 +434,7 @@ open_redirector (struct prog *master, int stream) fp = fdopen (p[0], "r"); if (fp == NULL) _exit (1); - openlog (master->tag, LOG_PID, master->facility); + openlog (prog_tag (master), LOG_PID, master->facility); prio = master->v.p.comp->redir[stream].v.prio; while (getline (&buf, &size, fp) > 0) syslog (prio, "%s", buf); @@ -482,12 +443,12 @@ open_redirector (struct prog *master, int stream) case -1: logmsg (LOG_CRIT, _("cannot run redirector `%s': fork failed: %s"), - master->tag, strerror (errno)); + prog_tag (master), strerror (errno)); return -1; default: debug (1, (_("redirector for %s started, pid=%lu"), - master->tag, (unsigned long) pid)); + prog_tag (master), (unsigned long) pid)); update_redir (stream, master, pid); close (p[0]); return p[1]; @@ -956,7 +917,7 @@ check_spawn_rate (struct prog *prog) ngettext ("%s is respawning too fast, disabled for %d minute", "%s is respawning too fast, disabled for %d minutes", SLEEPTIME / 60), - prog->tag, SLEEPTIME / 60); + prog_tag (prog), SLEEPTIME / 60); return 1; } return 0; @@ -973,7 +934,7 @@ check_connection_rate (struct prog *prog) ngettext ("%s is starting too often, disabled for %d minute", "%s is starting too often, disabled for %d minutes", SLEEPTIME / 60), - prog->tag, SLEEPTIME / 60); + prog_tag (prog), SLEEPTIME / 60); return 1; } return 0; @@ -1011,7 +972,7 @@ prog_start_prologue (struct prog *prog) debug (1, (_("chdir %s"), prog->v.p.comp->dir)); if (chdir (prog->v.p.comp->dir)) logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"), - prog->tag, prog->v.p.comp->dir, strerror (errno)); + prog_tag (prog), prog->v.p.comp->dir, strerror (errno)); } environ_setup (prog->v.p.comp->env ? @@ -1025,7 +986,7 @@ prog_start_prologue (struct prog *prog) if (prog->v.p.comp->umask) umask (prog->v.p.comp->umask); - set_limits (prog->tag, + set_limits (prog_tag (prog), prog->v.p.comp->limits ? prog->v.p.comp->limits : pies_limits); @@ -1057,7 +1018,7 @@ prog_execute (struct prog *prog) prog->v.p.comp->program : prog->v.p.comp->argv[0], prog->v.p.comp->argv); openlog (log_tag, LOG_PID, prog->v.p.comp->facility); - syslog (LOG_CRIT, _("cannot start `%s': %s"), prog->tag, + syslog (LOG_CRIT, _("cannot start `%s': %s"), prog_tag (prog), strerror (errno)); _exit (EX_SOFTWARE); } @@ -1066,7 +1027,7 @@ void progman_run_comp (struct component *comp, int fd, union pies_sockaddr_storage *sa, socklen_t salen) { - struct prog *prog = register_prog0 (comp, -1); + struct prog *prog = register_prog0 (comp); prog->v.p.socket = fd; prog->v.p.sa_storage = *sa; prog->v.p.sa_len = salen; @@ -1093,7 +1054,7 @@ prog_start (struct prog *prog) if (prog->v.p.status != status_disabled) { logmsg (LOG_NOTICE, "disabling sysvinit component %s", - prog->tag); + prog_tag (prog)); prog->v.p.status = status_disabled; } return; @@ -1147,14 +1108,14 @@ prog_start (struct prog *prog) break; } - debug (1, (_("starting %s"), prog->tag)); + debug (1, (_("starting %s"), prog_tag (prog))); if (prog->v.p.comp->rmfile) { debug (1, (_("unlinking %s"), prog->v.p.comp->rmfile)); if (unlink (prog->v.p.comp->rmfile) && errno != ENOENT) logmsg (LOG_ERR, _("%s: cannot remove file `%s': %s"), - prog->tag, prog->v.p.comp->rmfile, strerror (errno)); + prog_tag (prog), prog->v.p.comp->rmfile, strerror (errno)); } if (prog->v.p.comp->builtin && prog->v.p.comp->builtin->single_process) @@ -1259,7 +1220,7 @@ prog_start (struct prog *prog) case -1: logmsg (LOG_CRIT, _("cannot run `%s': fork failed: %s"), - prog->tag, strerror (errno)); + prog_tag (prog), strerror (errno)); break; default: @@ -1279,7 +1240,7 @@ prog_start (struct prog *prog) prog->v.p.comp->mode == pies_comp_pass_fd) close (prog->v.p.socket); else if (is_sysvinit (prog->v.p.comp)) - sysvinit_acct (SYSV_ACCT_PROC_START, "", prog->tag, pid, ""); + sysvinit_acct (SYSV_ACCT_PROC_START, "", prog_tag (prog), pid, ""); if (redir[RETR_OUT] != -1) close (redir[RETR_OUT]); @@ -1287,7 +1248,8 @@ prog_start (struct prog *prog) close (redir[RETR_ERR]); prog->pid = pid; prog->v.p.status = status_enabled; - debug (1, (_("%s started, pid=%lu"), prog->tag, (unsigned long) pid)); + debug (1, (_("%s started, pid=%lu"), prog_tag (prog), + (unsigned long) pid)); } } @@ -1361,7 +1323,7 @@ _prog_accept (struct prog *p) if (debug_level >= 1) { char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen); - logmsg (LOG_DEBUG, _("%s wants %s"), s, p->tag); + logmsg (LOG_DEBUG, _("%s wants %s"), s, prog_tag (p)); free (s); } @@ -1379,14 +1341,14 @@ _prog_accept (struct prog *p) char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen); logmsg (LOG_ERR, _("%s: access from %s denied: too many instances running"), - p->tag, s); + prog_tag (p), s); free (s); fd_report (fd, p->v.p.comp->max_instances_message); close (fd); return 1; } - pcclass = conn_class_lookup (p->tag, &addr, addrlen); + pcclass = conn_class_lookup (prog_tag (p), &addr, addrlen); if (p->v.p.comp->max_ip_connections && pcclass->count >= p->v.p.comp->max_ip_connections) { @@ -1394,7 +1356,7 @@ _prog_accept (struct prog *p) logmsg (LOG_ERR, _("%s: access from %s denied: " "too many connections from that ip"), - p->tag, s); + prog_tag (p), s); free (s); fd_report (fd, p->v.p.comp->max_ip_connections_message); close (fd); @@ -1413,7 +1375,7 @@ _prog_accept (struct prog *p) if (debug_level > 1) conn_class_report (LOG_DEBUG, pcclass); - pinst = register_prog0 (p->v.p.comp, -1); + pinst = register_prog0 (p->v.p.comp); pinst->v.p.socket = fd; pinst->v.p.listener = p; pinst->v.p.sa_storage = addr; @@ -1432,18 +1394,18 @@ _prog_wait (struct prog *p) { struct prog *pinst; - debug (1, (_("someone wants %s"), p->tag)); + debug (1, (_("someone wants %s"), prog_tag (p))); if (p->v.p.comp->max_instances && p->v.p.num_instances >= p->v.p.comp->max_instances) { logmsg (LOG_ERR, _("%s: too many instances running, dropping connection"), - p->tag); + prog_tag (p)); return 1; } - pinst = register_prog0 (p->v.p.comp, -1); + pinst = register_prog0 (p->v.p.comp); pinst->v.p.socket = p->v.p.socket; pinst->v.p.listener = p; prog_start (pinst); @@ -1465,164 +1427,6 @@ progman_accept (int socket, void *data) return _prog_wait (p); } - - -void -component_fixup_depend (struct component *comp) -{ - struct grecs_list_entry *ep; - - if (comp->depend == NULL) - return; - - for (ep = comp->depend->head; ep; ep = ep->next) - { - const char *tag = ep->data; - struct component *tgt; - - tgt = progman_lookup_component (tag); - if (!tgt) - { - logmsg (LOG_ERR, - _("component %s declares dependency target %s, " - "which is not declared"), - comp->tag, tag); - continue; - } - if (!tgt->prereq) - { - tgt->prereq = grecs_list_create(); - } - /* FIXME: memory allocation */ - grecs_list_append (tgt->prereq, grecs_strdup (comp->tag)); - } - grecs_list_free (comp->depend); - comp->depend = NULL; -} - -void -fixup_prerequisites () -{ - struct prog *prog; - - for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog)) - component_fixup_depend (prog->v.p.comp); -} - -void -rebuild_prerequisites () -{ - struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog)) - prog_rebuild_prerequisites (prog); -} - -void -print_dep (struct prog *prog) -{ - pies_depmap_pos_t pos; - size_t n; - - logmsg_printf (LOG_NOTICE, "%s -> ", prog->tag); - for (n = depmap_first (depmap, depmap_col, prog->v.p.idx, &pos); - n != (size_t)-1; - n = depmap_next (depmap, pos)) - { - struct prog *dp = prog_lookup_by_idx (n); - logmsg_printf (LOG_NOTICE, "%s -> ", dp->tag); - } - depmap_end (pos); - logmsg_printf (LOG_NOTICE, "%s\n", prog->tag); -} - -void -progman_dump_prereq () -{ - struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (prog->prereq) - { - int i; - printf ("%s:", prog->tag); - for (i = 0; prog->prereq[i]; i++) - printf (" %s", prog->prereq[i]); - printf ("\n"); - } -} - -void -progman_dump_depmap () -{ - struct prog *prog; - size_t i, j; - - printf ("%s:\n", _("Dependency map")); - printf (" "); - for (i = 0; i < numcomp; i++) - printf (" %2lu", (unsigned long)i); - printf ("\n"); - for (i = 0; i < numcomp; i++) - { - printf ("%2lu ", (unsigned long)i); - for (j = 0; j < numcomp; j++) - printf (" %c ", depmap_isset (depmap, i, j) ? 'X' : ' '); - printf ("\n"); - } - printf ("\n%s:\n", _("Legend")); - for (i = 0; i < numcomp; i++) - { - prog = prog_lookup_by_idx (i); - if (prog) - printf ("%2lu: %s\n", (unsigned long)i, prog->tag); - } -} - -int -progman_build_depmap () -{ - int rc = 0; - size_t i; - struct prog *prog; - pies_depmap_t dp; - - fixup_prerequisites (); - rebuild_prerequisites (); - depmap = depmap_alloc (numcomp); - for (prog = proghead; prog; prog = prog->next) - if (prog->prereq) - { - for (i = 0; prog->prereq[i]; i++) - { - struct prog *dep = prog_lookup_by_tag (prog->prereq[i]); - if (!dep) - { - prog->v.p.status = status_disabled; - logmsg (LOG_ERR, _("component %s depends on %s, " - "which is not declared"), - prog->tag, prog->prereq[i]); - rc++; - } - else - depmap_set (depmap, prog->v.p.idx, dep->v.p.idx); - } - } - dp = depmap_copy (depmap); - depmap_tc (dp); - for (i = 0; i < numcomp; i++) - if (depmap_isset (dp, i, i)) - { - prog = prog_lookup_by_idx (i); - logmsg (LOG_ERR, _("component %s depends on itself"), prog->tag); - print_dep (prog); - prog->v.p.status = status_disabled; - rc++; - } - free (dp); - return rc; -} - void progman_create_sockets () @@ -1634,7 +1438,8 @@ progman_create_sockets () if (IS_COMPONENT (prog)) { struct component *comp = prog->v.p.comp; - if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags)) + if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags) + && prog->v.p.socket == -1) { int fd = create_socket (comp->socket_url, comp->socket_type, @@ -1725,7 +1530,7 @@ check_stopping (struct prog *prog, time_t now) if (prog->pid == 0) logmsg (LOG_EMERG, _("INTERNAL ERROR: attempting to kill unexisting process %s"), - prog->tag); + prog_tag (prog)); else if (prog->v.p.comp->flags & CF_SIGGROUP) kill (-prog->pid, SIGKILL); else @@ -1790,23 +1595,28 @@ progman_wake_sleeping (int onalrm) static int prog_start_prerequisites (struct prog *prog) { - int i; - int ret; - + int ret = 0; + pies_depmap_pos_t pos; + struct component *comp; + int warned = 0; + if (prog->v.p.status == status_disabled) return 1; - if (!prog->prereq) - return 0; /* Ok to startup */ - debug (1, ("starting prerequisites of %s", prog->tag)); - ret = 0; - for (i = 0; prog->prereq[i]; i++) - { - struct prog *dp = prog_lookup_by_tag (prog->prereq[i]); - if (!IS_COMPONENT (dp)) /* Skip redirectors */ - continue; - if (prog->v.p.comp->flags & CF_PRECIOUS) + for (comp = component_depmap_first (depmap_col, prog->v.p.comp->arridx, &pos); + comp; + comp = component_depmap_next (pos)) + { + struct prog *p; + + if (!comp->prog || comp->flags & CF_PRECIOUS) continue; - switch (dp->v.p.status) + if (!warned) + { + debug (1, ("starting prerequisites of %s", prog_tag (prog))); + warned = 1; + } + p = comp->prog; + switch (p->v.p.status) { case status_enabled: if (prog->pid != 0) @@ -1825,18 +1635,20 @@ prog_start_prerequisites (struct prog *prog) break; case status_stopping: - check_stopping (dp, time (NULL)); + check_stopping (p, time (NULL)); ret = 1; continue; case status_finished: continue; } - prog_start (dp); - if (dp->v.p.comp->mode == pies_comp_once || - !(dp->v.p.status == status_enabled && dp->pid)) + prog_start (p); + if (p->v.p.comp->mode == pies_comp_once || + !(p->v.p.status == status_enabled && p->pid)) ret = 1; } + depmap_end (pos); + return ret; } @@ -1852,21 +1664,21 @@ prog_stop_redirectors (struct prog *prog) void prog_stop_dependents (struct prog *prog) { + struct component *comp; pies_depmap_pos_t pos; - size_t n; int warned = 0; prog_stop_redirectors (prog); - for (n = depmap_first (depmap, depmap_row, prog->v.p.idx, &pos); - n != (size_t)-1; - n = depmap_next (depmap, pos)) + for (comp = component_depmap_first (depmap_row, prog->v.p.comp->arridx, &pos); + comp; + comp = component_depmap_next (pos)) { - struct prog *dp = prog_lookup_by_idx (n); + struct prog *dp = comp->prog; if (!dp) /* should not happen */ continue; if (!warned && dp->pid) { - debug (1, ("stopping dependencies of %s", prog->tag)); + debug (1, ("stopping dependencies of %s", prog_tag (prog))); warned = 1; } prog_stop (dp, SIGTERM); @@ -1888,7 +1700,7 @@ prog_stop (struct prog *prog, int sig) recompute_alarm = 1; } } - debug (1, ("stopping %s (%lu)", prog->tag, (unsigned long) prog->pid)); + debug (1, ("stopping %s (%lu)", prog_tag (prog), (unsigned long) prog->pid)); if (prog->type == TYPE_COMPONENT && prog->v.p.comp->flags & CF_SIGGROUP) kill (-prog->pid, sig); else @@ -1908,15 +1720,15 @@ prog_stop_all (int sig) prog_stop (prog, sig); } -static int -progman_wait () +int +progman_wait_until (int (*cond) (void *), void *data) { time_t start = time (NULL); do { progman_cleanup (1); - if (progman_running_count () == 0) + if (cond && cond (data)) return 0; sleep (1); } @@ -1924,14 +1736,20 @@ progman_wait () return 1; } +static int +no_children_left (void *p) +{ + return progman_running_count () == 0; +} + void progman_stop () { prog_stop_all (SIGTERM); - if (progman_wait ()) + if (progman_wait_until (no_children_left, NULL)) { prog_stop_all (SIGKILL); - progman_wait (); + progman_wait_until (no_children_left, NULL); } } @@ -2337,7 +2155,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode, /* Child */ setsid (); setenv ("PIES_VERSION", PACKAGE_VERSION, 1); - setenv ("PIES_COMPONENT", prog->tag, 1); + setenv ("PIES_COMPONENT", prog_tag (prog), 1); setenv ("PIES_PID", umaxtostr (child_pid, buf), 1); if (retcode & STATUS_SIG_BIT) setenv ("PIES_SIGNAL", umaxtostr (STATUS_CODE (retcode), buf), 1); @@ -2365,60 +2183,67 @@ static void react (struct prog *prog, int status, pid_t pid) { unsigned retcode; - struct action *act = prog->v.p.comp->act_head; - - if (!act) - act = default_component.act_head; + struct grecs_list *list = prog->v.p.comp->act_list; + + if (!list) + list = default_component.act_list; if (WIFEXITED (status)) { retcode = WEXITSTATUS (status); - debug (1, (_("%s: terminated with code %d"), prog->tag, retcode)); + debug (1, (_("%s: terminated with code %d"), prog_tag (prog), retcode)); } else if (WIFSIGNALED (status)) { retcode = WTERMSIG (status); - debug (1, (_("%s: terminated on signal %d"), prog->tag, retcode)); + debug (1, (_("%s: terminated on signal %d"), prog_tag (prog), retcode)); retcode |= STATUS_SIG_BIT; } else { - debug (1, (_("%s: unrecognized termination status"), prog->tag)); + debug (1, (_("%s: unrecognized termination status"), prog_tag (prog))); /* Enforce default action: */ - act = NULL; + list = NULL; } - - for (; act; act = act->next) + + if (list) { - if (status_matches_p (act, retcode)) + struct grecs_list_entry *ep; + for (ep = list->head; ep; ep = ep->next) { - if (act->command) + struct action *act = ep->data; + + if (status_matches_p (act, retcode)) { - run_command (act, prog, retcode, pid); - } + 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; + 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->v.p.status = status_disabled; - /* FIXME: - if (prog->v.p.comp->mode == pies_comp_inetd) - disable_socket (prog->v.p.socket); - */ + case action_disable: + logmsg (LOG_NOTICE, _("disabling component %s"), + prog_tag (prog)); + prog->v.p.status = status_disabled; + /* FIXME: + if (prog->v.p.comp->mode == pies_comp_inetd) + disable_socket (prog->v.p.socket); + */ + } + if (act->addr) + notify (prog_tag (prog), status, act); + break; } - if (act->addr) - notify (prog->tag, status, act); - break; } } - if (!act && prog->v.p.comp->mode != pies_comp_inetd) + if (!list && prog->v.p.comp->mode != pies_comp_inetd) /* Default action: */ prog_start (prog); } @@ -2441,7 +2266,7 @@ progman_cleanup (int expect_term) switch (prog->type) { case TYPE_COMPONENT: - print_status (prog->tag, pid, status, expect_term); + print_status (prog_tag (prog), pid, status, expect_term); if (prog->v.p.comp->mode == pies_comp_inetd) { struct prog *listener = prog->v.p.listener; @@ -2461,41 +2286,58 @@ progman_cleanup (int expect_term) prog_stop_redirectors (prog); destroy_prog (&prog); - react (listener, status, pid); - if (listener->v.p.comp->flags & CF_WAIT) - enable_socket (listener->v.p.socket); - } - else if (prog->v.p.comp->mode >= pies_mark_sysvinit) - { - sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog->tag, pid, ""); - prog->v.p.status = status_finished; + if (listener->v.p.num_instances == 0 + && !component_is_active (prog->v.p.comp)) + destroy_prog (&listener); + else + { + if (!expect_term) + react (listener, status, pid); + if (listener->v.p.comp->flags & CF_WAIT) + enable_socket (listener->v.p.socket); + } } else { - if (is_sysvinit (prog->v.p.comp)) - sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog->tag, pid, ""); + if (prog->v.p.comp->mode >= pies_mark_sysvinit) + { + sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog), + pid, ""); + prog->v.p.status = status_finished; + } + else + { + if (is_sysvinit (prog->v.p.comp)) + sysvinit_acct (SYSV_ACCT_PROC_STOP, "", + prog_tag (prog), pid, ""); - prog->v.p.status = (prog->v.p.comp->flags & CF_DISABLED) + prog->v.p.status = + (prog->v.p.comp->flags & CF_DISABLED) ? status_disabled : status_enabled; - prog_stop_dependents (prog); - if (!expect_term) - react (prog, status, pid); + prog_stop_dependents (prog); + if (!expect_term) + react (prog, status, pid); + } + + if (!component_is_active (prog->v.p.comp)) + destroy_prog (&prog); } + break; case TYPE_REDIRECTOR: /* It was a redirector of an already finished process. */ - print_status (prog->tag, pid, status, + print_status (prog_tag (prog), pid, status, expect_term || (prog->v.r.master && prog->v.r.master->v.p.status == status_stopping)); debug (1, (_("removing redirector %s, pid=%lu"), - prog->tag, (unsigned long)pid)); + prog_tag (prog), (unsigned long)pid)); destroy_prog (&prog); break; case TYPE_COMMAND: - print_status (prog->tag, pid, status, expect_term); + print_status (prog_tag (prog), pid, status, expect_term); destroy_prog (&prog); break; } @@ -2515,27 +2357,27 @@ progman_stop_component (struct prog *prog) { case status_enabled: case status_listener: - logmsg (LOG_INFO, _("stopping component `%s'"), prog->tag); + logmsg (LOG_INFO, _("stopping component `%s'"), prog_tag (prog)); prog_stop (prog, SIGTERM); break; case status_disabled: if (!(prog->v.p.comp->flags & CF_DISABLED)) { - logmsg (LOG_INFO, _("enabling component `%s'"), prog->tag); + logmsg (LOG_INFO, _("enabling component `%s'"), prog_tag (prog)); prog->v.p.status = status_enabled; } break; case status_sleeping: - logmsg (LOG_INFO, _("waking up component `%s'"), prog->tag); + logmsg (LOG_INFO, _("waking up component `%s'"), prog_tag (prog)); prog->v.p.failcount = 0; break; default: logmsg (LOG_INFO, _("stopping component `%s': component not started"), - prog->tag); + prog_tag (prog)); } } } |