aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-02-18 15:23:30 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-02-18 15:33:34 +0200
commit0a55965bcc28928ae17ca39e3b8e35adf11ea09c (patch)
treeed8f6543999caef2d81b517fb90182be4a984fda
parentd5302613a00915076b945b25b50eb6b376121955 (diff)
downloadpies-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.c67
-rw-r--r--src/inetd-bi.c3
-rw-r--r--src/prog.h3
-rw-r--r--src/progman.c68
-rw-r--r--src/socket.c1
-rw-r--r--src/sysvinit.c6
6 files changed, 100 insertions, 48 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 6e162e5..54282a2 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -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");
diff --git a/src/prog.h b/src/prog.h
index 3b20979..316a229 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -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));
}

Return to:

Send suggestions and report system problems to the System administrator.