]> err.no Git - varnish/commitdiff
Make it possible to suspend and resume a cli connection while we wait
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 17 Mar 2006 13:41:32 +0000 (13:41 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 17 Mar 2006 13:41:32 +0000 (13:41 +0000)
for response from the child (or otherwise).

Add a generic "pass-through" handler for cli requests we just pass on
to the child.

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

varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cli_event.c
varnish-cache/bin/varnishd/cli_event.h
varnish-cache/bin/varnishd/mgt.h
varnish-cache/bin/varnishd/mgt_child.c
varnish-cache/bin/varnishd/varnishd.c

index 74d2b78c339eb8014517d97e2810da03677888de..1f36273cd5fad0fc2640d86af2d45576b1de9589 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <stdio.h>
+#include <unistd.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <sys/time.h>
@@ -42,6 +43,17 @@ arm_keepalive(void)
 
 /*--------------------------------------------------------------------*/
 
+static void
+cli_func_url_query(struct cli *cli, char **av, void *priv __unused)
+{
+
+       cli_out(cli, "url <%s>", av[2]);
+       sleep(1);
+       cli_result(cli, CLIS_UNIMPL);
+}
+
+/*--------------------------------------------------------------------*/
+
 static void
 cli_func_ping(struct cli *cli, char **av, void *priv __unused)
 {
@@ -59,6 +71,7 @@ cli_func_ping(struct cli *cli, char **av, void *priv __unused)
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto cli_proto[] = {
+       { CLI_URL_QUERY,        cli_func_url_query },
        { CLI_PING,             cli_func_ping },
        { NULL }
 };
index 70c83a8d4ad4f9d8d3be81583f00d868ad575492..8b8d6f6f0b79650d2ae0d19d7e6c20b0d6a450dc 100644 (file)
 #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, ...)
 {
@@ -51,7 +74,6 @@ cli_result(struct cli *cli, unsigned res)
 static void
 encode_output(struct cli *cli)
 {
-       char *p, *q;
 
        if (cli->verbose) {
                if (cli->result != CLIS_OK)
@@ -63,21 +85,9 @@ encode_output(struct cli *cli)
                        evbuffer_add_printf(cli->bev1->output, "OK\n");
                return;
        }
-       evbuffer_add_printf(cli->bev1->output, "%d \"", cli->result);
-       for (p = q = sbuf_data(cli->sb); *p != '\0'; p++) {
-               if ((*p != '"' && *p != '\\' && isgraph(*p)) || *p == ' ')
-                       continue;
-               if (p != q) 
-                       evbuffer_add(cli->bev1->output, q, p - q);
-               if (*p == '\n')
-                       evbuffer_add_printf(cli->bev1->output, "\\n");
-               else
-                       evbuffer_add_printf(cli->bev1->output, "\\x%02x", *p);
-               q = p + 1;
-       }
-       if (p != q) 
-               evbuffer_add(cli->bev1->output, q, p - q);
-       evbuffer_add_printf(cli->bev1->output, "\"\n");
+       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
@@ -91,10 +101,12 @@ rdcb(struct bufferevent *bev, void *arg)
                return;
        sbuf_clear(cli->sb);
        cli_dispatch(cli, cli->cli_proto, p);
-       sbuf_finish(cli->sb);
-       /* XXX: syslog results ? */
-       encode_output(cli);
-       bufferevent_enable(cli->bev1, EV_WRITE);
+       if (!cli->suspend) {
+               sbuf_finish(cli->sb);
+               /* XXX: syslog results ? */
+               encode_output(cli);
+               bufferevent_enable(cli->bev1, EV_WRITE);
+       }
 }
 
 static void
@@ -135,3 +147,23 @@ cli_setup(int fdr, int fdw, int ver, struct cli_proto *cli_proto)
        bufferevent_enable(cli->bev0, EV_READ);
        return (cli);
 }
+
+void
+cli_suspend(struct cli *cli)
+{
+
+       cli->suspend = 1;
+       bufferevent_disable(cli->bev0, EV_READ);
+}
+
+void
+cli_resume(struct cli *cli)
+{
+       sbuf_finish(cli->sb);
+       /* XXX: syslog results ? */
+       encode_output(cli);
+       bufferevent_enable(cli->bev1, EV_WRITE);
+       cli->suspend = 0;
+       bufferevent_enable(cli->bev0, EV_READ);
+}
+
index 4e17cd97553f7c55eaf92bfe41af885f76fe79eb..dae3eee25c9fcf6c70ae8f0bef1d99837ad43e1c 100644 (file)
@@ -6,9 +6,12 @@ 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(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);
index b903e032109c3a188ec7e6d95536ffec60b723ce..255c23d0f5e4daaaba2cf19d3a0d181adb059877 100644 (file)
@@ -9,4 +9,4 @@ 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, ...);
+void mgt_child_request(mgt_ccb_f *, void *, char **argv, const char *fmt, ...);
index 1e2251ebbb4c60c2279f76c8fe73b81445b1219a..3db88f91b872c696424a316838599e5fe5a8d149 100644 (file)
@@ -24,6 +24,7 @@
 #include <libvarnish.h>
 #include <cli.h>
 
+#include "cli_event.h" /* for cli_encode_string */
 #include "heritage.h"
 #include "mgt.h"
 
@@ -45,6 +46,7 @@ static struct event ev_child_pingpong;
 struct creq {
        TAILQ_ENTRY(creq)       list;
        char                    *req;
+       char                    **argv;
        mgt_ccb_f               *func;
        void                    *priv;
 };
@@ -90,17 +92,23 @@ static void
 send_req(void)
 {
        struct creq *cr;
+       int u;
 
        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);
+       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");
        bufferevent_enable(child_cli1, EV_WRITE);
 }
 
 void
