From: phk Date: Wed, 12 Mar 2008 10:25:51 +0000 (+0000) Subject: Rework the manager/cacher cli relationship, so that the manager does X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=73322d5664423c9bda8fa55f4d3c1e5b877f293e;p=varnish Rework the manager/cacher cli relationship, so that the manager does not have to grope around in the cacher's data structures. Whenever the manager gets a CLI command it does not understand, it will pass it to the cacher process, if it is running. This complicated "help" a little bit, because we want to show the combined commands of the manager and cacher. Since we're dealing with help anyway, hide undocumented debug commands from it. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2595 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_cli.c b/varnish-cache/bin/varnishd/cache_cli.c index 493eb8d5..13628802 100644 --- a/varnish-cache/bin/varnishd/cache_cli.c +++ b/varnish-cache/bin/varnishd/cache_cli.c @@ -85,29 +85,69 @@ cli_func_start(struct cli *cli, const char * const *av, void *priv) return; } - /*--------------------------------------------------------------------*/ -struct cli_proto CLI_cmds[] = { +static void ccf_help(struct cli *cli, const char * const *av, void *priv); + +/*-------------------------------------------------------------------- + * The CLI commandlist is split in three: + * Commands we get from/share with the manager + * Cache process commands + * Undocumented commands + */ + +static struct cli_proto master_cmds[] = { { CLI_PING, cli_func_ping }, { CLI_SERVER_START, cli_func_start }, -#if 0 - { CLI_URL_QUERY, cli_func_url_query }, -#endif - { CLI_URL_PURGE, cli_func_url_purge }, - { CLI_HASH_PURGE, cli_func_hash_purge }, { CLI_VCL_LOAD, cli_func_config_load }, { CLI_VCL_LIST, cli_func_config_list }, { CLI_VCL_DISCARD, cli_func_config_discard }, { CLI_VCL_USE, cli_func_config_use }, + { NULL } +}; - /* Undocumented functions for debugging */ +static struct cli_proto cacher_cmds[] = { + { CLI_HELP, ccf_help, NULL }, + { CLI_URL_PURGE, cli_func_url_purge }, + { CLI_HASH_PURGE, cli_func_hash_purge }, +#if 0 + { CLI_URL_QUERY, cli_func_url_query }, +#endif + { NULL } +}; + +static struct cli_proto undoc_cmds[] = { { "debug.sizeof", "debug.sizeof", "\tDump sizeof various data structures\n", 0, 0, cli_debug_sizeof }, { NULL } }; + +/*--------------------------------------------------------------------*/ + +static void +ccf_help(struct cli *cli, const char * const *av, void *priv) +{ + + (void)priv; + /* "+1" to skip "help" entry, manager already did that. */ + cli_func_help(cli, av, cacher_cmds + 1); + + if (av[2] != NULL && !strcmp(av[2], "-d")) { + /* Also list undocumented commands */ + cli_out(cli, "\nDebugging commands:\n"); + cli_func_help(cli, av, undoc_cmds); + } else if (cli->result == CLIS_UNKNOWN) { + /* Otherwise, try the undocumented list */ + vsb_clear(cli->sb); + cli->result = CLIS_OK; + cli_func_help(cli, av, undoc_cmds); + } +} + +/*--------------------------------------------------------------------*/ + static int cli_vlu(void *priv, const char *p) { @@ -117,7 +157,17 @@ cli_vlu(void *priv, const char *p) cli = priv; VSL(SLT_CLI, 0, "Rd %s", p); vsb_clear(cli->sb); - cli_dispatch(cli, CLI_cmds, p); + cli_dispatch(cli, master_cmds, p); + if (cli->result == CLIS_UNKNOWN) { + vsb_clear(cli->sb); + cli->result = CLIS_OK; + cli_dispatch(cli, cacher_cmds, p); + } + if (cli->result == CLIS_UNKNOWN) { + vsb_clear(cli->sb); + cli->result = CLIS_OK; + cli_dispatch(cli, undoc_cmds, p); + } vsb_finish(cli->sb); AZ(vsb_overflowed(cli->sb)); i = cli_writeres(heritage.fds[1], cli); diff --git a/varnish-cache/bin/varnishd/mgt_cli.c b/varnish-cache/bin/varnishd/mgt_cli.c index 5f003493..eed2b430 100644 --- a/varnish-cache/bin/varnishd/mgt_cli.c +++ b/varnish-cache/bin/varnishd/mgt_cli.c @@ -78,73 +78,30 @@ mcf_stats(struct cli *cli, const char * const *av, void *priv) #undef MAC_STAT } - -/*-------------------------------------------------------------------- - * Passthru of cli commands. It is more or less just undoing what - * the cli parser did, but such is life... - */ - static void -mcf_passthru(struct cli *cli, const char * const *av, void *priv) +mcf_help(struct cli *cli, const char * const *av, void *priv) { - struct vsb *sb; - const char *p; - char *q; unsigned u; - int i; - - (void)priv; + char *p; - /* Request */ - if (cli_o <= 0) { - cli_result(cli, CLIS_CANT); - cli_out(cli, "Cache process not running"); - return; - } - sb = vsb_new(NULL, NULL, 64, VSB_AUTOEXTEND); - XXXAN(sb); - for (u = 1; av[u] != NULL; u++) { - if (u > 1) - vsb_putc(sb, ' '); - vsb_putc(sb, '"'); - for (p = av[u]; *p; p++) { - switch (*p) { - case '\\': - vsb_cat(sb, "\\\\"); - break; - case '\n': - vsb_cat(sb, "\\n"); - break; - case '"': - vsb_cat(sb, "\\\""); - break; - default: - vsb_putc(sb, *p); - } - } - vsb_putc(sb, '"'); + cli_func_help(cli, av, priv); + if (cli_o >= 0 && (av[2] == NULL || *av[2] == '-')) { + p = NULL; + if (!mgt_cli_askchild(&u, &p, + "help %s\n", av[2] != NULL ? av[2] : "")) { + cli_out(cli, "%s", p); + cli_result(cli, u); + } + free(p); } - vsb_putc(sb, '\n'); - xxxassert(!vsb_overflowed(sb)); - vsb_finish(sb); - AZ(vsb_overflowed(sb)); - i = write(cli_o, vsb_data(sb), vsb_len(sb)); - xxxassert(i == vsb_len(sb)); - vsb_delete(sb); - - i = cli_readres(cli_i, &u, &q, params->cli_timeout); - cli_result(cli, u); - cli_out(cli, "%s", q); - free(q); - } /*--------------------------------------------------------------------*/ -static struct cli_proto *cli_proto; /* XXX: what order should this list be in ? */ -static struct cli_proto mgt_cli_proto[] = { +static struct cli_proto cli_proto[] = { + { CLI_HELP, mcf_help, cli_proto }, { CLI_PING, cli_func_ping }, { CLI_SERVER_STATUS, mcf_server_status, NULL }, { CLI_SERVER_START, mcf_server_startstop, NULL }, @@ -158,7 +115,6 @@ static struct cli_proto mgt_cli_proto[] = { { CLI_VCL_SHOW, mcf_config_show, NULL }, { CLI_PARAM_SHOW, mcf_param_show, NULL }, { CLI_PARAM_SET, mcf_param_set, NULL }, - { CLI_HELP, cli_func_help, NULL }, #if 0 { CLI_SERVER_RESTART }, { CLI_ZERO }, @@ -170,59 +126,13 @@ static struct cli_proto mgt_cli_proto[] = { { 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); - XXXAN(cli_proto); - 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 = mcf_passthru; - u++; - } - - /* Fixup the entry for 'help' entry */ - for (u = 0; cli_proto[u].request != NULL; u++) { - if (!strcmp(cli_proto[u].request, "help")) { - cli_proto[u].priv = cli_proto; - break; - } - } -} - /*-------------------------------------------------------------------- * Ask the child something over CLI, return zero only if everything is * happy happy. */ int -mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...) -{ +mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...) { char *p; int i, j; va_list ap; @@ -319,12 +229,41 @@ static int mgt_cli_vlu(void *priv, const char *p) { struct cli_port *cp; + char *q; + unsigned u; + int i; CAST_OBJ_NOTNULL(cp, priv, CLI_PORT_MAGIC); vsb_clear(cp->cli->sb); cli_dispatch(cp->cli, cli_proto, p); vsb_finish(cp->cli->sb); AZ(vsb_overflowed(cp->cli->sb)); + if (cp->cli->result == CLIS_UNKNOWN) { + /* + * Command not recognized in master, try cacher if it is + * running. + */ + vsb_clear(cp->cli->sb); + cp->cli->result = CLIS_OK; + if (cli_o <= 0) { + cli_result(cp->cli, CLIS_UNKNOWN); + cli_out(cp->cli, + "Unknown request in manager process " + "(child not running).\n" + "Type 'help' for more info."); + } else { + i = write(cli_o, p, strlen(p)); + xxxassert(i == strlen(p)); + i = write(cli_o, "\n", 1); + xxxassert(i == 1); + i = cli_readres(cli_i, &u, &q, params->cli_timeout); + cli_result(cp->cli, u); + cli_out(cp->cli, "%s", q); + free(q); + } + vsb_finish(cp->cli->sb); + AZ(vsb_overflowed(cp->cli->sb)); + } /* send the result back */ if (cli_writeres(cp->fdo, cp->cli)) diff --git a/varnish-cache/bin/varnishd/varnishd.c b/varnish-cache/bin/varnishd/varnishd.c index b716ff5d..b84f21fe 100644 --- a/varnish-cache/bin/varnishd/varnishd.c +++ b/varnish-cache/bin/varnishd/varnishd.c @@ -556,8 +556,6 @@ main(int argc, char *argv[]) if (pfh != NULL && vpf_write(pfh)) fprintf(stderr, "NOTE: Could not write PID file\n"); - mgt_cli_init(); - mgt_run(d_flag, T_arg); if (pfh != NULL) diff --git a/varnish-cache/include/cli_common.h b/varnish-cache/include/cli_common.h index 53bec5e9..90e856db 100644 --- a/varnish-cache/include/cli_common.h +++ b/varnish-cache/include/cli_common.h @@ -37,6 +37,5 @@ struct cli { int cli_writeres(int fd, const struct cli *cli); int cli_readres(int fd, unsigned *status, char **ptr, double tmo); -extern struct cli_proto CLI_cmds[]; cli_func_t cli_func_ping;