r58 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Fri Mar 17 11:03:05 CET 2006


Author: phk
Date: 2006-03-17 11:03:05 +0100 (Fri, 17 Mar 2006)
New Revision: 58

Added:
   trunk/varnish-cache/bin/varnishd/mgt.h
   trunk/varnish-cache/bin/varnishd/mgt_child.c
Modified:
   trunk/varnish-cache/bin/varnishd/Makefile.am
   trunk/varnish-cache/bin/varnishd/cache_main.c
   trunk/varnish-cache/bin/varnishd/cli_event.c
   trunk/varnish-cache/bin/varnishd/heritage.h
   trunk/varnish-cache/bin/varnishd/varnishd.c
Log:
Add multiplexing for the mgt->child cli connection and get ping/pong
working across it.

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



Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am	2006-03-17 10:03:05 UTC (rev 58)
@@ -7,6 +7,7 @@
 varnishd_SOURCES = \
 	cache_main.c \
 	cli_event.c \
+	mgt_child.c \
 	varnishd.c
 
 varnishd_LDADD = \

Modified: trunk/varnish-cache/bin/varnishd/cache_main.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_main.c	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/cache_main.c	2006-03-17 10:03:05 UTC (rev 58)
@@ -33,7 +33,7 @@
 {
 	struct timeval tv;
 
-	tv.tv_sec = 5;
+	tv.tv_sec = 30;
 	tv.tv_usec = 0;
 
 	evtimer_del(&ev_keepalive);
@@ -48,8 +48,10 @@
 	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 @@
 	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();

Modified: trunk/varnish-cache/bin/varnishd/cli_event.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cli_event.c	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/cli_event.c	2006-03-17 10:03:05 UTC (rev 58)
@@ -108,7 +108,7 @@
 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 *

Modified: trunk/varnish-cache/bin/varnishd/heritage.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/heritage.h	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/heritage.h	2006-03-17 10:03:05 UTC (rev 58)
@@ -5,7 +5,7 @@
  */
 
 struct heritage {
-	int	fds[2];
+	int	fds[4];
 };
 
 extern struct heritage heritage;

Added: trunk/varnish-cache/bin/varnishd/mgt.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt.h	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/mgt.h	2006-03-17 10:03:05 UTC (rev 58)
@@ -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, ...);

Added: trunk/varnish-cache/bin/varnishd/mgt_child.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_child.c	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/mgt_child.c	2006-03-17 10:03:05 UTC (rev 58)
@@ -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();
+}

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2006-03-16 12:14:59 UTC (rev 57)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2006-03-17 10:03:05 UTC (rev 58)
@@ -1,5 +1,7 @@
 /*
  * $Id$
+ *
+ * The management process and CLI handling
  */
 
 #include <assert.h>
@@ -22,133 +24,39 @@
 #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;
+struct event_base *eb;
 
-static struct event_base *eb;
-
-static struct bufferevent *child_std;
-
 /*--------------------------------------------------------------------*/
 
-static void
-std_rdcb(struct bufferevent *bev, void *arg)
+void
+xxx_ccb(unsigned u, const char *r, void *priv)
 {
-	const char *p;
-
-	p = evbuffer_readline(bev->input);
-	if (p == NULL)
-		return;
-	printf("Child said <%s>\n", p);
+	printf("%s(%u, %s, %p)\n", __func__, u, r, priv);
 }
 
-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);
-}
-
-
-
 /*--------------------------------------------------------------------*/
 
 static void
-start_child(void)
+cli_func_url_query(struct cli *cli, char **av __unused, void *priv __unused)
 {
-	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);
+	mgt_child_request(xxx_ccb, NULL, "url.query %s", av[2]);
 }
 
 /*--------------------------------------------------------------------*/
 
 static void
-sig_chld(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(child_fds[0]);
-	close(child_fds[1]);
-
-	if (desired == H_START)
-		start_child();
-}
-
-/*--------------------------------------------------------------------*/
-
-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 @@
 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->verbose = !cli->verbose;
 }
 
+
 static void
 cli_func_ping(struct cli *cli, char **av, void *priv __unused)
 {
@@ -190,7 +94,7 @@
 
 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 @@
 
 	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();




More information about the varnish-commit mailing list