]> err.no Git - varnish/commitdiff
Expand the empty shell a bit.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 16 Mar 2006 10:48:50 +0000 (10:48 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 16 Mar 2006 10:48:50 +0000 (10:48 +0000)
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.

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

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

index 4c8f6cf5cbc2e9453f15108e632841fd892be134..507e5c54de8d9775a67adf5fe470746ebb65d9c9 100644 (file)
@@ -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
diff --git a/varnish-cache/bin/varnishd/cache_main.c b/varnish-cache/bin/varnishd/cache_main.c
new file mode 100644 (file)
index 0000000..0aafb32
--- /dev/null
@@ -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");
+}
+
diff --git a/varnish-cache/bin/varnishd/heritage.h b/varnish-cache/bin/varnishd/heritage.h
new file mode 100644 (file)
index 0000000..aaf0e71
--- /dev/null
@@ -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);
index ffa9ebae5acd7ea719d106aeb77623c5e5643ff7..2d81c1f1ad4a47efeff69b10078b7a6e6602d0ae 100644 (file)
@@ -3,9 +3,239 @@
  */
 
 #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)
@@ -26,6 +256,8 @@ usage(void)
        exit(1);
 }
 
+/*--------------------------------------------------------------------*/
+
 int
 main(int argc, char *argv[])
 {
@@ -51,5 +283,8 @@ main(int argc, char *argv[])
        if (argc != 0)
                usage();
 
+       testme();
+
+
        exit(0);
 }