diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-02-23 18:04:52 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-02-23 18:04:52 +0200 |
commit | dd2c48ddfc7f8bc62c565b43bbd42a3a2a87836d (patch) | |
tree | c160c3d7af3a7709fb33224e8344caafe581fcc4 /src | |
parent | 6e73a7b0822d1fd506c75a662070f447bba94afb (diff) | |
download | pies-dd2c48ddfc7f8bc62c565b43bbd42a3a2a87836d.tar.gz pies-dd2c48ddfc7f8bc62c565b43bbd42a3a2a87836d.tar.bz2 |
Bugfixes
* lib/addrfmt.c: Include limits.h
* src/ctl.c (fun_stop,fun_start): Ignore non-component
progs.
* src/pies.c (request_restart_components): Fix piesctl
invocation.
* src/pies.h (PIES_CHLD_RESCHEDULE_ALARM): New flag.
(progman_wait_until): Remove.
(progman_recompute_alarm): New proto.
* src/progman.c (recompute_alarm): Remove. All uses
raise PIES_CHLD_RESCHEDULE_ALARM instead.
(progman_wake_sleeping): Handle status_stopping components
independently on their activity flag.
(prog_stop_all, progman_wait_until): Remove.
(progman_stop): Rewrite using mark+sweep approach.
Diffstat (limited to 'src')
-rw-r--r-- | src/ctl.c | 32 | ||||
-rw-r--r-- | src/pies.c | 17 | ||||
-rw-r--r-- | src/pies.h | 11 | ||||
-rw-r--r-- | src/progman.c | 91 |
4 files changed, 67 insertions, 84 deletions
@@ -1907,28 +1907,42 @@ fun_list (struct json_value *result, struct prog *prog) return 0; } static int fun_stop (struct json_value *result, struct prog *prog) { - if (!prog->v.p.active) - { - json_object_set_string (result, "status", "ER"); - json_object_set_string (result, "error_message", "already stopped"); - return 1; + if (IS_COMPONENT (prog)) + { + if (!prog->v.p.active) + { + json_object_set_string (result, "status", "ER"); + json_object_set_string (result, "error_message", "already stopped"); + return 1; + } + + prog->v.p.active = 0; + progman_stop_component (&prog); + json_object_set_string (result, "status", "OK"); + } + else + { + //FIXME progman_stop_component (&prog); + json_object_set_string (result, "status", "OK"); } - - prog->v.p.active = 0; - progman_stop_component (&prog); - json_object_set_string (result, "status", "OK"); return 0; } static int fun_start (struct json_value *result, struct prog *prog) { + if (!IS_COMPONENT (prog)) + { + json_object_set_string (result, "status", "ER"); + json_object_set_string (result, "error_message", "not a component"); + return 1; + } switch (prog->v.p.status) { case status_stopped: prog->v.p.comp->flags &= ~CF_DISABLED; json_object_set_string (result, "status", "OK"); break; @@ -1766,21 +1766,28 @@ pies_check_status (pid_t *ppid) #define pies_control_url() control.url->string int request_restart_components (size_t cc, char **cv) { char **argv; - size_t i; + size_t i, j; - argv = grecs_calloc (cc + 4, sizeof (*argv)); + 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++) - argv[3 + i] = cv[i]; - argv[3 + i] = NULL; + { + 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 @@ -2276,12 +2283,14 @@ main (int argc, char **argv) sysvinit_power (); pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; } if (action == ACTION_CONT) { + if (children_op & PIES_CHLD_RESCHEDULE_ALARM) + progman_recompute_alarm (); if (children_op & PIES_CHLD_GC) progman_gc (); if (children_op & PIES_CHLD_CLEANUP) progman_cleanup (0); if (children_op & PIES_CHLD_WAKEUP) progman_wake_sleeping (1); @@ -317,16 +317,17 @@ void config_file_remove_all (void); void free_redirector (struct redirector *rp); void pies_schedule_action (int act); void free_action (struct action *act); -#define PIES_CHLD_NONE 0 -#define PIES_CHLD_CLEANUP 0x01 -#define PIES_CHLD_WAKEUP 0x02 -#define PIES_CHLD_GC 0x04 +#define PIES_CHLD_NONE 0 +#define PIES_CHLD_CLEANUP 0x01 +#define PIES_CHLD_WAKEUP 0x02 +#define PIES_CHLD_GC 0x04 +#define PIES_CHLD_RESCHEDULE_ALARM 0x08 void pies_schedule_children (int op); int pies_read_config (void); void register_prog (struct component *comp); @@ -335,22 +336,22 @@ void progman_start (void); void progman_gc (void); void progman_wake_sleeping (int); void progman_stop (void); void progman_cleanup (int expect_term); void progman_filter (int (*filter) (struct component *, void *data), void *data); -int progman_wait_until (int (*cond) (void *), void *data); int progman_accept (int socket, void *data); void progman_create_sockets (void); struct component *progman_lookup_component (const char *tag); struct component *progman_lookup_tcpmux (const char *service, const char *master); void progman_run_comp (struct component *comp, int fd, union pies_sockaddr_storage *sa, socklen_t salen); +void progman_recompute_alarm (void); void fd_report (int fd, const char *msg); int check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen, pies_identity_t identity); diff --git a/src/progman.c b/src/progman.c index 547f806..2d3a14c 100644 --- a/src/progman.c +++ b/src/progman.c @@ -15,13 +15,12 @@ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" #include "prog.h" static struct prog *proghead, *progtail; -static int recompute_alarm; static struct grecs_symtab *conn_tab; struct prog * progman_locate (const char *name) { struct prog *prog; @@ -905,13 +904,13 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count) } if (prog->v.p.failcount > max_count) { prog->v.p.timestamp = now; prog->v.p.status = status_sleeping; - recompute_alarm = 1; + pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM); return 1; } return 0; } @@ -1468,13 +1467,12 @@ void progman_recompute_alarm () { struct prog *prog; time_t now = time (NULL); time_t alarm_time = 0, x; - recompute_alarm = 0; debug (2, ("Recomputing alarm settings")); for (prog = proghead; prog; prog = prog->next) if (IS_COMPONENT (prog)) { switch (prog->v.p.status) { @@ -1505,13 +1503,12 @@ progman_start () struct prog *prog; if (progman_waiting_p ()) /* Noting to do if there are processes left in the previous runlevel */ return; - recompute_alarm = 0; debug (1, ("starting components")); for (prog = proghead; prog; prog = prog->next) if (IS_COMPONENT (prog)) { switch (prog->v.p.status) { @@ -1546,13 +1543,13 @@ check_stopping (struct prog *prog, time_t now) else if (prog->v.p.comp->flags & CF_SIGGROUP) kill (-prog->pid, SIGKILL); else kill (prog->pid, SIGKILL); } else - recompute_alarm = 1; + pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM); } void progman_wake_sleeping (int onalrm) { struct prog *prog; @@ -1571,17 +1568,17 @@ progman_wake_sleeping (int onalrm) prog_start (prog); return; } } for (prog = proghead; prog; prog = prog->next) - if (IS_ACTIVE_COMPONENT (prog)) + switch (prog->v.p.status) { - switch (prog->v.p.status) + case status_sleeping: + if (IS_ACTIVE_COMPONENT (prog)) { - case status_sleeping: if (now - prog->v.p.timestamp >= SLEEPTIME) { if (prog->v.p.comp->mode == pies_comp_inetd) { prog->v.p.status = status_listener; enable_socket (prog->v.p.socket); @@ -1594,29 +1591,28 @@ progman_wake_sleeping (int onalrm) prog_start (prog); } } /* If there is no alarm pending, recompute next alarm. This allows to cope with eventual clock inaccuracies. */ if (onalrm) - recompute_alarm = 1; - break; + pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM); + } + break; - case status_stopping: - check_stopping (prog, now); - break; + case status_stopping: + check_stopping (prog, now); + break; - case status_stopped: - prog_start (prog); - break; + case status_stopped: + if (IS_ACTIVE_COMPONENT (prog)) + prog_start (prog); + break; - default: - break; - } + default: + break; } - if (recompute_alarm) - progman_recompute_alarm (); } static int prog_start_prerequisites (struct prog *prog) { int ret = 0; @@ -1722,72 +1718,35 @@ prog_stop (struct prog *prog, int sig) if (prog->type == TYPE_COMPONENT) { if (prog->v.p.status == status_running) { prog->v.p.status = status_stopping; prog->v.p.timestamp = time (NULL); - recompute_alarm = 1; + pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM); } } 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 kill (prog->pid, sig); } -static void -prog_stop_all (int sig) -{ - struct prog *prog; - - debug (1, ("stopping all components (signal %d)", sig)); - for (prog = progtail; prog; prog = prog->prev) - if (IS_COMPONENT (prog) - && (prog->v.p.status == status_running - || prog->v.p.status == status_stopping)) - prog_stop (prog, sig); -} - -int -progman_wait_until (int (*cond) (void *), void *data) -{ - time_t start = time (NULL); - - do - { - progman_cleanup (1); - if (cond && cond (data)) - return 0; - sleep (1); - } - while (time (NULL) - start < shutdown_timeout); - return 1; -} - static int -no_children_left (void *p) +mark_for_stopping (struct prog *prog, void *data) { - struct prog *prog; - - for (prog = proghead; prog; prog = prog->next) - if (prog->pid > 0) - return 0; - - return 1; + if (IS_COMPONENT (prog)) + prog->v.p.stop = 1; + return 0; } void -progman_stop () +progman_stop (void) { - prog_stop_all (SIGTERM); - if (progman_wait_until (no_children_left, NULL)) - { - prog_stop_all (SIGKILL); - progman_wait_until (no_children_left, NULL); - } + progman_foreach (mark_for_stopping, NULL); + progman_gc (); } static void print_status (const char *tag, pid_t pid, int status, int expect_term) { int prio; |