r616 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Thu Aug 3 11:45:14 CEST 2006


Author: phk
Date: 2006-08-03 11:45:14 +0200 (Thu, 03 Aug 2006)
New Revision: 616

Added:
   trunk/varnish-cache/bin/varnishd/cli_common.c
   trunk/varnish-cache/bin/varnishd/common_cli.c
   trunk/varnish-cache/bin/varnishd/common_cli.h
   trunk/varnish-cache/bin/varnishd/mgt_cli.c
Removed:
   trunk/varnish-cache/bin/varnishd/cli_event.c
   trunk/varnish-cache/bin/varnishd/cli_event.h
Modified:
   trunk/varnish-cache/bin/varnishd/Makefile.am
   trunk/varnish-cache/bin/varnishd/cache_cli.c
   trunk/varnish-cache/bin/varnishd/cache_main.c
   trunk/varnish-cache/bin/varnishd/mgt.h
   trunk/varnish-cache/bin/varnishd/mgt_child.c
   trunk/varnish-cache/bin/varnishd/varnishd.c
Log:
Rip out the old CLI handling and start over, more or less.

Still bits missing.



Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am	2006-08-03 09:45:14 UTC (rev 616)
@@ -1,6 +1,6 @@
 # $Id$
 
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/contrib/libevent
+INCLUDES = -I$(top_srcdir)/include
 
 bin_PROGRAMS = varnishd
 
@@ -8,7 +8,7 @@
 
 varnishd_SOURCES = \
 	cache.h \
-	cli_event.h \
+	common_cli.h \
 	hash_slinger.h \
 	heritage.h \
 	mgt.h \
@@ -33,10 +33,11 @@
 	cache_vrt.c \
 	cache_vrt_acl.c \
 	cache_vrt_re.c \
-	cli_event.c \
+	common_cli.c \
 	hash_simple_list.c \
 	hash_classic.c \
 	mgt_child.c \
+	mgt_cli.c \
 	rfc2616.c \
 	shmlog.c \
 	storage_file.c \
@@ -51,6 +52,5 @@
 	$(top_builddir)/lib/libsbuf/libsbuf.a \
 	$(top_builddir)/lib/libvarnish/libvarnish.la \
 	$(top_builddir)/lib/libvcl/libvcl.la \
-	$(top_builddir)/contrib/libevent/libevent.la \
 	-lpthread \
 	-lmd

Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_cli.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/cache_cli.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -10,13 +10,11 @@
 #include <poll.h>
 #include <pthread.h>
 
-#include "event.h"		/* XXX only as long as it takes */
-
 #include "libvarnish.h"
 #include "shmlog.h"
 #include "cli.h"
 #include "cli_priv.h"
-#include "cli_event.h"
+#include "common_cli.h"
 #include "cache.h"
 #include "sbuf.h"
 #include "heritage.h"
@@ -54,24 +52,6 @@
 	{ NULL }
 };
 
