[master] 91dcf6a Simplify the cli servicing by reducing a level of data structure indirection.
Poul-Henning Kamp
phk at FreeBSD.org
Sat May 21 22:42:05 CEST 2016
commit 91dcf6a90d30cde718df1f6f1752ac02a7bbdde2
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Sat May 21 18:57:01 2016 +0000
Simplify the cli servicing by reducing a level of data structure indirection.
diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c
index 337c2dc..b6d1e82 100644
--- a/bin/varnishd/cache/cache_cli.c
+++ b/bin/varnishd/cache/cache_cli.c
@@ -67,7 +67,7 @@ CLI_AddFuncs(struct cli_proto *p)
AZ(add_check);
Lck_Lock(&cli_mtx);
- AZ(VCLS_AddFunc(cls, 0, p));
+ VCLS_AddFunc(cls, 0, p);
Lck_Unlock(&cli_mtx);
}
diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c
index 40d6c2f..806b4e9 100644
--- a/bin/varnishd/mgt/mgt_cli.c
+++ b/bin/varnishd/mgt/mgt_cli.c
@@ -356,11 +356,11 @@ mgt_cli_init_cls(void)
cls = VCLS_New(mgt_cli_cb_before, mgt_cli_cb_after,
&mgt_param.cli_buffer, &mgt_param.cli_limit);
AN(cls);
- AZ(VCLS_AddFunc(cls, MCF_NOAUTH, cli_auth));
- AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_proto));
- AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_debug));
- AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_stv));
- AZ(VCLS_AddFunc(cls, MCF_AUTH, cli_askchild));
+ VCLS_AddFunc(cls, MCF_NOAUTH, cli_auth);
+ VCLS_AddFunc(cls, MCF_AUTH, cli_proto);
+ VCLS_AddFunc(cls, MCF_AUTH, cli_debug);
+ VCLS_AddFunc(cls, MCF_AUTH, cli_stv);
+ VCLS_AddFunc(cls, MCF_AUTH, cli_askchild);
}
/*--------------------------------------------------------------------
diff --git a/include/vcli_priv.h b/include/vcli_priv.h
index c1b44f0..cc7d111 100644
--- a/include/vcli_priv.h
+++ b/include/vcli_priv.h
@@ -38,6 +38,7 @@ struct cli; /* NB: struct cli is opaque at this level. */
typedef void cli_func_t(struct cli*, const char * const *av, void *priv);
struct cli_cmd_desc {
+ /* Must match CLI_CMD macro in include/tbl/cli_cmds.h */
const char *request;
const char *syntax;
const char *help;
@@ -51,7 +52,6 @@ struct cli_cmd_desc {
#undef CLI_CMD
struct cli_proto {
- /* These must match the CLI_* macros in cli.h */
const struct cli_cmd_desc *desc;
char flags[4];
@@ -59,6 +59,9 @@ struct cli_proto {
cli_func_t *func;
cli_func_t *jsonfunc;
void *priv;
+
+ unsigned auth;
+ VTAILQ_ENTRY(cli_proto) list;
};
/* The implementation must provide these functions */
diff --git a/include/vcli_serve.h b/include/vcli_serve.h
index 0ff65d0..226fad6 100644
--- a/include/vcli_serve.h
+++ b/include/vcli_serve.h
@@ -34,7 +34,7 @@ struct VCLS *VCLS_New(cls_cbc_f *before, cls_cbc_f *after,
volatile unsigned *maxlen, volatile unsigned *limit);
struct cli *VCLS_AddFd(struct VCLS *cs, int fdi, int fdo, cls_cb_f *closefunc,
void *priv);
-int VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp);
+void VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp);
int VCLS_Poll(struct VCLS *cs, int timeout);
int VCLS_PollFd(struct VCLS *cs, int fd, int timeout);
void VCLS_Destroy(struct VCLS **);
diff --git a/lib/libvarnish/cli_common.c b/lib/libvarnish/cli_common.c
index b735d1f..a2dd4f6 100644
--- a/lib/libvarnish/cli_common.c
+++ b/lib/libvarnish/cli_common.c
@@ -46,6 +46,7 @@
#include "vdef.h"
#include "vas.h"
#include "miniobj.h"
+#include "vqueue.h"
#include "vcli.h"
#include "vcli_common.h"
diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c
index 5c3e2f5..2945539 100644
--- a/lib/libvarnish/cli_serve.c
+++ b/lib/libvarnish/cli_serve.c
@@ -43,6 +43,7 @@
#include "vdef.h"
#include "vas.h"
+#include "vqueue.h"
#include "miniobj.h"
#include "vav.h"
@@ -51,17 +52,8 @@
#include "vcli_priv.h"
#include "vcli_serve.h"
#include "vlu.h"
-#include "vqueue.h"
#include "vsb.h"
-struct VCLS_func {
- unsigned magic;
-#define VCLS_FUNC_MAGIC 0x7d280c9b
- VTAILQ_ENTRY(VCLS_func) list;
- unsigned auth;
- struct cli_proto *clp;
-};
-
struct VCLS_fd {
unsigned magic;
#define VCLS_FD_MAGIC 0x010dbd1e
@@ -81,10 +73,11 @@ struct VCLS {
#define VCLS_MAGIC 0x60f044a3
VTAILQ_HEAD(,VCLS_fd) fds;
unsigned nfd;
- VTAILQ_HEAD(,VCLS_func) funcs;
+ VTAILQ_HEAD(,cli_proto) funcs;
cls_cbc_f *before, *after;
volatile unsigned *maxlen;
volatile unsigned *limit;
+ struct cli_proto *wildcard;
};
/*--------------------------------------------------------------------*/
@@ -117,9 +110,8 @@ VCLS_func_ping(struct cli *cli, const char * const *av, void *priv)
void
VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
{
- struct cli_proto *cp;
- struct VCLS_func *cfn;
- unsigned all, debug, u, d, h, i, wc;
+ struct cli_proto *clp;
+ unsigned all, debug, u, d, h, i;
struct VCLS *cs;
(void)priv;
@@ -135,70 +127,59 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
all = 0;
debug = 1;
} else {
- VTAILQ_FOREACH(cfn, &cs->funcs, list) {
- if (cfn->auth > cli->auth)
+ VTAILQ_FOREACH(clp, &cs->funcs, list) {
+ if (clp->auth > cli->auth)
continue;
- for (cp = cfn->clp; cp->desc != NULL; cp++) {
- if (!strcmp(cp->desc->request, av[2])) {
- VCLI_Out(cli, "%s\n%s\n",
- cp->desc->syntax, cp->desc->help);
- return;
- }
- for (u = 0; u < sizeof cp->flags; u++) {
- if (cp->flags[u] == '*') {
- cp->func(cli, av, NULL);
- return;
- }
- }
+ if (!strcmp(clp->desc->request, av[2])) {
+ VCLI_Out(cli, "%s\n%s\n",
+ clp->desc->syntax, clp->desc->help);
+ return;
}
}
- VCLI_Out(cli, "Unknown request.\nType 'help' for more info.\n");
- VCLI_SetResult(cli, CLIS_UNKNOWN);
+ if (cs->wildcard != NULL) {
+ cs->wildcard->func(cli, av, NULL);
+ } else {
+ VCLI_Out(cli,
+ "Unknown request.\nType 'help' for more info.\n");
+ VCLI_SetResult(cli, CLIS_UNKNOWN);
+ }
return;
}
- VTAILQ_FOREACH(cfn, &cs->funcs, list) {
- if (cfn->auth > cli->auth)
+ VTAILQ_FOREACH(clp, &cs->funcs, list) {
+ if (clp->auth > cli->auth)
continue;
- for (cp = cfn->clp; cp->desc != NULL; cp++) {
- d = 0;
- h = 0;
- i = 0;
- wc = 0;
- for (u = 0; u < sizeof cp->flags; u++) {
- if (cp->flags[u] == '\0')
- continue;
- if (cp->flags[u] == 'd')
- d = 1;
- if (cp->flags[u] == 'h')
- h = 1;
- if (cp->flags[u] == 'i')
- i = 1;
- if (cp->flags[u] == '*')
- wc = 1;
- }
- if (i)
- continue;
- if (wc) {
- cp->func(cli, av, NULL);
- continue;
- }
- if (debug != d)
- continue;
- if (h && !all)
+ d = 0;
+ h = 0;
+ i = 0;
+ for (u = 0; u < sizeof clp->flags; u++) {
+ if (clp->flags[u] == '\0')
continue;
- if (cp->desc->syntax != NULL)
- VCLI_Out(cli, "%s\n", cp->desc->syntax);
+ if (clp->flags[u] == 'd')
+ d = 1;
+ if (clp->flags[u] == 'h')
+ h = 1;
+ if (clp->flags[u] == 'i')
+ i = 1;
}
+ if (i)
+ continue;
+ if (debug != d)
+ continue;
+ if (h && !all)
+ continue;
+ if (clp->desc->syntax != NULL)
+ VCLI_Out(cli, "%s\n", clp->desc->syntax);
}
+ if (cs->wildcard != NULL)
+ cs->wildcard->func(cli, av, NULL);
}
void
VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
{
- struct cli_proto *cp;
- struct VCLS_func *cfn;
+ struct cli_proto *clp;
struct VCLS *cs;
- unsigned u, f_wc, f_i;
+ unsigned u, f_i;
(void)priv;
cs = cli->cls;
@@ -206,39 +187,33 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
if (priv == NULL)
VCLI_JSON_ver(cli, 1, av);
- VTAILQ_FOREACH(cfn, &cs->funcs, list) {
- if (cfn->auth > cli->auth)
+ VTAILQ_FOREACH(clp, &cs->funcs, list) {
+ if (clp->auth > cli->auth)
continue;
- for (cp = cfn->clp; cp->desc != NULL; cp++) {
- f_wc = f_i = 0;
- for (u = 0; u < sizeof cp->flags; u++) {
- if (cp->flags[u] == '*')
- f_wc = 1;
- if (cp->flags[u] == 'i')
- f_i = 1;
- }
- if (f_wc) {
- cp->func(cli, av, priv);
- continue;
- }
- if (f_i)
- continue;
- VCLI_Out(cli, ",\n {");
- VCLI_Out(cli, "\n \"request\": ");
- VCLI_JSON_str(cli, cp->desc->request);
- VCLI_Out(cli, ",\n \"syntax\": ");
- VCLI_JSON_str(cli, cp->desc->syntax);
- VCLI_Out(cli, ",\n \"help\": ");
- VCLI_JSON_str(cli, cp->desc->help);
- VCLI_Out(cli, ",\n \"minarg\": %d", cp->desc->minarg);
- VCLI_Out(cli, ", \"maxarg\": %d", cp->desc->maxarg);
- VCLI_Out(cli, ", \"flags\": ");
- VCLI_JSON_str(cli, cp->flags);
- VCLI_Out(cli, ", \"json\": %s",
- cp->jsonfunc == NULL ? "false" : "true");
- VCLI_Out(cli, "\n }");
- }
+ f_i = 0;
+ for (u = 0; u < sizeof clp->flags; u++)
+ if (clp->flags[u] == 'i')
+ f_i = 1;
+ if (f_i)
+ continue;
+ VCLI_Out(cli, ",\n {");
+ VCLI_Out(cli, "\n \"request\": ");
+ VCLI_JSON_str(cli, clp->desc->request);
+ VCLI_Out(cli, ",\n \"syntax\": ");
+ VCLI_JSON_str(cli, clp->desc->syntax);
+ VCLI_Out(cli, ",\n \"help\": ");
+ VCLI_JSON_str(cli, clp->desc->help);
+ VCLI_Out(cli, ",\n \"minarg\": %d", clp->desc->minarg);
+ VCLI_Out(cli, ", \"maxarg\": %d", clp->desc->maxarg);
+ VCLI_Out(cli, ", \"flags\": ");
+ VCLI_JSON_str(cli, clp->flags);
+ VCLI_Out(cli, ", \"json\": %s",
+ clp->jsonfunc == NULL ? "false" : "true");
+ VCLI_Out(cli, "\n }");
}
+ if (cs->wildcard != NULL)
+ cs->wildcard->func(cli, av, priv);
+
if (priv == NULL)
VCLI_Out(cli, "\n]\n");
}
@@ -247,22 +222,13 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
* Look for a CLI command to execute
*/
-static int
-cls_dispatch(struct cli *cli, struct cli_proto *clp, char * const * av,
- unsigned ac)
+static void
+cls_dispatch(struct cli *cli, const struct cli_proto *cp,
+ char * const * av, unsigned ac)
{
- struct cli_proto *cp;
int json = 0;
AN(av);
- for (cp = clp; cp->desc != NULL; cp++) {
- if (!strcmp(av[1], cp->desc->request))
- break;
- if (!strcmp("*", cp->desc->request))
- break;
- }
- if (cp->desc == NULL)
- return (0);
if (ac > 1 && !strcmp(av[2], "-j"))
json = 1;
@@ -270,24 +236,24 @@ cls_dispatch(struct cli *cli, struct cli_proto *clp, char * const * av,
if (cp->func == NULL && !json) {
VCLI_Out(cli, "Unimplemented\n");
VCLI_SetResult(cli, CLIS_UNIMPL);
- return(1);
+ return;
}
if (cp->jsonfunc == NULL && json) {
VCLI_Out(cli, "JSON unimplemented\n");
VCLI_SetResult(cli, CLIS_UNIMPL);
- return(1);
+ return;
}
if (ac - 1 < cp->desc->minarg + json) {
VCLI_Out(cli, "Too few parameters\n");
VCLI_SetResult(cli, CLIS_TOOFEW);
- return(1);
+ return;
}
if (ac - 1> cp->desc->maxarg + json) {
VCLI_Out(cli, "Too many parameters\n");
VCLI_SetResult(cli, CLIS_TOOMANY);
- return(1);
+ return;
}
cli->result = CLIS_OK;
@@ -296,7 +262,6 @@ cls_dispatch(struct cli *cli, struct cli_proto *clp, char * const * av,
cp->jsonfunc(cli, (const char * const *)av, cp->priv);
else
cp->func(cli, (const char * const *)av, cp->priv);
- return (1);
}
/*--------------------------------------------------------------------
@@ -308,7 +273,7 @@ cls_vlu2(void *priv, char * const *av)
{
struct VCLS_fd *cfd;
struct VCLS *cs;
- struct VCLS_func *cfn;
+ struct cli_proto *clp;
struct cli *cli;
unsigned na;
ssize_t len;
@@ -352,12 +317,18 @@ cls_vlu2(void *priv, char * const *av)
for (na = 0; av[na + 1] != NULL; na++)
continue;
- VTAILQ_FOREACH(cfn, &cs->funcs, list) {
- if (cfn->auth > cli->auth)
+ VTAILQ_FOREACH(clp, &cs->funcs, list) {
+ if (clp->auth > cli->auth)
continue;
- if (cls_dispatch(cli, cfn->clp, av, na))
+ if (!strcmp(clp->desc->request, av[1])) {
+ cls_dispatch(cli, clp, av, na);
break;
+ }
}
+ if (clp == NULL &&
+ cs->wildcard && cs->wildcard->auth <= cli->auth)
+ cls_dispatch(cli, cs->wildcard, av, na);
+
} while (0);
AZ(VSB_finish(cli->sb));
@@ -524,18 +495,33 @@ cls_close_fd(struct VCLS *cs, struct VCLS_fd *cfd)
FREE_OBJ(cfd);
}
-int
+void
VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp)
{
- struct VCLS_func *cfn;
+ struct cli_proto *clp2;
+ int i;
CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC);
- ALLOC_OBJ(cfn, VCLS_FUNC_MAGIC);
- AN(cfn);
- cfn->clp = clp;
- cfn->auth = auth;
- VTAILQ_INSERT_TAIL(&cs->funcs, cfn, list);
- return (0);
+ AN(clp);
+
+ for (;clp->desc != NULL; clp++) {
+ clp->auth = auth;
+ if (!strcmp(clp->desc->request, "*")) {
+ cs->wildcard = clp;
+ } else {
+ VTAILQ_FOREACH(clp2, &cs->funcs, list) {
+ i = strcmp(clp->desc->request,
+ clp2->desc->request);
+ assert(i != 0);
+ if (i < 0)
+ break;
+ }
+ if (clp2 != NULL)
+ VTAILQ_INSERT_BEFORE(clp2, clp, list);
+ else
+ VTAILQ_INSERT_TAIL(&cs->funcs, clp, list);
+ }
+ }
}
int
@@ -625,7 +611,7 @@ VCLS_Destroy(struct VCLS **csp)
{
struct VCLS *cs;
struct VCLS_fd *cfd, *cfd2;
- struct VCLS_func *cfn;
+ struct cli_proto *clp;
cs = *csp;
*csp = NULL;
@@ -634,9 +620,8 @@ VCLS_Destroy(struct VCLS **csp)
cls_close_fd(cs, cfd);
while (!VTAILQ_EMPTY(&cs->funcs)) {
- cfn = VTAILQ_FIRST(&cs->funcs);
- VTAILQ_REMOVE(&cs->funcs, cfn, list);
- FREE_OBJ(cfn);
+ clp = VTAILQ_FIRST(&cs->funcs);
+ VTAILQ_REMOVE(&cs->funcs, clp, list);
}
FREE_OBJ(cs);
}
More information about the varnish-commit
mailing list