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 /src/ctl.c | |
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.
Diffstat (limited to 'src/ctl.c')
-rw-r--r-- | src/ctl.c | 67 |
1 files changed, 51 insertions, 16 deletions
@@ -529,13 +529,12 @@ ctlio_reset (struct ctlio *io) } static int ctlio_end (int fd, struct ctlio *io) { deregister_socket (fd); - close (fd); ctlio_destroy (io); return 1; } static char const * http_text (int code) @@ -1813,12 +1812,30 @@ selector (struct prog *prog, void *data) else env->noperm_count++; } 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) { struct json_value *v; size_t i; @@ -1826,20 +1843,29 @@ prog_serialize (struct json_value *ret, struct prog *prog) switch (prog->type) { case TYPE_COMPONENT: 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", prog->v.p.comp->runlevels); if (prog->v.p.status == status_sleeping) @@ -1869,52 +1895,61 @@ 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 && 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; } static int fun_start (struct json_value *result, struct prog *prog) { switch (prog->v.p.status) { case status_stopped: prog->v.p.comp->flags &= ~CF_DISABLED; - prog->v.p.active = 1; json_object_set_string (result, "status", "OK"); break; case status_sleeping: case status_finished: prog->v.p.status = status_stopped; prog->v.p.failcount = 0; 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; } static int fun_restart (struct json_value *result, struct prog *prog) { |