r56 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Thu Mar 16 11:48:50 CET 2006


Author: phk
Date: 2006-03-16 11:48:50 +0100 (Thu, 16 Mar 2006)
New Revision: 56

Added:
   trunk/varnish-cache/bin/varnishd/cache_main.c
   trunk/varnish-cache/bin/varnishd/heritage.h
Modified:
   trunk/varnish-cache/bin/varnishd/Makefile.am
   trunk/varnish-cache/bin/varnishd/varnishd.c
Log:
Expand the empty shell a bit.

Add CLI handler on stdin (for now, in production only if
debug is specified).

Implement help, verbos, ping and start.

start forks the child process, sets up listeners on its stdout/stderr
(where nothing should arrive in production).

Add SIGCHLD handler to reap and restart the child.

Add shell "main" for the child:  Set up a CLI handler on the pipes
passed as heritage.

Add ping command and keepalive timeout.



Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am	2006-03-16 10:46:01 UTC (rev 55)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am	2006-03-16 10:48:50 UTC (rev 56)
@@ -1,10 +1,15 @@
 # $Id$
 
-INCLUDES = -I$(top_srcdir)/include
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/contrib/libevent
 
 bin_PROGRAMS = varnishd
 
 varnishd_SOURCES = \
+	cache_main.c \
+	cli_event.c \
 	varnishd.c
 
-#varnishd_LDADD = $(top_builddir)/lib/libvarnish/libvarnish.la
+varnishd_LDADD = \
+	$(top_builddir)/lib/libvarnish/libvarnish.la \
+	$(top_builddir)/lib/libsbuf/libsbuf.la \
+	$(top_builddir)/contrib/libevent/libevent.la

Added: trunk/varnish-cache/bin/varnishd/cache_main.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_main.c	2006-03-16 10:46:01 UTC (rev 55)
+++ trunk/varnish-cache/bin/varnishd/cache_main.c	2006-03-16 10:48:50 UTC (rev 56)
@@ -0,0 +1,87 @@
+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#include <event.h>
+
+#include <cli.h>
+#include <cli_priv.h>
+
+#include "heritage.h"
+
+static struct event ev_keepalive;
+
+/*--------------------------------------------------------------------*/
+
+static void
+timer_keepalive(int a, short b, void *c)
+{
+
+	printf("%s(%d, %d, %p)\n", __func__, a, b, c);
+	printf("Heeellloooo ?   Ohh bother...\n");
+	exit (1);
+}
+
+static void
+arm_keepalive(void)
+{
+	struct timeval tv;
+
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+
+	evtimer_del(&ev_keepalive);
+	evtimer_add(&ev_keepalive, &tv);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+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]);
+	time(&t);
+	cli_out(cli, "PONG %ld\n", t);
+}
+
+/*--------------------------------------------------------------------*/
+
+static struct cli_proto cli_proto[] = {
+	{ CLI_PING },
+	{ NULL }
+};
+
+void
+child_main(void)
+{
+	struct event_base *eb;
+	struct cli *cli;
+	int i;
+
+	setbuf(stdout, NULL);
+	setbuf(stderr, NULL);
+	printf("Child starts\n");
+
+	eb = event_init();
+	assert(eb != NULL);
+
+	cli = cli_setup(heritage.fds[0], heritage.fds[1], 0, cli_proto);
+
+	evtimer_set(&ev_keepalive, timer_keepalive, NULL);
+	arm_keepalive();
+
+	i = event_dispatch();
+	if (i != 0)
+		printf("event_dispatch() = %d\n", i);
+
+	printf("Child dies\n");
+}
+

Added: trunk/varnish-cache/bin/varnishd/heritage.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/heritage.h	2006-03-16 10:46:01 UTC (rev 55)
+++ trunk/varnish-cache/bin/varnishd/heritage.h	2006-03-16 10:48:50 UTC (rev 56)
@@ -0,0 +1,13 @@
+/*
+ * $Id$
+ *
+ * This file contains the heritage passed when mgt forks cache
+ */
+
+struct heritage {
+	int	fds[2];
+};
+
+extern struct heritage heritage;
+
+void child_main(void);

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2006-03-16 10:46:01 UTC (rev 55)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2006-03-16 10:48:50 UTC (rev 56)
@@ -3,11 +3,241 @@
  */
 
 #include <errno.h>
+#include <assert.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <signal.h>
+#include <fcntl.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"
+
+/*--------------------------------------------------------------------*/
+
+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__, bev, arg);
+	exit (2);
+}
+
+static void
+std_excb(struct bufferevent *bev, short what, void *arg)
+{
+
+	printf("%s(%p, %d, %p)\n", __func__, bev, what, arg);
+	exit (2);
+}
+
+
+
+/*--------------------------------------------------------------------*/
+
+static void
+start_child(void)
+{
+	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);
+}
+
+/*--------------------------------------------------------------------*/
+
+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();
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+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
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+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)
+{
+	time_t t;
+
+	if (av[2] != NULL) {
+		cli_out(cli, "Got your %s\n", av[2]);
+	} 
+	time(&t);
+	cli_out(cli, "PONG %ld\n", t);
+}
+
+/*--------------------------------------------------------------------*/
+
+static struct cli_proto cli_proto[] = {
+	/* URL manipulation */
+	{ CLI_URL_QUERY },
+	{ CLI_URL_PURGE },
+	{ CLI_URL_STATUS },
+	{ CLI_CONFIG_LOAD },
+	{ CLI_CONFIG_INLINE },
+	{ CLI_CONFIG_UNLOAD },
+	{ CLI_CONFIG_LIST },
+	{ CLI_CONFIG_USE },
+	{ CLI_SERVER_FREEZE },
+	{ CLI_SERVER_THAW },
+	{ CLI_SERVER_SUSPEND },
+	{ CLI_SERVER_RESUME },
+	{ CLI_SERVER_STOP,	cli_func_server_stop, NULL },
+	{ CLI_SERVER_START,	cli_func_server_start, NULL },
+	{ CLI_SERVER_RESTART },
+	{ CLI_PING,		cli_func_ping, NULL },
+	{ CLI_STATS },
+	{ CLI_ZERO },
+	{ CLI_HELP,		cli_func_help, cli_proto },
+	{ CLI_VERBOSE,		cli_func_verbose, NULL },
+	{ CLI_EXIT },
+	{ CLI_QUIT },
+	{ CLI_BYE },
+	{ NULL }
+};
+
+static void
+testme(void)
+{
+	struct event e_sigchld;
+	struct cli *cli;
+	int i;
+
+	eb = event_init();
+	assert(eb != NULL);
+
+	cli = cli_setup(0, 1, 1, cli_proto);
+
+	signal_set(&e_sigchld, SIGCHLD, sig_chld, NULL);
+	signal_add(&e_sigchld, NULL);
+
+	i = event_dispatch();
+	if (i != 0)
+		printf("event_dispatch() = %d\n", i);
+
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
 usage(void)
 {
 	fprintf(stderr, "usage: varnishd [options]\n");
@@ -26,6 +256,8 @@
 	exit(1);
 }
 
+/*--------------------------------------------------------------------*/
+
 int
 main(int argc, char *argv[])
 {
@@ -51,5 +283,8 @@
 	if (argc != 0)
 		usage();
 
+	testme();
+
+
 	exit(0);
 }




More information about the varnish-commit mailing list