[master] 552292e Hack the help with/without worker process thing up a different way, resulting in alphabetically sorted command listing.

Poul-Henning Kamp phk at FreeBSD.org
Sat May 21 22:42:05 CEST 2016


commit 552292e6943e6edcd289b51fca1dce03cec4cf09
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat May 21 20:38:46 2016 +0000

    Hack the help with/without worker process thing up a different way,
    resulting in alphabetically sorted command listing.
    
    Not what I set out to do right now, but somebody asked for this
    recently and I happened to spot a way to do it now...

diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index 5719720..b45c4f4 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -588,7 +588,7 @@ ccf_listen_address(struct cli *cli, const char * const *av, void *priv)
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto vca_cmds[] = {
-	{ CLICMD_SERVER_START,		"i", ccf_start },
+	{ CLICMD_SERVER_START,		"", ccf_start },
 	{ CLICMD_DEBUG_LISTEN_ADDRESS,	"d", ccf_listen_address },
 	{ NULL }
 };
diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c
index b6d1e82..db72904 100644
--- a/bin/varnishd/cache/cache_cli.c
+++ b/bin/varnishd/cache/cache_cli.c
@@ -111,7 +111,7 @@ CLI_Run(void)
 
 static struct cli_proto cli_cmds[] = {
 	{ CLICMD_PING,	"i", VCLS_func_ping },
-	{ CLICMD_HELP,	"i", VCLS_func_help, VCLS_func_help_json, cli_cmds },
+	{ CLICMD_HELP,	"i", VCLS_func_help, VCLS_func_help_json },
 	{ NULL }
 };
 
@@ -129,6 +129,7 @@ CLI_Init(void)
 	cls = VCLS_New(cli_cb_before, cli_cb_after,
 	    &cache_param->cli_buffer, &cache_param->cli_limit);
 	AN(cls);
+	VCLS_Clone(cls, mgt_cls);
 
 	CLI_AddFuncs(cli_cmds);
 }
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 8b0ac91..a8702e7 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -947,11 +947,11 @@ VCL_##func##_method(struct vcl *vcl, struct worker *wrk,		\
 /*--------------------------------------------------------------------*/
 
 static struct cli_proto vcl_cmds[] = {
-	{ CLICMD_VCL_LOAD,		"i", ccf_config_load },
-	{ CLICMD_VCL_LIST,		"i", ccf_config_list },
-	{ CLICMD_VCL_STATE,		"i", ccf_config_state },
-	{ CLICMD_VCL_DISCARD,		"i", ccf_config_discard },
-	{ CLICMD_VCL_USE,		"i", ccf_config_use },
+	{ CLICMD_VCL_LOAD,		"", ccf_config_load },
+	{ CLICMD_VCL_LIST,		"", ccf_config_list },
+	{ CLICMD_VCL_STATE,		"", ccf_config_state },
+	{ CLICMD_VCL_DISCARD,		"", ccf_config_discard },
+	{ CLICMD_VCL_USE,		"", ccf_config_use },
 	{ CLICMD_VCL_SHOW,		"", ccf_config_show },
 	{ NULL }
 };
diff --git a/bin/varnishd/common/common.h b/bin/varnishd/common/common.h
index 7b6a6b8..afdeafd 100644
--- a/bin/varnishd/common/common.h
+++ b/bin/varnishd/common/common.h
@@ -85,3 +85,6 @@ void VSM_common_delete(struct vsm_sc **sc);
 void VSM_common_copy(struct vsm_sc *to, const struct vsm_sc *from);
 void VSM_common_cleaner(struct vsm_sc *sc, struct VSC_C_main *stats);
 void VSM_common_ageupdate(const struct vsm_sc *sc);
