]> err.no Git - varnish/commitdiff
Add multiplexing for the mgt->child cli connection and get ping/pong
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 17 Mar 2006 10:03:05 +0000 (10:03 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 17 Mar 2006 10:03:05 +0000 (10:03 +0000)
working across it.

The management process will now keep the child process watchdog from
expiring.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@58 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cli_event.c
varnish-cache/bin/varnishd/heritage.h
varnish-cache/bin/varnishd/mgt.h [new file with mode: 0644]
varnish-cache/bin/varnishd/mgt_child.c [new file with mode: 0644]
varnish-cache/bin/varnishd/varnishd.c

index 507e5c54de8d9775a67adf5fe470746ebb65d9c9..32d8553cea276222b4de1f84392510e9a5c7b6ac 100644 (file)
@@ -7,6 +7,7 @@ bin_PROGRAMS = varnishd
 varnishd_SOURCES = \
        cache_main.c \
        cli_event.c \
+       mgt_child.c \
        varnishd.c
 
 varnishd_LDADD = \
index 6cb3c3506285f0e40f74c48b2332f75e51712818..74d2b78c339eb8014517d97e2810da03677888de 100644 (file)
@@ -33,7 +33,7 @@ arm_keepalive(void)
 {
        struct timeval tv;
 
-       tv.tv_sec = 5;
+       tv.tv_sec = 30;
        tv.tv_usec = 0;
 
        evtimer_del(&ev_keepalive);
@@ -48,8 +48,10 @@ cli_func_ping(struct cli *cli, char **av, void *priv __unused)
        time_t t;
 
        arm_keepalive();
-       if (av[2] != NULL)
-               cli_out(cli, "Got your %s\n", av[2]);
+       if (av[2] != NULL) {
+               /* XXX: check clock skew is pointless here */
+               printf("Got your ping %s\n", av[2]);
+       }
        time(&t);
        cli_out(cli, "PONG %ld\n", t);
 }
@@ -75,7 +77,7 @@ child_main(void)
        eb = event_init();
        assert(eb != NULL);
 
-       cli = cli_setup(heritage.fds[0], heritage.fds[1], 0, cli_proto);
+       cli = cli_setup(heritage.fds[2], heritage.fds[1], 0, cli_proto);
 
        evtimer_set(&ev_keepalive, timer_keepalive, NULL);
        arm_keepalive();
index 8621efe404bb71cc44e8d61c63ca6de317813c40..70c83a8d4ad4f9d8d3be81583f00d868ad575492 100644 (file)
@@ -108,7 +108,7 @@ wrcb(struct bufferevent *bev, void *arg)
 static void
 excb(struct bufferevent *bev, short what, void *arg)
 {
-       printf("Exception\n");
+       printf("%s(%p, %d, %p)\n", __func__, (void*)bev, what, arg);
 }
 
 struct cli *
index aaf0e713dac5175828c826e4420979c0437fc4d5..c1b8e78b90e484707f1bf745b4f9d629307835d9 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 struct heritage {
-       int     fds[2];
+       int     fds[4];
 };
 
 extern struct heritage heritage;
diff --git a/varnish-cache/bin/varnishd/mgt.h b/varnish-cache/bin/varnishd/mgt.h
new file mode 100644 (file)
index 0000000..b903e03
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * $Id$
+ */
+
+extern struct event_base *eb;
+
+void mgt_child_start(void);
+void mgt_child_stop(void);
+void mgt_sigchld(int, short, void *);
+
+typedef void mgt_ccb_f(unsigned, const char *, void *);
+void mgt_child_request(mgt_ccb_f *, void *, const char *fmt, ...);
diff --git a/varnish-cache/bin/varnishd/mgt_child.c b/varnish-cache/bin/varnishd/mgt_child.c
new file mode 100644 (file)
index 0000000..1e2251e
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * $Id$
+ *
+ * The mechanics of handling the child process
+ */
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <sys/queue.h>
+
+#include <event.h>
+#include <sbuf.h>
+
+#include <libvarnish.h>
+#include <cli.h>
+
+#include "heritage.h"
+#include "mgt.h"
+
+/*--------------------------------------------------------------------*/
+
+static enum {
+       H_STOP = 0,
+       H_START
+}      desired;
+
+static pid_t   child_pid;
+static int     child_fds[2];
+
+static struct bufferevent *child_std;
+static struct bufferevent *child_cli0, *child_cli1;
+
+static struct event ev_child_pingpong;
+
+struct creq {
+       TAILQ_ENTRY(creq)       list;
+       char                    *req;
+       mgt_ccb_f               *func;
+       void                    *priv;
+};
+
+static TAILQ_HEAD(,creq)       creqhead = TAILQ_HEAD_INITIALIZER(creqhead);
+
+/*--------------------------------------------------------------------
+ * Handle stdout+stderr from the child.
+ */
+
+static void
+std_rdcb(struct bufferevent *bev, void *arg)
+{
+       const char *p;
+
+       p = evbuffer_readline(bev->input);
+       if (p == NULL)
+               return;
+       printf("Child said <%s>\n", p);
+}
+
+static void
+std_wrcb(struct bufferevent *bev, void *arg)
+{
+
+       printf("%s(%p, %p)\n", __func__, (void*)bev, arg);
+       exit (2);
+}
+
+static void
+std_excb(struct bufferevent *bev, short what, void *arg)
+{
+
+       printf("%s(%p, %d, %p)\n", __func__, (void*)bev, what, arg);
+       exit (2);
+}
+
+/*--------------------------------------------------------------------
+ * Multiplex requests/answers to the child
+ */
+
+static void
+send_req(void)
+{
+       struct creq *cr;
+
+       cr = TAILQ_FIRST(&creqhead);
+       if (cr == NULL)
+               return;
+       printf("Send Request <%s>\n", cr->req);
+       evbuffer_add_printf(child_cli1->output, "%s\n", cr->req);
+       bufferevent_enable(child_cli1, EV_WRITE);
+}
+
+void
+mgt_child_request(mgt_ccb_f *func, void *priv, const char *fmt, ...)
+{
+       struct creq *cr;
+       va_list ap;
+       int i;
+
+       cr = calloc(sizeof *cr, 1);
+       assert(cr != NULL);
+       cr->func = func;
+       cr->priv = priv;
+       va_start(ap, fmt);
+       vasprintf(&cr->req, fmt, ap);
+       va_end(ap);
+       i = TAILQ_EMPTY(&creqhead);
+       TAILQ_INSERT_TAIL(&creqhead, cr, list);
+       if (i)
+               send_req();
+}
+
+static void
+cli_rdcb(struct bufferevent *bev, void *arg)
+{
+       const char *p;
+       char **av;
+       struct creq *cr;
+
+       p = evbuffer_readline(bev->input);
+       if (p == NULL)
+               return;
+       cr = TAILQ_FIRST(&creqhead);
+       assert(cr != NULL);
+       av = ParseArgv(p, 0);
+       if (av[0] != NULL) 
+               cr->func(CLIS_SYNTAX, av[0], cr->priv);
+       else
+               cr->func(strtoul(av[1], NULL, 0), av[2], cr->priv);
+       FreeArgv(av);
+       TAILQ_REMOVE(&creqhead, cr, list);
+       free(cr->req);
+       free(cr);
+       send_req();
+}
+
+static void
+cli_wrcb(struct bufferevent *bev __unused, void *arg __unused)
+{
+
+}
+
+static void
+cli_excb(struct bufferevent *bev, short what, void *arg)
+{
+
+       printf("%s(%p, %d, %p)\n", __func__, (void*)bev, what, arg);
+       exit (2);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+child_pingpong_ccb(unsigned u, const char *r, void *priv)
+{
+       printf("%s(%u, \"%s\", %p)\n", __func__, u, r, priv);
+       /* XXX: reset keepalive timer */
+}
+
+
+static void
+child_pingpong(int a, short b, void *c)
+{
+       time_t t;
+       struct timeval tv;
+
+       printf("%s(%d, %d, %p)\n", __func__, a, b, c);
+       time(&t);
+       mgt_child_request(child_pingpong_ccb, NULL, "ping %ld", t);
+       if (1) {
+               tv.tv_sec = 3;
+               tv.tv_usec = 0;
+               evtimer_del(&ev_child_pingpong);
+               evtimer_add(&ev_child_pingpong, &tv);
+       }
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static void
+start_child(void)
+{
+       int i;
+
+       assert(pipe(&heritage.fds[0]) == 0);
+       assert(pipe(&heritage.fds[2]) == 0);
+       assert(pipe(child_fds) == 0);
+       i = fork();
+       if (i < 0) 
+               errx(1, "Could not fork child");
+       if (i == 0) {
+               /* XXX: close fds */
+               /* XXX: (re)set signals */
+
+               /* Redirect stdin/out/err */
+               close(0);
+               i = open("/dev/null", O_RDONLY);
+               assert(i == 0);
+               close(child_fds[0]);
+               dup2(child_fds[1], 1);
+               dup2(child_fds[1], 2);
+               close(child_fds[1]);
+
+               child_main();
+
+               exit (1);
+       }
+       child_pid = i;
+       printf("start child pid %d\n", i);
+
+       /*
+        * We do not close the unused ends of the pipes here to avoid
+        * doing SIGPIPE handling.
+        */
+       child_std = bufferevent_new(child_fds[0],
+           std_rdcb, std_wrcb, std_excb, NULL);
+       assert(child_std != NULL);
+       bufferevent_enable(child_std, EV_READ);
+       child_cli0 = bufferevent_new(heritage.fds[0],
+           cli_rdcb, cli_wrcb, cli_excb, NULL);
+       assert(child_cli0 != NULL);
+       bufferevent_enable(child_cli0, EV_READ);
+       child_cli1 = bufferevent_new(heritage.fds[3],
+           cli_rdcb, cli_wrcb, cli_excb, NULL);
+       assert(child_cli1 != NULL);
+
+       evtimer_set(&ev_child_pingpong, child_pingpong, NULL);
+       child_pingpong(0, 0, NULL);
+}
+
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_child_start(void)
+{
+
+       if (desired == H_START)
+               return;
+       desired = H_START;
+       start_child();
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_child_stop(void)
+{
+
+       if (desired == H_STOP)
+               return;
+       desired = H_STOP;
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_sigchld(int a, short b, void *c)
+{
+       pid_t p;
+       int status;
+
+       printf("sig_chld(%d, %d, %p)\n", a, b, c);
+
+       p = wait4(-1, &status, WNOHANG, NULL);
+       printf("pid = %d status = 0x%x\n", p, status);
+       assert(p == child_pid);
+
+       bufferevent_free(child_std); /* XXX: is this enough ? */
+       child_std = NULL;
+
+       close(heritage.fds[0]);
+       close(heritage.fds[1]);
+       close(heritage.fds[2]);
+       close(heritage.fds[3]);
+       close(child_fds[0]);
+       close(child_fds[1]);
+
+       if (desired == H_START)
+               start_child();
+}
index 6a688668263a19169f1de5aeef8d2a0d5d425259..422337e52fbd03bf022bb8a36dac50f925825871 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * $Id$
+ *
+ * The management process and CLI handling
  */
 
 #include <assert.h>
 #include <cli_priv.h>
 #include <libvarnish.h>
 
+#include "mgt.h"
 #include "heritage.h"
 #include "cli_event.h"
 
 /*--------------------------------------------------------------------*/
 
-static enum {
-       H_STOP = 0,
-       H_START
-}      desired;
-static pid_t   child_pid;
-static int     child_fds[2];
-
 struct heritage heritage;
-
-static struct event_base *eb;
-
-static struct bufferevent *child_std;
-
-/*--------------------------------------------------------------------*/
-
-static void
-std_rdcb(struct bufferevent *bev, void *arg)
-{
-       const char *p;
-
-       p = evbuffer_readline(bev->input);
-       if (p == NULL)
-               return;
-       printf("Child said <%s>\n", p);
-}
-
-static void
-std_wrcb(struct bufferevent *bev, void *arg)
-{
-
-       printf("%s(%p, %p)\n", __func__, (void*)bev, arg);
-       exit (2);
-}
-
-static void
-std_excb(struct bufferevent *bev, short what, void *arg)
-{
-
-       printf("%s(%p, %d, %p)\n", __func__, (void*)bev, what, arg);
-       exit (2);
-}
-
-
+struct event_base *eb;
 
 /*--------------------------------------------------------------------*/
 
-static void
-start_child(void)
+void
+xxx_ccb(unsigned u, const char *r, void *priv)
 {
-       int i;
-
-       assert(pipe(heritage.fds) == 0);
-       assert(pipe(child_fds) == 0);
-       i = fork();
-       if (i < 0) 
-               errx(1, "Could not fork child");
-       if (i == 0) {
-               /* XXX: close fds */
-               /* XXX: (re)set signals */
-
-               /* Redirect stdin/out/err */
-               close(0);
-               i = open("/dev/null", O_RDONLY);
-               assert(i == 0);
-               close(child_fds[0]);
-               dup2(child_fds[1], 1);
-               dup2(child_fds[1], 2);
-               close(child_fds[1]);
-
-               child_main();
-
-               exit (1);
-       }
-       child_pid = i;
-       printf("start child pid %d\n", i);
-
-       /*
-        * We do not close the unused ends of the pipes here to avoid
-        * doing SIGPIPE handling.
-        */
-       child_std = bufferevent_new(child_fds[0],
-           std_rdcb, std_wrcb, std_excb, NULL);
-       assert(child_std != NULL);
-       bufferevent_enable(child_std, EV_READ);
+       printf("%s(%u, %s, %p)\n", __func__, u, r, priv);
 }
 
 /*--------------------------------------------------------------------*/
 
 static void
-sig_chld(int a, short b, void *c)
+cli_func_url_query(struct cli *cli, char **av __unused, void *priv __unused)
 {
-       pid_t p;
-       int status;
-
-       printf("sig_chld(%d, %d, %p)\n", a, b, c);
-
-       p = wait4(-1, &status, WNOHANG, NULL);
-       printf("pid = %d status = 0x%x\n", p, status);
-       assert(p == child_pid);
-
-       bufferevent_free(child_std); /* XXX: is this enough ? */
-       child_std = NULL;
 
-       close(heritage.fds[0]);
-       close(heritage.fds[1]);
-       close(child_fds[0]);
-       close(child_fds[1]);
-
-       if (desired == H_START)
-               start_child();
+       mgt_child_request(xxx_ccb, NULL, "url.query %s", av[2]);
 }
 
 /*--------------------------------------------------------------------*/
@@ -145,10 +56,7 @@ static void
 cli_func_server_start(struct cli *cli, char **av __unused, void *priv __unused)
 {
 
-       if (desired != H_START) {
-               desired = H_START;
-               start_child();
-       }
+       mgt_child_start();
 }
 
 /*--------------------------------------------------------------------*/
@@ -157,12 +65,7 @@ static void
 cli_func_server_stop(struct cli *cli, char **av __unused, void *priv __unused)
 {
 
-       if (desired != H_STOP) {
-               desired = H_STOP;
-#if 0
-               stop_child();
-#endif
-       }
+       mgt_child_stop();
 }
 
 /*--------------------------------------------------------------------*/
@@ -174,6 +77,7 @@ cli_func_verbose(struct cli *cli, char **av __unused, void *priv)
        cli->verbose = !cli->verbose;
 }
 
+
 static void
 cli_func_ping(struct cli *cli, char **av, void *priv __unused)
 {
@@ -190,7 +94,7 @@ cli_func_ping(struct cli *cli, char **av, void *priv __unused)
 
 static struct cli_proto cli_proto[] = {
        /* URL manipulation */
-       { CLI_URL_QUERY },
+       { CLI_URL_QUERY,        cli_func_url_query, NULL },
        { CLI_URL_PURGE },
        { CLI_URL_STATUS },
        { CLI_CONFIG_LOAD },
@@ -228,7 +132,7 @@ testme(void)
 
        cli = cli_setup(0, 1, 1, cli_proto);
 
-       signal_set(&e_sigchld, SIGCHLD, sig_chld, NULL);
+       signal_set(&e_sigchld, SIGCHLD, mgt_sigchld, NULL);
        signal_add(&e_sigchld, NULL);
 
        i = event_dispatch();