Mailing List Archive

r2595 - in trunk/varnish-cache: bin/varnishd include
Author: phk
Date: 2008-03-12 11:25:51 +0100 (Wed, 12 Mar 2008)
New Revision: 2595

Modified:
trunk/varnish-cache/bin/varnishd/cache_cli.c
trunk/varnish-cache/bin/varnishd/mgt_cli.c
trunk/varnish-cache/bin/varnishd/varnishd.c
trunk/varnish-cache/include/cli_common.h
Log:
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.



Modified: trunk/varnish-cache/bin/varnishd/cache_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_cli.c 2008-03-12 10:21:49 UTC (rev 2594)
+++ trunk/varnish-cache/bin/varnishd/cache_cli.c 2008-03-12 10:25:51 UTC (rev 2595)
@@ -85,29 +85,69 @@
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 = 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);

Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_cli.c 2008-03-12 10:21:49 UTC (rev 2594)
+++ trunk/varnish-cache/bin/varnishd/mgt_cli.c 2008-03-12 10:25:51 UTC (rev 2595)
@@ -78,73 +78,30 @@
#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;
+ char *p;

- (void)priv;
-
- /* Request */
- if (cli_o <= 0) {
- cli_result(cli, CLIS_CANT);
- cli_out(cli, "Cache process not running");
- return;
+ 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);
}
- 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, '"');
- }
- 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 @@
{ 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 @@
{ 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 @@
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))

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c 2008-03-12 10:21:49 UTC (rev 2594)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c 2008-03-12 10:25:51 UTC (rev 2595)
@@ -556,8 +556,6 @@
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)

Modified: trunk/varnish-cache/include/cli_common.h
===================================================================
--- trunk/varnish-cache/include/cli_common.h 2008-03-12 10:21:49 UTC (rev 2594)
+++ trunk/varnish-cache/include/cli_common.h 2008-03-12 10:25:51 UTC (rev 2595)
@@ -37,6 +37,5 @@

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;