-static int
-cli_writes(const char *s, const char *r, const char *t)
-{
-	int i, l;
-	struct iovec iov[3];
-
-	iov[0].iov_base = (void*)(uintptr_t)s;
-	iov[1].iov_base = (void*)(uintptr_t)r;
-	iov[2].iov_base = (void*)(uintptr_t)t;
-	for (l = i = 0; i < 3; i++) {
-		iov[i].iov_len = strlen(iov[i].iov_base);
-		l += iov[i].iov_len;
-	}
-	i = writev(heritage.fds[1], iov, 3);
-	VSL(SLT_CLI, 0, "Wr %d %s %s", i != l, s, r);
-	return (i != l);
-}
-
 void
 CLI_Init(void)
 {
@@ -80,7 +60,6 @@
 	unsigned nbuf, lbuf;
 	struct cli *cli, clis;
 	int i;
-	char res[30];
 
 	cli = &clis;
 	memset(cli, 0, sizeof *cli);
@@ -116,11 +95,13 @@
 		sbuf_clear(cli->sb);
 		cli_dispatch(cli, CLI_cmds, buf);
 		sbuf_finish(cli->sb);
-		sprintf(res, "%d ", cli->result);
-		if (cli_writes(res, sbuf_data(cli->sb), "\n")) {
+		i = cli_writeres(heritage.fds[2], cli);
+		if (i) {
 			VSL(SLT_Error, 0, "CLI write failed (errno=%d)", errno);
 			return;
 		}
+		VSL(SLT_CLI, 0, "Wr %d %d %s",
+		    i, cli->result, sbuf_data(cli->sb));
 		i = ++p - buf; 
 		assert(i <= nbuf);
 		if (i < nbuf)

Modified: trunk/varnish-cache/bin/varnishd/cache_main.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_main.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/cache_main.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -11,7 +11,6 @@
 #include "heritage.h"
 #include "shmlog.h"
 #include "cache.h"
-#include "event.h"
 
 struct stevedore	*stevedore;
 

Copied: trunk/varnish-cache/bin/varnishd/cli_common.c (from rev 585, trunk/varnish-cache/bin/varnishd/cli_event.c)
===================================================================
--- trunk/varnish-cache/bin/varnishd/cli_event.c	2006-08-01 12:38:26 UTC (rev 585)
+++ trunk/varnish-cache/bin/varnishd/cli_common.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ */
+
+#include <errno.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <sys/wait.h>
+
+#include "sbuf.h"
+
+#include <cli.h>
+#include <cli_common.h>
+#include <libvarnish.h>
+
+void
+cli_out(struct cli *cli, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	sbuf_vprintf(cli->sb, fmt, ap);
+	va_end(ap);
+}
+
+void
+cli_param(struct cli *cli)
+{
+
+	cli->result = CLIS_PARAM;
+	cli_out(cli, "Parameter error, use \"help [command]\" for more info.\n");
+}
+
+void
+cli_result(struct cli *cli, unsigned res)
+{
+
+	cli->result = res;
+}
+

Deleted: trunk/varnish-cache/bin/varnishd/cli_event.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cli_event.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/cli_event.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -1,172 +0,0 @@
-/*
- * $Id$
- */
-
-#include <errno.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include <sys/wait.h>
-
-#include <event.h>
-#include <sbuf.h>
-
-#include <cli.h>
-#include <cli_priv.h>
-#include <libvarnish.h>
-
-#include "heritage.h"
-#include "cli_event.h"
-
-void
-cli_encode_string(struct evbuffer *buf, char *b)
-{
-	char *p, *q;
-
-	evbuffer_add_printf(buf, "\"");
-	for (p = q = b; *p != '\0'; p++) {
-		if ((*p != '"' && *p != '\\' && isgraph(*p)) || *p == ' ')
-			continue;
-		if (p != q) 
-			evbuffer_add(buf, q, p - q);
-		if (*p == '\n')
-			evbuffer_add_printf(buf, "\\n");
-		else
-			evbuffer_add_printf(buf, "\\x%02x", *p);
-		q = p + 1;
-	}
-	if (p != q) 
-		evbuffer_add(buf, q, p - q);
-	evbuffer_add_printf(buf, "\"");
-}
-
-
-void
-cli_out(struct cli *cli, const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	sbuf_vprintf(cli->sb, fmt, ap);
-	va_end(ap);
-}
-
-void
-cli_param(struct cli *cli)
-{
-
-	cli->result = CLIS_PARAM;
-	cli_out(cli, "Parameter error, use \"help [command]\" for more info.\n");
-}
-
-void
-cli_result(struct cli *cli, unsigned res)
-{
-
-	cli->result = res;
-}
-
-static void
-encode_output(struct cli *cli)
-{
-
-	if (cli->verbose) {
-		if (cli->result != CLIS_OK)
-			evbuffer_add_printf(cli->bev1->output, "ERROR %d ",
-			    cli->result);
-		evbuffer_add(cli->bev1->output,
-		    sbuf_data(cli->sb), sbuf_len(cli->sb));
-		if (cli->result == CLIS_OK)
-			evbuffer_add_printf(cli->bev1->output, "OK\n");
-		return;
-	}
-	evbuffer_add_printf(cli->bev1->output, "%d ", cli->result);
-	cli_encode_string(cli->bev1->output, sbuf_data(cli->sb));
-	evbuffer_add_printf(cli->bev1->output, "\n");
-}
-
-static void
-rdcb(struct bufferevent *bev, void *arg)
-{
-	const char *p;
-	struct cli *cli = arg;
-
-	p = evbuffer_readline(bev->input);
-	if (p == NULL)
-		return;
-	sbuf_clear(cli->sb);
-	cli_dispatch(cli, cli->cli_proto, p);
-	if (!cli->suspend) {
-		sbuf_finish(cli->sb);
-		/* XXX: syslog results ? */
-		encode_output(cli);
-		AZ(bufferevent_enable(cli->bev1, EV_WRITE));
-	}
-}
-
-static void
-wrcb(struct bufferevent *bev, void *arg)
-{
-	struct cli *cli = arg;
-
-	(void)bev;
-	AZ(bufferevent_disable(cli->bev1, EV_WRITE));
-}
-
-static void
-excb(struct bufferevent *bev, short what, void *arg)
-{
-	printf("%s(%p, %d, %p)\n", __func__, (void*)bev, (int)what, arg);
-}
-
-struct cli *
-cli_setup(struct event_base *eb, int fdr, int fdw, int ver, struct cli_proto *cli_proto)
-{
-	struct cli	*cli;
-
-	cli = calloc(sizeof *cli, 1);
-	assert(cli != NULL);
-
-	cli->bev0 = bufferevent_new(fdr, rdcb, wrcb, excb, cli);
-	assert(cli->bev0 != NULL);
-	AZ(bufferevent_base_set(eb, cli->bev0));
-	if (fdr == fdw)
-		cli->bev1 = cli->bev0;
-	else 
-		cli->bev1 = bufferevent_new(fdw, rdcb, wrcb, excb, cli);
-	assert(cli->bev1 != NULL);
-	AZ(bufferevent_base_set(eb, cli->bev1));
-	cli->sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
-	assert(cli->sb != NULL);
-
-	cli->verbose = ver;
-	cli->cli_proto = cli_proto;
-	
-	AZ(bufferevent_enable(cli->bev0, EV_READ));
-	return (cli);
-}
-
-void
-cli_suspend(struct cli *cli)
-{
-
-	cli->suspend = 1;
-	AZ(bufferevent_disable(cli->bev0, EV_READ));
-}
-
-void
-cli_resume(struct cli *cli)
-{
-	sbuf_finish(cli->sb);
-	/* XXX: syslog results ? */
-	encode_output(cli);
-	AZ(bufferevent_enable(cli->bev1, EV_WRITE));
-	cli->suspend = 0;
-	AZ(bufferevent_enable(cli->bev0, EV_READ));
-}
-

Deleted: trunk/varnish-cache/bin/varnishd/cli_event.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cli_event.h	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/cli_event.h	2006-08-03 09:45:14 UTC (rev 616)
@@ -1,18 +0,0 @@
-/*
- * $Id$
- */
-
-struct cli {
-	struct bufferevent	*bev0, *bev1;
-	struct sbuf		*sb;
-	unsigned		verbose;
-	unsigned		suspend;
-	enum cli_status_e	result;
-	struct cli_proto	*cli_proto;
-};
-
-struct cli *cli_setup(struct event_base *eb, int fdr, int fdw, int ver, struct cli_proto *cli_proto);
-void cli_suspend(struct cli *cli);
-void cli_resume(struct cli *cli);
-void cli_encode_string(struct evbuffer *buf, char *b);
-extern struct cli_proto CLI_cmds[];

Added: trunk/varnish-cache/bin/varnishd/common_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/common_cli.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/common_cli.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -0,0 +1,67 @@
+/*
+ * $Id: cli_event.c 466 2006-07-12 23:30:49Z phk $
+ */
+
+#include <errno.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/uio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <sys/wait.h>
+
+#include "sbuf.h"
+
+#include "cli.h"
+#include "cli_priv.h"
+#include "common_cli.h"
+#include "libvarnish.h"
+
+void
+cli_out(struct cli *cli, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	sbuf_vprintf(cli->sb, fmt, ap);
+	va_end(ap);
+}
+
+void
+cli_param(struct cli *cli)
+{
+
+	cli->result = CLIS_PARAM;
+	cli_out(cli, "Parameter error, use \"help [command]\" for more info.\n");
+}
+
+void
+cli_result(struct cli *cli, unsigned res)
+{
+
+	cli->result = res;
+}
+
+int
+cli_writeres(int fd, struct cli *cli)
+{
+	int i, l;
+	struct iovec iov[3];
+	char res[32];
+
+	sprintf(res, "%d %d\n", cli->result, sbuf_len(cli->sb));
+	iov[0].iov_base = (void*)(uintptr_t)res;
+	iov[1].iov_base = (void*)(uintptr_t)sbuf_data(cli->sb);
+	iov[2].iov_base = (void*)(uintptr_t)"\n";
+	for (l = i = 0; i < 3; i++) {
+		iov[i].iov_len = strlen(iov[i].iov_base);
+		l += iov[i].iov_len;
+	}
+	i = writev(fd, iov, 3);
+	return (i != l);
+}

Copied: trunk/varnish-cache/bin/varnishd/common_cli.h (from rev 615, trunk/varnish-cache/bin/varnishd/cli_event.h)
===================================================================
--- trunk/varnish-cache/bin/varnishd/cli_event.h	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/common_cli.h	2006-08-03 09:45:14 UTC (rev 616)
@@ -0,0 +1,16 @@
+/*
+ * $Id$
+ */
+
+struct cli {
+	struct sbuf		*sb;
+	unsigned		verbose;
+	unsigned		suspend;
+	enum cli_status_e	result;
+	struct cli_proto	*cli_proto;
+};
+
+void cli_suspend(struct cli *cli);
+void cli_resume(struct cli *cli);
+int cli_writeres(int fd, struct cli *cli);
+extern struct cli_proto CLI_cmds[];

Modified: trunk/varnish-cache/bin/varnishd/mgt.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt.h	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/mgt.h	2006-08-03 09:45:14 UTC (rev 616)
@@ -4,15 +4,17 @@
 
 #include "common.h"
 
-extern struct event_base *mgt_eb;
+/* mgt_child.c */
+void mgt_run(int dflag);
+void mgt_start_child(void);
+void mgt_stop_child(void);
 
-void mgt_child_start(void);
-void mgt_child_stop(void);
-void mgt_child_kill(void);
-void mgt_sigchld(int, short, void *);
+/* mgt_cli.c */
 
-typedef void mgt_ccb_f(unsigned, const char *, void *);
-void mgt_child_request(mgt_ccb_f *, void *, char **argv, const char *fmt, ...);
+void mgt_cli_init(void);
+void mgt_cli_setup(int fdi, int fdo, int verbose);
+void mgt_cli_start_child(int fdi, int fdo);
+void mgt_cli_stop_child(void);
 
 /* tcp.c */
 int open_tcp(const char *port);

Modified: trunk/varnish-cache/bin/varnishd/mgt_child.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_child.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/mgt_child.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -4,214 +4,65 @@
  * 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 <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-
+#include <signal.h>
+#include <assert.h>
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+#include <sys/types.h>
 #include <sys/wait.h>
-#include "queue.h"
 
-#include <event.h>
-#include <sbuf.h>
+#include <err.h>		/* XXX */
 
-#include <libvarnish.h>
-#include <cli.h>
-
-#include "cli_event.h"	/* for cli_encode_string */
+#include "libvarnish.h"
 #include "heritage.h"
 #include "mgt.h"
 
+static pid_t		child_pid = -1;
+static int		child_fds[2];
+static unsigned 	child_should_run;
+static pthread_t	child_listen_thread;
+static pthread_t	child_poker_thread;
+static pthread_mutex_t	child_mtx;
+static pthread_cond_t	child_cv;
+static unsigned		child_ticker;
+
 /*--------------------------------------------------------------------*/
 
-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;
-	char			**argv;
-	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)
+static void *
+child_listener(void *arg)
 {
-	const char *p;
+	FILE *f;
+	char buf[BUFSIZ];
 
 	(void)arg;
 
-	while (1) {
-		p = evbuffer_readline(bev->input);
-		if (p == NULL)
-			return;
-		printf("Child said <%s>\n", p);
+	f = fdopen(child_fds[0], "r");
+	assert(f != NULL);
+	while (fgets(buf, sizeof buf, f)) {
+		printf("Child said: %s", buf);
 	}
+	return (NULL);
 }
 
-static void
-std_wrcb(struct bufferevent *bev, void *arg)
-{
-
-	printf("%s(%p, %p)\n",
-	    (const char *)__func__, (void*)bev, arg);
-	exit (2);
-}
-
-static void
-std_excb(struct bufferevent *bev, short what, void *arg)
-{
-
-	printf("%s(%p, %d, %p)\n",
-	    (const char *)__func__, (void*)bev, what, arg);
-	exit (2);
-}
-
-/*--------------------------------------------------------------------
- * Multiplex requests/answers to the child
- */
-
-static void
-send_req(void)
-{
-	struct creq *cr;
-	int u;
-
-	cr = TAILQ_FIRST(&creqhead);
-	if (cr == NULL)
-		return;
-	if (0)
-		printf("Send Request <%s>\n", cr->req);
-	evbuffer_add_printf(child_cli1->output, "%s", cr->req);
-	for (u = 0; cr->argv != NULL && cr->argv[u] != NULL; u++) {
-		evbuffer_add_printf(child_cli1->output, " ");
-		cli_encode_string(child_cli1->output, cr->argv[u]);
-	}
-	evbuffer_add_printf(child_cli1->output, "\n");
-	AZ(bufferevent_enable(child_cli1, EV_WRITE));
-}
-
-void
-mgt_child_request(mgt_ccb_f *func, void *priv, char **argv, 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;
-	cr->argv = argv;
-	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;
-
-	(void)arg;
-
-	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, void *arg)
-{
-
-	(void)bev;
-	(void)arg;
-}
-
-static void
-cli_excb(struct bufferevent *bev, short what, void *arg)
-{
-
-	printf("%s(%p, %d, %p)\n",
-	    (const char *)__func__, (void*)bev, what, arg);
-	exit (2);
-}
-
 /*--------------------------------------------------------------------*/
 
-static void
-child_pingpong_ccb(unsigned u, const char *r, void *priv)
+static void *
+child_poker(void *arg)
 {
-	(void)u;
-	(void)r;
-	(void)priv;
 
-	/* XXX: reset keepalive timer */
-}
-
-
-static void
-child_pingpong(int a, short b, void *c)
-{
-	time_t t;
-	struct timeval tv;
-
-	(void)a;
-	(void)b;
-	(void)c;
-
-	t = time(NULL);
-	mgt_child_request(child_pingpong_ccb, NULL, NULL, "ping %ld", t);
-	if (1) {
-		tv.tv_sec = 10;
-		tv.tv_usec = 0;
-		AZ(evtimer_del(&ev_child_pingpong));
-		AZ(evtimer_add(&ev_child_pingpong, &tv));
+	(void)arg;
+	while (1) {
+		sleep (1);
+		/* CLI: ping/pong */
+		child_ticker = 0;
 	}
 }
 
-
 /*--------------------------------------------------------------------*/
 
 static void
@@ -219,13 +70,14 @@
 {
 	int i;
 
-	assert(pipe(&heritage.fds[0]) == 0);
-	assert(pipe(&heritage.fds[2]) == 0);
-	assert(pipe(child_fds) == 0);
+	AZ(pipe(&heritage.fds[0]));
+	AZ(pipe(&heritage.fds[2]));
+	AZ(pipe(child_fds));
 	i = fork();
 	if (i < 0) 
 		errx(1, "Could not fork child");
 	if (i == 0) {
+		AZ(pthread_single_np());
 		/* Redirect stdin/out/err */
 		AZ(close(0));
 		i = open("/dev/null", O_RDONLY);
@@ -243,99 +95,119 @@
 		exit (1);
 	}
 
-	child_pid = i;
 	printf("start child pid %d\n", i);
 
 	AZ(close(child_fds[1]));
 
 	AZ(close(heritage.fds[1]));
 	AZ(close(heritage.fds[2]));
+	mgt_cli_start_child(heritage.fds[0], heritage.fds[3]);
+	child_pid = i;
+	AZ(pthread_create(&child_listen_thread, NULL, child_listener, NULL));
+	AZ(pthread_create(&child_poker_thread, NULL, child_poker, NULL));
+}
 
-	child_std = bufferevent_new(child_fds[0],
-	    std_rdcb, std_wrcb, std_excb, NULL);
-	assert(child_std != NULL);
-	AZ(bufferevent_base_set(mgt_eb, child_std));
-	bufferevent_enable(child_std, EV_READ);
+/*--------------------------------------------------------------------*/
 
-	child_cli0 = bufferevent_new(heritage.fds[0],
-	    cli_rdcb, cli_wrcb, cli_excb, NULL);
-	assert(child_cli0 != NULL);
-	AZ(bufferevent_base_set(mgt_eb, child_cli0));
-	bufferevent_enable(child_cli0, EV_READ);
+static void
+stop_child(void)
+{
 
-	child_cli1 = bufferevent_new(heritage.fds[3],
-	    cli_rdcb, cli_wrcb, cli_excb, NULL);
-	assert(child_cli1 != NULL);
-	AZ(bufferevent_base_set(mgt_eb, child_cli1));
-
-	evtimer_set(&ev_child_pingpong, child_pingpong, NULL);
-	AZ(event_base_set(mgt_eb, &ev_child_pingpong));
-	child_pingpong(0, 0, NULL);
+	exit(2);
+	/* kill child, if relevant */
+	/* join child_listen_thread */
+	/* join child_poker_thread */
+	/* close heritage.fds */
+	/* close child_fds */
 }
 
-
 /*--------------------------------------------------------------------*/
 
-void
-mgt_child_start(void)
+static void
+mgt_sigchld(int arg)
 {
+	int status;
+	pid_t r;
 
-	if (desired == H_START)
-		return;
-	desired = H_START;
-	start_child();
+	(void)arg;
+	r = wait4(-1, &status, WNOHANG, NULL);
+	if (r == child_pid) {
+		printf("Cache child died pid=%d status=0x%x\n",
+		    r, status);
+		child_pid = -1;
+	} else {
+		printf("Unknown child died pid=%d status=0x%x\n",
+		    r, status);
+	}
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * This thread is the master thread in the management process.
+ * The relatively simple task is to start and stop the child process
+ * and to reincarnate it in case of trouble.
+ */
 
 void
-mgt_child_stop(void)
+mgt_run(int dflag)
 {
+	struct timespec to;
+	struct sigaction sac;
+	int i, dstarts = 0;
 
-	if (desired == H_STOP)
-		return;
-	desired = H_STOP;
+#if 1
+	if (dflag)
+		mgt_cli_setup(0, 1, 1);
+#else
+	dflag = 0;
+#endif
+
+	sac.sa_handler = mgt_sigchld;
+	sac.sa_flags = SA_NOCLDSTOP;
+	AZ(sigaction(SIGCHLD, &sac, NULL));
+	child_should_run = !dflag;
+
+	AZ(pthread_cond_init(&child_cv, NULL));
+	AZ(pthread_mutex_init(&child_mtx, NULL));
+
+	while (1) {
+		if (!child_should_run && child_pid != -1)
+			stop_child();
+		else if (child_should_run && child_pid == -1) {
+			if (dflag && dstarts)
+				exit(2);
+			start_child();
+			dstarts = 1;
+		}
+			
+		/* XXX POSIXBRAINDAMAGE */
+		AZ(clock_gettime(CLOCK_REALTIME, &to));
+		to.tv_sec += 1;
+
+		AZ(pthread_mutex_lock(&child_mtx));
+		i = pthread_cond_timedwait(&child_cv, &child_mtx, &to);
+		AZ(pthread_mutex_unlock(&child_mtx));
+		if (i == ETIMEDOUT && ++child_ticker > 5 && child_pid != -1) {
+			stop_child();
+			if (dflag)
+				exit (2);
+		}
+	}
 }
 
 /*--------------------------------------------------------------------*/
 
 void
-mgt_child_kill(void)
+mgt_start_child(void)
 {
 
-	desired = H_STOP;
-	kill(child_pid, 9);
+	child_should_run = 1;
+	AZ(pthread_cond_signal(&child_cv));
 }
 
-/*--------------------------------------------------------------------*/
-
 void
-mgt_sigchld(int a, short b, void *c)
+mgt_stop_child(void)
 {
-	pid_t p;
-	int status;
 
-	printf("sig_chld(%d, %d, %p)\n", a, b, c);
-
-	p = wait4(-1, &status, WNOHANG, NULL);
-	if (p == 0)
-		return;
-	printf("pid = %d status = 0x%x\n", p, status);
-	assert(p == child_pid);
-
-	printf("Child died :-(\n");
-	exit (0);
-
-	bufferevent_free(child_std); /* XXX: is this enough ? */
-	child_std = NULL;
-
-	AZ(close(heritage.fds[0]));
-	AZ(close(heritage.fds[1]));
-	AZ(close(heritage.fds[2]));
-	AZ(close(heritage.fds[3]));
-	AZ(close(child_fds[0]));
-	AZ(close(child_fds[1]));
-
-	if (desired == H_START)
-		start_child();
+	child_should_run = 0;
+	AZ(pthread_cond_signal(&child_cv));
 }

Added: trunk/varnish-cache/bin/varnishd/mgt_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_cli.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/mgt_cli.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -0,0 +1,508 @@
+/*
+ * $Id$
+ *
+ * The management process' CLI handling
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+
+#include "libvarnish.h"
+#include "cli_priv.h"
+#include "cli.h"
+#include "sbuf.h"
+#include "common_cli.h"
+#include "mgt.h"
+
+static int		cli_i = -1, cli_o = -1;
+
+/*--------------------------------------------------------------------*/
+
+static void
+mcf_server_start(struct cli *cli)
+{
+
+	(void)cli;
+	mgt_start_child();
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static struct cli_proto *cli_proto;
+
+static struct cli_proto mgt_cli_proto[] = {
+	{ CLI_HELP,		cli_func_help, NULL },	/* must be first */
+	{ CLI_SERVER_START,	mcf_server_start, NULL },
+	{ CLI_CONFIG_LOAD },
+#if 0
+	{ CLI_CONFIG_LOAD,	m_cli_func_config_load, NULL },
+	{ CLI_CONFIG_INLINE,	m_cli_func_config_inline, NULL },
+	{ CLI_SERVER_STOP,	m_cli_func_server_stop, NULL },
+	{ CLI_SERVER_RESTART },
+	{ CLI_PING,		m_cli_func_ping, NULL },
+	{ CLI_STATS,		m_cli_func_stats, NULL },
+	{ CLI_ZERO },
+	{ CLI_VERBOSE,		m_cli_func_verbose, NULL },
+	{ CLI_EXIT, 		m_cli_func_exit, NULL},
+#endif
+	{ CLI_QUIT },
+	{ CLI_BYE },
+	{ NULL }
+};
+
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_cli_init(void)
+{
+	struct cli_proto *cp;
+	unsigned u, v;
+
+
+	/*
+	 * Build the joint cli_proto by combining the manager process
+	 * entries with with the cache process entries.  The latter
+	 * get a "passthough" function in the joint list
+	 */
+	u = 0;
+	for (cp = mgt_cli_proto; cp->request != NULL; cp++)
+		u++;
+	for (cp = CLI_cmds; cp->request != NULL; cp++)
+		u++;
+	cli_proto = calloc(sizeof *cli_proto, u + 1);
+	assert(cli_proto != NULL);
+	u = 0;
+	for (cp = mgt_cli_proto; cp->request != NULL; cp++)
+		cli_proto[u++] = *cp;
+	for (cp = CLI_cmds; cp->request != NULL; cp++) {
+		/* Skip any cache commands we already have in the manager */
+		for (v = 0; v < u; v++)
+			if (!strcmp(cli_proto[v].request, cp->request))
+				break;
+		if (v < u)
+			continue;
+		cli_proto[u] = *cp;
+		cli_proto[u].func = NULL;	/* XXX: pass */
+		u++;
+	}
+
+	/* Fixup the entry for 'help' entry */
+	assert(!strcmp(cli_proto[0].request, "help"));
+	cli_proto[0].priv = cli_proto;
+
+	/* XXX: open listening sockets, contact cluster server etc */
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_cli_start_child(int fdi, int fdo)
+{
+
+	cli_i = fdi;
+	cli_o = fdo;
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_cli_stop_child(void)
+{
+
+	cli_i = -1;
+	cli_o = -1;
+	/* XXX: kick any users */
+}
+
+/*--------------------------------------------------------------------*/
+
+struct cli_port {
+	int			fdi;
+	int			fdo;
+	int			verbose;
+	char			*buf;
+	unsigned		nbuf;
+	unsigned		lbuf;
+	struct cli		cli[1];
+};
+
+static void *
+mgt_cli_main(void *arg)
+{
+	struct cli_port *cp;
+	char *p;
+	int i;
+
+	assert(arg != NULL);
+	cp = arg;
+
+	cp->lbuf = 4096;
+	cp->buf = malloc(cp->lbuf);
+	assert(cp->buf != NULL);
+	cp->cli->sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+	assert(cp->cli->sb != NULL);
+	while (1) {
+		if (cp->nbuf == cp->lbuf) {
+			cp->lbuf += cp->lbuf;
+			cp->buf = realloc(cp->buf, cp->lbuf);
+			assert(cp->buf != NULL);
+		}
+		i = read(cp->fdi, cp->buf + cp->nbuf, cp->lbuf - cp->nbuf);
+		if (i <= 0)
+			break;
+		cp->nbuf += i;
+		p = strchr(cp->buf, '\n');
+		if (p == NULL)
+			continue;
+		*p = '\0';
+		sbuf_clear(cp->cli->sb);
+		cli_dispatch(cp->cli, cli_proto, cp->buf);
+		sbuf_finish(cp->cli->sb);
+		/* XXX: cp->verbose */
+		if (cli_writeres(cp->fdo, cp->cli))
+			break;
+		i = ++p - cp->buf;
+		assert(i <= cp->nbuf);
+		if (i < cp->nbuf)
+			memcpy(cp->buf, p, cp->nbuf - i);
+		cp->nbuf -= i;
+	}
+	sbuf_delete(cp->cli->sb);
+	free(cp->buf);
+	close(cp->fdi);
+	close(cp->fdo);
+	free(cp);
+	return (NULL);
+}
+
+void
+mgt_cli_setup(int fdi, int fdo, int verbose)
+{
+	struct cli_port *cp;
+	pthread_t tp;
+
+	cp = calloc(sizeof *cp, 1);
+	assert(cp != NULL);
+
+	cp->fdi = fdi;
+	cp->fdo = fdo;
+	cp->verbose = verbose;
+	AZ(pthread_create(&tp, NULL, mgt_cli_main, cp));
+	AZ(pthread_detach(tp));
+}
+
+#if 0
+
+/*--------------------------------------------------------------------
+ * Generic passthrough for CLI functions
+ */
+
+static void
+cli_passthrough_cb(unsigned u, const char *r, void *priv)
+{
+	struct cli *cli = priv;
+
+	cli_out(cli, "%s\n", r);
+	cli_result(cli, u);
+	cli_resume(cli);
+}
+
+static void
+m_cli_func_passthrough(struct cli *cli, char **av, void *priv)
+{
+
+	(void)av;
+	(void)priv;
+
+	cli_suspend(cli);
+	mgt_child_request(cli_passthrough_cb, cli, &av[2], av[1]);
+}
+
+static void
+m_cli_func_config_inline(struct cli *cli, char **av, void *priv)
+{
+	char *vf;
+	struct sbuf *sb;
+
+	(void)priv;
+
+	sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+	assert(sb != NULL);
+	vf = VCC_Compile(sb, av[3], NULL);
+	sbuf_finish(sb);
+	if (sbuf_len(sb) > 0) {
+		cli_out(cli, "%s", sbuf_data(sb));
+		sbuf_delete(sb);
+		return;
+	}
+	sbuf_delete(sb);
+	cli_suspend(cli);
+	mgt_child_request(cli_passthrough_cb, cli, NULL,
+	    "config.load %s %s", av[2], vf);
+}
+
+/* XXX: m prefix to avoid name clash */
+static void
+m_cli_func_config_load(struct cli *cli, char **av, void *priv)
+{
+	char *vf;
+	struct sbuf *sb;
+
+	(void)priv;
+
+	sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+	assert(sb != NULL);
+	vf = VCC_CompileFile(sb, av[3]);
+	sbuf_finish(sb);
+	if (sbuf_len(sb) > 0) {
+		cli_out(cli, "%s", sbuf_data(sb));
+		sbuf_delete(sb);
+		return;
+	}
+	sbuf_delete(sb);
+	cli_suspend(cli);
+	mgt_child_request(cli_passthrough_cb, cli, NULL,
+	    "config.load %s %s", av[2], vf);
+}
+
+static char *
+vcl_file(const char *fflag)
+{
+	char *vf;
+	struct sbuf *sb;
+
+	sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+	assert(sb != NULL);
+	vf = VCC_CompileFile(sb, fflag);
+	sbuf_finish(sb);
+	if (sbuf_len(sb) > 0) {
+		fprintf(stderr, "%s", sbuf_data(sb));
+		sbuf_delete(sb);
+		return (NULL);
+	}
+	sbuf_delete(sb);
+	return (vf);
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static void
+m_cli_func_server_start(struct cli *cli, char **av, void *priv)
+{
+
+	(void)cli;
+	(void)av;
+	(void)priv;
+
+	mgt_child_start();
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+m_cli_func_server_stop(struct cli *cli, char **av, void *priv)
+{
+
+	(void)cli;
+	(void)av;
+	(void)priv;
+
+	mgt_child_stop();
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+m_cli_func_exit(struct cli *cli, char **av, void *priv)
+{
+
+	(void)cli;
+	(void)av;
+	(void)priv;
+	mgt_child_kill();
+	exit (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+m_cli_func_verbose(struct cli *cli, char **av, void *priv)
+{
+
+	(void)av;
+	(void)priv;
+
+	cli->verbose = !cli->verbose;
+}
+
+
+static void
+m_cli_func_ping(struct cli *cli, char **av, void *priv)
+{
+	time_t t;
+
+	(void)priv;
+
+	if (av[2] != NULL) {
+		cli_out(cli, "Got your %s\n", av[2]);
+	} 
+	t = time(NULL);
+	cli_out(cli, "PONG %ld\n", t);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+m_cli_func_stats(struct cli *cli, char **av, void *priv)
+{
+
+	(void)av;
+	(void)priv;
+
+	assert (VSL_stats != NULL);
+#define MAC_STAT(n,t,f,d) \
+    cli_out(cli, "%12ju  " d "\n", (VSL_stats->n));
+#include "stat_field.h"
+#undef MAC_STAT
+}
+
+/*--------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------*/
+
+/* for development purposes */
+#include <printf.h>
+
+int
+main(int argc, char *argv[])
+{
+	int o;
+	const char *portnumber = "8080";
+	unsigned dflag = 0;
+	const char *bflag = NULL;
+	const char *fflag = NULL;
+	const char *sflag = "file";
+	const char *hflag = "classic";
+
+	(void)register_printf_render_std((const unsigned char *)"HVQ");
+
+	setbuf(stdout, NULL);
+	setbuf(stderr, NULL);
+ 
+	VCC_InitCompile(default_vcl);
+
+	heritage.default_ttl = 120;
+	heritage.wthread_min = 1;
+	heritage.wthread_max = UINT_MAX;
+	heritage.wthread_timeout = 10;
+	heritage.mem_workspace = 4096;
+
+	while ((o = getopt(argc, argv, "b:df:h:p:s:t:w:")) != -1)
+		switch (o) {
+		case 'b':
+			bflag = optarg;
+			break;
+		case 'd':
+			dflag++;
+			break;
+		case 'f':
+			fflag = optarg;
+			break;
+		case 'h':
+			hflag = optarg;
+			break;
+		case 'p':
+			portnumber = optarg;
+			break;
+		case 's':
+			sflag = optarg;
+			break;
+		case 't':
+			heritage.default_ttl = strtoul(optarg, NULL, 0);
+			break;
+		case 'w':
+			tackle_warg(optarg);
+			break;
+		default:
+			usage();
+		}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 0) {
+		fprintf(stderr, "Too many arguments\n");
+		usage();
+	}
+
+	if (bflag != NULL && fflag != NULL) {
+		fprintf(stderr, "Only one of -b or -f can be specified\n");
+		usage();
+	}
+	if (bflag == NULL && fflag == NULL) {
+		fprintf(stderr, "One of -b or -f must be specified\n");
+		usage();
+	}
+
+	if (bflag != NULL)
+		heritage.vcl_file = vcl_default(bflag);
+	else
+		heritage.vcl_file = vcl_file(fflag);
+	if (heritage.vcl_file == NULL)
+		exit (1);
+
+	setup_storage(sflag);
+	setup_hash(hflag);
+
+	/*
+	 * XXX: Lacking the suspend/resume facility (due to the socket API
+	 * missing an unlisten(2) facility) we may want to push this into
+	 * the child to limit the amount of time where the socket(s) exists
+	 * but do not answer.  That, on the other hand, would eliminate the
+	 * possibility of doing a "no-glitch" restart of the child process.
+	 */
+	open_tcp(portnumber);
+
+	VSL_MgtInit(SHMLOG_FILENAME, 8*1024*1024);
+
+	if (dflag)
+		DebugStunt();
+	daemon(dflag, dflag);
+	if (dflag)
+		printf("%d\n%d\n%d\n", getpid(), getsid(0), getpgrp());
+
+	{
+	struct event e_sigchld;
+	struct cli *cli;
+	int i;
+
+	mgt_eb = event_init();
+	assert(mgt_eb != NULL);
+
+	if (dflag)
+		cli = cli_setup(mgt_eb, 0, 1, 1, cli_proto);
+
+	signal_set(&e_sigchld, SIGCHLD, mgt_sigchld, NULL);
+	AZ(event_base_set(mgt_eb, &e_sigchld));
+	AZ(signal_add(&e_sigchld, NULL));
+
+	mgt_child_start();
+
+	i = event_base_loop(mgt_eb, 0);
+	if (i != 0)
+		printf("event_dispatch() = %d\n", i);
+
+	}
+
+	exit(0);
+}
+#endif

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2006-08-03 06:45:58 UTC (rev 615)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2006-08-03 09:45:14 UTC (rev 616)
@@ -17,20 +17,17 @@
 #include <time.h>
 #include <unistd.h>
 
-#include <sys/wait.h>
-
-#include "event.h"
 #include "sbuf.h"
 
-#include <cli.h>
-#include <cli_priv.h>
-#include <libvarnish.h>
-#include <libvcl.h>
+#include "libvarnish.h"
+#include "libvcl.h"
+#include "cli.h"
+#include "cli_priv.h"
+#include "common_cli.h"
 
 #include "mgt.h"
 #include "heritage.h"
 #include "shmlog.h"
-#include "cli_event.h"
 
 /*--------------------------------------------------------------------*/
 
@@ -75,8 +72,8 @@
 /*--------------------------------------------------------------------*/
 
 struct heritage heritage;
-struct event_base *mgt_eb;
 
+#if 0
 /*--------------------------------------------------------------------
  * Generic passthrough for CLI functions
  */
@@ -101,6 +98,7 @@
 	cli_suspend(cli);
 	mgt_child_request(cli_passthrough_cb, cli, &av[2], av[1]);
 }
+#endif
 
 /*--------------------------------------------------------------------*/
 
@@ -149,7 +147,7 @@
 	free(buf);
 	return (vf);
 }
-
+#if 0
 static void
 m_cli_func_config_inline(struct cli *cli, char **av, void *priv)
 {
@@ -196,6 +194,7 @@
 	mgt_child_request(cli_passthrough_cb, cli, NULL,
 	    "config.load %s %s", av[2], vf);
 }
+#endif
 
 static char *
 vcl_file(const char *fflag)
@@ -216,6 +215,7 @@
 	return (vf);
 }
 
+#if 0
 
 /*--------------------------------------------------------------------*/
 
@@ -329,6 +329,7 @@
 	{ NULL }
 };
 
+#endif
 
 /*--------------------------------------------------------------------*/
 
@@ -585,6 +586,7 @@
 
 /*--------------------------------------------------------------------*/
 
+
 /* for development purposes */
 #include <printf.h>
 
@@ -686,28 +688,9 @@
 	if (dflag)
 		printf("%d\n%d\n%d\n", getpid(), getsid(0), getpgrp());
 
-	{
-	struct event e_sigchld;
-	struct cli *cli;
-	int i;
+	mgt_cli_init();
 
-	mgt_eb = event_init();
-	assert(mgt_eb != NULL);
+	mgt_run(dflag);
 
-	if (dflag)
-		cli = cli_setup(mgt_eb, 0, 1, 1, cli_proto);
-
-	signal_set(&e_sigchld, SIGCHLD, mgt_sigchld, NULL);
-	AZ(event_base_set(mgt_eb, &e_sigchld));
-	AZ(signal_add(&e_sigchld, NULL));
-
-	mgt_child_start();
-
-	i = event_base_loop(mgt_eb, 0);
-	if (i != 0)
-		printf("event_dispatch() = %d\n", i);
-
-	}
-
 	exit(0);
 }




More information about the varnish-commit mailing list