]> err.no Git - varnish/commitdiff
Rework the manager/cacher cli relationship, so that the manager does
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 12 Mar 2008 10:25:51 +0000 (10:25 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 12 Mar 2008 10:25:51 +0000 (10:25 +0000)
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

varnish-cache/bin/varnishd/cache_cli.c
varnish-cache/bin/varnishd/mgt_cli.c
varnish-cache/bin/varnishd/varnishd.c
varnish-cache/include/cli_common.h

index 493eb8d5554fdd0df9e139a5205f83e0773fed8a..13628802045f62dfc9c38a8e20158393b652ce35 100644 (file)
@@ -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);
index 5f0034930ca67f4c8e7fdde1db1ee963d22e4aba..eed2b4300d4e65dfa8a1adf6a1d88827c76ac3b4 100644 (file)
@@ -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))
index b716ff5dd4e1232e97f3e0403a02f06b737dda02..b84f21feba971c0c556b14f2c897d954c9fc5c56 100644 (file)
@@ -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)
index 53bec5e98d6a0fc72f605190cb6a8907b5eeb6df..90e856dba8178e8a4d2c47daa2d36e4334460c22 100644 (file)
@@ -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;