diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-02-18 15:23:30 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-02-18 15:33:34 +0200 |
commit | 0a55965bcc28928ae17ca39e3b8e35adf11ea09c (patch) | |
tree | ed8f6543999caef2d81b517fb90182be4a984fda | |
parent | d5302613a00915076b945b25b50eb6b376121955 (diff) | |
download | pies-0a55965bcc28928ae17ca39e3b8e35adf11ea09c.tar.gz pies-0a55965bcc28928ae17ca39e3b8e35adf11ea09c.tar.bz2 |
Fix activation/deactivation of network listeners.
* src/ctl.c (prog_active): New function.
(prog_serialize): Use prog_active to report prog's activity state.
For listener components, return also their service and tcpmux master
names, if applicable.
(fun_stop): Stop listeners as well.
(fun_start): Start listeners.
(ctlio_end): Don't close fd: this is done by deregister_socket
* src/inetd-bi.c (tcpmux_help): Don't list inactive components.
* src/prog.h (prog_activate_listener)
(prog_deactivate_listener): New protos.
* src/progman.c (prog_lookup_by_tag)
(prog_lookup_by_service): Remove.
(progman_cleanup): Fix coredump (premature free).
(progman_stop_component): If component is a listener, deactivate it.
(prog_activate_listener)
(prog_deactivate_listener): New functions.
* src/socket.c (delete_sockinst): Close the socket descriptor.
* src/sysvinit.c (sysvinit_fifo_handler, create_fifo): Don't close fd,
leave that to deregister_socket.
-rw-r--r-- | src/ctl.c | 67 | ||||
-rw-r--r-- | src/inetd-bi.c | 3 | ||||
-rw-r--r-- | src/prog.h | 3 | ||||
-rw-r--r-- | src/progman.c | 68 | ||||
-rw-r--r-- | src/socket.c | 1 | ||||
-rw-r--r-- | src/sysvinit.c | 6 |
6 files changed, 100 insertions, 48 deletions
@@ -532,7 +532,6 @@ static int ctlio_end (int fd, struct ctlio *io) { deregister_socket (fd); - close (fd); ctlio_destroy (io); return 1; } @@ -1816,6 +1815,24 @@ selector (struct prog *prog, void *data) return 0; } +/* Return true if PROG is active. For TCPMUX progs, this takes into account + the state of the master listener. + FIXME: Ideally all TCPMUXen must form a list attached to their master + listener. When this is fixed, this function will disappear. */ +static int +prog_active (struct prog *prog) +{ + if (prog->v.p.active) + { + if (ISCF_TCPMUX (prog->v.p.comp->flags)) + { + prog = progman_locate (prog->v.p.comp->tcpmux); + return prog && prog->v.p.active; + } + } + return prog->v.p.active; +} + static struct json_value * prog_serialize (struct json_value *ret, struct prog *prog) { @@ -1829,14 +1846,23 @@ prog_serialize (struct json_value *ret, struct prog *prog) FORMAT_IDX (ret, "mode", pies_comp_mode_str, prog->v.p.comp->mode); FORMAT_IDX (ret, "status", pies_status_str, prog->v.p.status); - json_object_set_bool (ret, "active", prog->v.p.active); + json_object_set_bool (ret, "active", prog_active (prog)); if (prog->pid) json_object_set_number (ret, "PID", prog->pid); - else if (prog->v.p.status == status_listener - && prog->v.p.comp->socket_url) - json_object_set_string (ret, "URL", "%s", - prog->v.p.comp->socket_url->string); + else if (prog->v.p.status == status_listener) + { + if (prog->v.p.comp->socket_url) + json_object_set_string (ret, "URL", "%s", + prog->v.p.comp->socket_url->string); + if (prog->v.p.comp->service) + json_object_set_string (ret, "service", "%s", + prog->v.p.comp->service); + if (ISCF_TCPMUX (prog->v.p.comp->flags) && prog->v.p.comp->tcpmux) + json_object_set_string (ret, "master", "%s", + prog->v.p.comp->tcpmux); + } + if (prog->v.p.comp->runlevels) json_object_set_string (ret, "runlevels", "%s", @@ -1872,19 +1898,16 @@ fun_list (struct json_value *result, struct prog *prog) static int fun_stop (struct json_value *result, struct prog *prog) { - if (prog->v.p.active && prog->v.p.status == status_stopped) - { - + if (!prog->v.p.active) + { json_object_set_string (result, "status", "ER"); json_object_set_string (result, "error_message", "already stopped"); return 1; } - else - { - prog->v.p.active = 0; - 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; } @@ -1895,7 +1918,6 @@ fun_start (struct json_value *result, struct prog *prog) { case status_stopped: prog->v.p.comp->flags &= ~CF_DISABLED; - prog->v.p.active = 1; json_object_set_string (result, "status", "OK"); break; @@ -1906,12 +1928,25 @@ fun_start (struct json_value *result, struct prog *prog) prog->v.p.timestamp = 0; json_object_set_string (result, "status", "OK"); break; + + case status_listener: + if (prog_activate_listener (prog) == 0) + json_object_set_string (result, "status", "OK"); + else + { + json_object_set_string (result, "status", "ER"); + /* FIXME: error message */ + json_object_set_string (result, "error_message", + "can't open socket"); + } + break; default: json_object_set_string (result, "status", "ER"); json_object_set_string (result, "error_message", "already running"); return 1; } + prog->v.p.active = 1; return 0; } diff --git a/src/inetd-bi.c b/src/inetd-bi.c index de9cfa0..d0d3ea4 100644 --- a/src/inetd-bi.c +++ b/src/inetd-bi.c @@ -15,6 +15,7 @@ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" +#include "prog.h" #include <netdb.h> #define INTBUFSIZE 8192 @@ -303,7 +304,7 @@ tcpmux_help (struct component *comp, void *data) { int *pfd = data; - if (!(comp->flags & CF_DISABLED) && ISCF_TCPMUX (comp->flags)) + if (ISCF_TCPMUX (comp->flags) && comp->prog && comp->prog->v.p.active) { fd_report (*pfd, comp->service); fd_report (*pfd, "\r\n"); @@ -91,3 +91,6 @@ void prog_stop (struct prog *prog, int sig); void progman_stop_component (struct prog **prog); char const *prog_tag (struct prog const *prog); + +int prog_activate_listener (struct prog *prog); +void prog_deactivate_listener (struct prog *prog); diff --git a/src/progman.c b/src/progman.c index 9641629..2c38b63 100644 --- a/src/progman.c +++ b/src/progman.c @@ -72,28 +72,6 @@ prog_lookup_by_pid (pid_t pid) return prog; } -struct prog * -prog_lookup_by_tag (const char *tag) -{ - struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (strcmp (prog_tag (prog), tag) == 0) - break; - return prog; -} - -struct prog * -prog_lookup_by_service (const char *service) -{ - struct prog *prog; - for (prog = proghead; prog; prog = prog->next) - if (IS_COMPONENT (prog) - && prog->v.p.comp->service - && strcmp (prog->v.p.comp->service, service) == 0) - break; - return prog; -} - struct component * progman_lookup_component (const char *tag) { @@ -190,8 +168,8 @@ destroy_prog (struct prog **pp) { case TYPE_COMPONENT: component_ref_decr (p->v.p.comp); - if (p->v.p.status == status_listener) - deregister_socket (p->v.p.socket); + if (p->v.p.status == status_listener && p->v.p.socket != -1) + deregister_socket (p->v.p.socket); break; case TYPE_REDIRECTOR: @@ -2311,7 +2289,6 @@ progman_cleanup (int expect_term) } prog_stop_redirectors (prog); - destroy_prog (&prog); if (listener->v.p.num_instances == 0 && !component_is_active (prog->v.p.comp)) destroy_prog (&listener); @@ -2322,6 +2299,7 @@ progman_cleanup (int expect_term) if (listener->v.p.comp->flags & CF_WAIT) enable_socket (listener->v.p.socket); } + destroy_prog (&prog); } else { @@ -2388,11 +2366,13 @@ progman_stop_component (struct prog **progptr) switch (prog->v.p.status) { case status_running: - case status_listener: logmsg (LOG_INFO, _("stopping component `%s'"), prog_tag (prog)); prog_stop (prog, SIGTERM); break; + case status_listener: + prog_deactivate_listener (prog); + /* fall through */ case status_stopped: if (!component_is_active (prog->v.p.comp)) destroy_prog (progptr); @@ -2420,6 +2400,42 @@ progman_stop_component (struct prog **progptr) } void +prog_deactivate_listener (struct prog *prog) +{ + logmsg (LOG_INFO, _("deactivating listener `%s'"), prog_tag (prog)); + if (prog->v.p.socket != -1) + { + deregister_socket (prog->v.p.socket); + prog->v.p.socket = -1; + } +} + +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) + { + int fd = create_socket (comp->socket_url, + comp->socket_type, + comp->privs.user, comp->umask); + if (fd == -1) + return -1; + else if (register_program_socket (comp->socket_type, fd, prog)) + { + close (fd); + return -1; + } + else + prog->v.p.socket = fd; + } + return 0; +} + +void progman_stop_tag (const char *name) { struct prog *prog = progman_locate (name); diff --git a/src/socket.c b/src/socket.c index f239074..3223a65 100644 --- a/src/socket.c +++ b/src/socket.c @@ -489,6 +489,7 @@ update_socket (int fd, int evt, socket_handler_t f) static void delete_sockinst (struct sockinst *sp) { + close (sp->fd); if (sp->handler[PIES_EVT_RD]) FD_CLR (sp->fd, &fdset[PIES_EVT_RD]); if (sp->handler[PIES_EVT_WR]) diff --git a/src/sysvinit.c b/src/sysvinit.c index 87a52d6..6276228 100644 --- a/src/sysvinit.c +++ b/src/sysvinit.c @@ -482,7 +482,6 @@ sysvinit_fifo_handler (int fd, void *data) { logmsg (LOG_ERR, _("end of file on %s: reopening"), init_fifo); size = 0; - close (fd); deregister_socket (fd); create_fifo (); return 0; @@ -573,10 +572,7 @@ create_fifo () { fstat (fd, &fst); if (fst.st_dev != st.st_dev || fst.st_ino != st.st_ino) - { - deregister_socket (fd); - close (fd); - } + deregister_socket (fd); debug (1, ("reopening %s", init_fifo)); } |