+
+/* mgt_cli.c */
+extern struct VCLS	*mgt_cls;
diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c
index 806b4e9..dcebb2a 100644
--- a/bin/varnishd/mgt/mgt_cli.c
+++ b/bin/varnishd/mgt/mgt_cli.c
@@ -71,7 +71,7 @@ static const struct cli_cmd_desc *cmds[] = {
 static const int ncmds = sizeof cmds / sizeof cmds[0];
 
 static int		cli_i = -1, cli_o = -1;
-static struct VCLS	*cls;
+struct VCLS		*mgt_cls;
 static const char	*secret_file;
 
 #define	MCF_NOAUTH	0	/* NB: zero disables here-documents */
@@ -152,12 +152,6 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv)
 	 * running.
 	 */
 	if (cli_o <= 0) {
-		if (!strcmp(av[1], "help")) {
-			if (av[2] == NULL || strcmp(av[2], "-j"))
-				VCLI_Out(cli,
-				   "No help from child, (not running).\n");
-			return;
-		}
 		VCLI_SetResult(cli, CLIS_UNKNOWN);
 		VCLI_Out(cli,
 		    "Unknown request in manager process "
@@ -322,8 +316,28 @@ mcf_auth(struct cli *cli, const char *const *av, void *priv)
 	mcf_banner(cli, av, priv);
 }
 
+/*--------------------------------------------------------------------*/
+
+static void __match_proto__(cli_func_t)
+mcf_help(struct cli *cli, const char * const *av, void *priv)
+{
+	if (cli_o <= 0)
+		VCLS_func_help(cli, av, priv);
+	else
+		mcf_askchild(cli, av, priv);
+}
+
+static void __match_proto__(cli_func_t)
+mcf_help_json(struct cli *cli, const char * const *av, void *priv)
+{
+	if (cli_o <= 0)
+		VCLS_func_help_json(cli, av, priv);
+	else
+		mcf_askchild(cli, av, priv);
+}
+
 static struct cli_proto cli_auth[] = {
-	{ CLICMD_HELP,		"", VCLS_func_help, VCLS_func_help_json },
+	{ CLICMD_HELP,		"", mcf_help, mcf_help_json },
 	{ CLICMD_PING,		"", VCLS_func_ping },
 	{ CLICMD_AUTH,		"", mcf_auth },
 	{ CLICMD_QUIT,		"", VCLS_func_close },
@@ -353,14 +367,14 @@ static void
 mgt_cli_init_cls(void)
 {
 
-	cls = VCLS_New(mgt_cli_cb_before, mgt_cli_cb_after,
+	mgt_cls = VCLS_New(mgt_cli_cb_before, mgt_cli_cb_after,
 	    &mgt_param.cli_buffer, &mgt_param.cli_limit);
-	AN(cls);
-	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);
+	AN(mgt_cls);
+	VCLS_AddFunc(mgt_cls, MCF_NOAUTH, cli_auth);
+	VCLS_AddFunc(mgt_cls, MCF_AUTH, cli_proto);
+	VCLS_AddFunc(mgt_cls, MCF_AUTH, cli_debug);
+	VCLS_AddFunc(mgt_cls, MCF_AUTH, cli_stv);
+	VCLS_AddFunc(mgt_cls, MCF_AUTH, cli_askchild);
 }
 
 /*--------------------------------------------------------------------
@@ -371,7 +385,7 @@ void
 mgt_cli_close_all(void)
 {
 
-	VCLS_Destroy(&cls);
+	VCLS_Destroy(&mgt_cls);
 }
 
 /*--------------------------------------------------------------------
@@ -385,7 +399,7 @@ mgt_cli_callback2(const struct vev *e, int what)
 
 	(void)e;
 	(void)what;
-	i = VCLS_PollFd(cls, e->fd, 0);
+	i = VCLS_PollFd(mgt_cls, e->fd, 0);
 	return (i);
 }
 
@@ -400,10 +414,10 @@ mgt_cli_setup(int fdi, int fdo, int verbose, const char *ident,
 
 	(void)ident;
 	(void)verbose;
-	if (cls == NULL)
+	if (mgt_cls == NULL)
 		mgt_cli_init_cls();
 
-	cli = VCLS_AddFd(cls, fdi, fdo, closefunc, priv);
+	cli = VCLS_AddFd(mgt_cls, fdi, fdo, closefunc, priv);
 
 	cli->ident = strdup(ident);
 
diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc
index ac18701..19bc2d9 100644
--- a/bin/varnishtest/tests/b00008.vtc
+++ b/bin/varnishtest/tests/b00008.vtc
@@ -10,7 +10,7 @@ varnish v1 -cliok "help -d"
 
 varnish v1 -cliok "help vcl.load"
 
-varnish v1 -cliok "help ban"
+varnish v1 -clierr 101 "help ban"
 
 varnish v1 -clierr 101 "FOO?"
 
diff --git a/include/vcli_priv.h b/include/vcli_priv.h
index cc7d111..09bd042 100644
--- a/include/vcli_priv.h
+++ b/include/vcli_priv.h
@@ -53,7 +53,7 @@ struct cli_cmd_desc {
 
 struct cli_proto {
 	const struct cli_cmd_desc	*desc;
-	char				flags[4];
+	const char			*flags;
 
 	/* Dispatch information */
 	cli_func_t			*func;
diff --git a/include/vcli_serve.h b/include/vcli_serve.h
index 226fad6..1c5ac88 100644
--- a/include/vcli_serve.h
+++ b/include/vcli_serve.h
@@ -38,6 +38,7 @@ 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 **);
+void VCLS_Clone(struct VCLS *cs, struct VCLS *cso);
 
 /* From libvarnish/cli.c */
 cli_func_t	VCLS_func_close;
diff --git a/lib/libvarnish/cli_serve.c b/lib/libvarnish/cli_serve.c
index 2945539..4e88bdc 100644
--- a/lib/libvarnish/cli_serve.c
+++ b/lib/libvarnish/cli_serve.c
@@ -82,7 +82,7 @@ struct VCLS {
 
 /*--------------------------------------------------------------------*/
 
-void
+void __match_proto__(cli_func_t)
 VCLS_func_close(struct cli *cli, const char *const *av, void *priv)
 {
 
@@ -94,24 +94,24 @@ VCLS_func_close(struct cli *cli, const char *const *av, void *priv)
 
 /*--------------------------------------------------------------------*/
 
-void
+void __match_proto__(cli_func_t)
 VCLS_func_ping(struct cli *cli, const char * const *av, void *priv)
 {
 	time_t t;
 
-	(void)priv;
 	(void)av;
+	(void)priv;
 	t = time(NULL);
 	VCLI_Out(cli, "PONG %jd 1.0", (intmax_t)t);
 }
 
 /*--------------------------------------------------------------------*/
 
-void
+void __match_proto__(cli_func_t)
 VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
 {
 	struct cli_proto *clp;
-	unsigned all, debug, u, d, h, i;
+	unsigned all, debug, d;
 	struct VCLS *cs;
 
 	(void)priv;
@@ -128,74 +128,44 @@ VCLS_func_help(struct cli *cli, const char * const *av, void *priv)
 		debug = 1;
 	} else {
 		VTAILQ_FOREACH(clp, &cs->funcs, list) {
-			if (clp->auth > cli->auth)
-				continue;
-			if (!strcmp(clp->desc->request, av[2])) {
+			if (clp->auth <= cli->auth &&
+			    !strcmp(clp->desc->request, av[2])) {
 				VCLI_Out(cli, "%s\n%s\n",
 				    clp->desc->syntax, clp->desc->help);
 				return;
 			}
 		}
-		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);
-		}
+		VCLI_Out(cli, "Unknown request.\nType 'help' for more info.\n");
+		VCLI_SetResult(cli, CLIS_UNKNOWN);
 		return;
 	}
 	VTAILQ_FOREACH(clp, &cs->funcs, list) {
 		if (clp->auth > cli->auth)
 			continue;
-		d = 0;
-		h = 0;
-		i = 0;
-		for (u = 0; u < sizeof clp->flags; u++) {
-			if (clp->flags[u] == '\0')
-				continue;
-			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)
+		d =  strchr(clp->flags, 'd') != NULL ? 1 : 0;
+		if (d && (!all && !debug))
 			continue;
-		if (h && !all)
+		if (debug && !d)
 			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
+void __match_proto__(cli_func_t)
 VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
 {
 	struct cli_proto *clp;
 	struct VCLS *cs;
-	unsigned u, f_i;
 
 	(void)priv;
 	cs = cli->cls;
 	CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC);
 
-	if (priv == NULL)
-		VCLI_JSON_ver(cli, 1, av);
+	VCLI_JSON_ver(cli, 1, av);
 	VTAILQ_FOREACH(clp, &cs->funcs, list) {
 		if (clp->auth > cli->auth)
 			continue;
-		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);
@@ -211,11 +181,7 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv)
 		    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");
+	VCLI_Out(cli, "\n]\n");
 }
 
 /*--------------------------------------------------------------------
@@ -509,14 +475,17 @@ VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp)
 		if (!strcmp(clp->desc->request, "*")) {
 			cs->wildcard = clp;
 		} else {
+			i = 0;
 			VTAILQ_FOREACH(clp2, &cs->funcs, list) {
 				i = strcmp(clp->desc->request,
 				    clp2->desc->request);
-				assert(i != 0);
-				if (i < 0)
+				if (i <= 0)
 					break;
 			}
-			if (clp2 != NULL)
+			if (clp2 != NULL && i == 0) {
+				VTAILQ_INSERT_BEFORE(clp2, clp, list);
+				VTAILQ_REMOVE(&cs->funcs, clp2, list);
+			} else if (clp2 != NULL)
 				VTAILQ_INSERT_BEFORE(clp2, clp, list);
 			else
 				VTAILQ_INSERT_TAIL(&cs->funcs, clp, list);
@@ -524,6 +493,26 @@ VCLS_AddFunc(struct VCLS *cs, unsigned auth, struct cli_proto *clp)
 	}
 }
 
+/*
+ * This function has *very* special semantics, related to the mgt/worker
+ * process Copy-On-Write memory relationship.
+ */
+
+void
+VCLS_Clone(struct VCLS *cs, struct VCLS *cso)
+{
+	struct cli_proto *clp, *clp2;
+
+	CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC);
+	CHECK_OBJ_NOTNULL(cso, VCLS_MAGIC);
+	VTAILQ_FOREACH_SAFE(clp, &cso->funcs, list, clp2) {
+		VTAILQ_REMOVE(&cso->funcs, clp, list);
+		VTAILQ_INSERT_TAIL(&cs->funcs, clp, list);
+		clp->auth = 0;
+		clp->func = NULL;
+	}
+}
+
 int
 VCLS_PollFd(struct VCLS *cs, int fd, int timeout)
 {



More information about the varnish-commit mailing list