From a14d3b17116e1e2905e0fa9eb2739fc0de57aba7 Mon Sep 17 00:00:00 2001 From: phk Date: Fri, 17 Mar 2006 13:41:32 +0000 Subject: [PATCH] Make it possible to suspend and resume a cli connection while we wait 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 | 13 +++++ varnish-cache/bin/varnishd/cli_event.c | 72 ++++++++++++++++++------- varnish-cache/bin/varnishd/cli_event.h | 5 +- varnish-cache/bin/varnishd/mgt.h | 2 +- varnish-cache/bin/varnishd/mgt_child.c | 15 ++++-- varnish-cache/bin/varnishd/varnishd.c | 33 +++++++----- 6 files changed, 101 insertions(+), 39 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_main.c b/varnish-cache/bin/varnishd/cache_main.c index 74d2b78c..1f36273c 100644 --- a/varnish-cache/bin/varnishd/cache_main.c +++ b/varnish-cache/bin/varnishd/cache_main.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -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 } }; diff --git a/varnish-cache/bin/varnishd/cli_event.c b/varnish-cache/bin/varnishd/cli_event.c index 70c83a8d..8b8d6f6f 100644 --- a/varnish-cache/bin/varnishd/cli_event.c +++ b/varnish-cache/bin/varnishd/cli_event.c @@ -23,6 +23,29 @@ #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); +} + diff --git a/varnish-cache/bin/varnishd/cli_event.h b/varnish-cache/bin/varnishd/cli_event.h index 4e17cd97..dae3eee2 100644 --- a/varnish-cache/bin/varnishd/cli_event.h +++ b/varnish-cache/bin/varnishd/cli_event.h @@ -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); diff --git a/varnish-cache/bin/varnishd/mgt.h b/varnish-cache/bin/varnishd/mgt.h index b903e032..255c23d0 100644 --- a/varnish-cache/bin/varnishd/mgt.h +++ b/varnish-cache/bin/varnishd/mgt.h @@ -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, ...); diff --git a/varnish-cache/bin/varnishd/mgt_child.c b/varnish-cache/bin/varnishd/mgt_child.c index 1e2251eb..3db88f91 100644 --- a/varnish-cache/bin/varnishd/mgt_child.c +++ b/varnish-cache/bin/varnishd/mgt_child.c @@ -24,6 +24,7 @@ #include #include +#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; diff --git a/varnish-cache/bin/varnishd/varnishd.c b/varnish-cache/bin/varnishd/varnishd.c index 422337e5..ee340958 100644 --- a/varnish-cache/bin/varnishd/varnishd.c +++ b/varnish-cache/bin/varnishd/varnishd.c @@ -33,21 +33,26 @@ 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 }, -- 2.39.5