-mgt_child_request(mgt_ccb_f *func, void *priv, const char *fmt, ...)
+mgt_child_request(mgt_ccb_f *func, void *priv, char **argv, const char *fmt, ...)
 {
        struct creq *cr;
        va_list ap;
@@ -110,6 +118,7 @@ mgt_child_request(mgt_ccb_f *func, void *priv, const char *fmt, ...)
        assert(cr != NULL);
        cr->func = func;
        cr->priv = priv;
+       cr->argv = argv;
        va_start(ap, fmt);
        vasprintf(&cr->req, fmt, ap);
        va_end(ap);
@@ -175,7 +184,7 @@ child_pingpong(int a, short b, void *c)
 
        printf("%s(%d, %d, %p)\n", __func__, a, b, c);
        time(&t);
-       mgt_child_request(child_pingpong_ccb, NULL, "ping %ld", t);
+       mgt_child_request(child_pingpong_ccb, NULL, NULL, "ping %ld", t);
        if (1) {
                tv.tv_sec = 3;
                tv.tv_usec = 0;
index 422337e52fbd03bf022bb8a36dac50f925825871..ee340958b7464f0a08d874d4bca14352ee61f72e 100644 (file)
 struct heritage heritage;
 struct event_base *eb;
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Generic passthrough for CLI functions
+ */
 
 void
-xxx_ccb(unsigned u, const char *r, void *priv)
+cli_passthrough_cb(unsigned u, const char *r, void *priv)
 {
-       printf("%s(%u, %s, %p)\n", __func__, u, r, priv);
-}
+       struct cli *cli = priv;
 
-/*--------------------------------------------------------------------*/
+       cli_out(cli, "%s\n", r);
+       cli_result(cli, u);
+       cli_resume(cli);
+}
 
 static void
-cli_func_url_query(struct cli *cli, char **av __unused, void *priv __unused)
+cli_func_passthrough(struct cli *cli, char **av __unused, void *priv)
 {
 
-       mgt_child_request(xxx_ccb, NULL, "url.query %s", av[2]);
+       cli_suspend(cli);
+       mgt_child_request(cli_passthrough_cb, cli, &av[2], av[1]);
 }
 
 /*--------------------------------------------------------------------*/
@@ -94,18 +99,18 @@ cli_func_ping(struct cli *cli, char **av, void *priv __unused)
 
 static struct cli_proto cli_proto[] = {
        /* URL manipulation */
-       { CLI_URL_QUERY,        cli_func_url_query, NULL },
-       { CLI_URL_PURGE },
-       { CLI_URL_STATUS },
+       { CLI_URL_QUERY,        cli_func_passthrough, NULL },
+       { CLI_URL_PURGE,        cli_func_passthrough, NULL },
+       { CLI_URL_STATUS,       cli_func_passthrough, NULL },
        { 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_FREEZE,    cli_func_passthrough, NULL },
+       { CLI_SERVER_THAW,      cli_func_passthrough, NULL },
+       { CLI_SERVER_SUSPEND,   cli_func_passthrough, NULL },
+       { CLI_SERVER_RESUME,    cli_func_passthrough, NULL },
        { CLI_SERVER_STOP,      cli_func_server_stop, NULL },
        { CLI_SERVER_START,     cli_func_server_start, NULL },
        { CLI_SERVER_RESTART },