[master] 0231323 Propagate the vcl state to the child process.

Poul-Henning Kamp phk at FreeBSD.org
Mon Mar 9 10:29:33 CET 2015


commit 023132329dcb6f557bc971653571b2a082107e6e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Mar 9 09:29:18 2015 +0000

    Propagate the vcl state to the child process.

diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 1b7e25e..0db8cd8 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -34,6 +34,7 @@
 #include "config.h"
 
 #include <dlfcn.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #include "cache.h"
@@ -49,6 +50,8 @@ struct vcls {
 	VTAILQ_ENTRY(vcls)	list;
 	void			*dlh;
 	struct VCL_conf		conf[1];
+	char			state[8];
+	int			warm;
 };
 
 /*
@@ -58,7 +61,6 @@ struct vcls {
 static VTAILQ_HEAD(, vcls)	vcl_head =
     VTAILQ_HEAD_INITIALIZER(vcl_head);
 
-
 static struct lock		vcl_mtx;
 static struct vcls		*vcl_active; /* protected by vcl_mtx */
 
@@ -167,8 +169,16 @@ vcl_find(const char *name)
 	return (NULL);
 }
 
+static void
+vcl_set_state(struct vcls *vcl, const char *state)
+{
+
+	vcl->warm = state[0] == '1' ? 1 : 0;
+	bprintf(vcl->state, "%s", state + 1);
+}
+
 static int
-VCL_Load(const char *fn, const char *name, struct cli *cli)
+VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
 {
 	struct vcls *vcl;
 	struct VCL_conf const *cnf;
@@ -184,7 +194,7 @@ VCL_Load(const char *fn, const char *name, struct cli *cli)
 	}
 
 	ALLOC_OBJ(vcl, VVCLS_MAGIC);
-	XXXAN(vcl);
+	AN(vcl);
 
 	vcl->dlh = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
 
@@ -234,6 +244,7 @@ VCL_Load(const char *fn, const char *name, struct cli *cli)
 		FREE_OBJ(vcl);
 		return (1);
 	}
+	vcl_set_state(vcl, state);
 	assert(hand == VCL_RET_OK);
 	VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
 	VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
@@ -307,8 +318,9 @@ ccf_config_list(struct cli *cli, const char * const *av, void *priv)
 			flg = "discarded";
 		} else
 			flg = "available";
-		VCLI_Out(cli, "%-10s %6u %s\n",
+		VCLI_Out(cli, "%-10s %4s/%s  %6u %s\n",
 		    flg,
+		    vcl->state, vcl->warm ? "warm" : "cold",
 		    vcl->conf->busy,
 		    vcl->conf->loaded_name);
 	}
@@ -320,7 +332,7 @@ ccf_config_load(struct cli *cli, const char * const *av, void *priv)
 
 	AZ(priv);
 	ASSERT_CLI();
-	if (VCL_Load(av[3], av[2], cli))
+	if (VCL_Load(cli, av[2], av[3], av[4]))
 		VCLI_SetResult(cli, CLIS_PARAM);
 	return;
 }
@@ -328,12 +340,16 @@ ccf_config_load(struct cli *cli, const char * const *av, void *priv)
 static void __match_proto__(cli_func_t)
 ccf_config_state(struct cli *cli, const char * const *av, void *priv)
 {
+	struct vcls *vcl;
 
+	(void)cli;
 	AZ(priv);
 	ASSERT_CLI();
-	(void)cli;
-	(void)av;
-	return;
+	AN(av[2]);
+	AN(av[3]);
+	vcl = vcl_find(av[2]);
+	AN(vcl);			// MGT ensures this
+	vcl_set_state(vcl, av[3]);
 }
 
 static void __match_proto__(cli_func_t)
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 0c8dc08..1795777 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -54,14 +54,14 @@ struct vclprog {
 	VTAILQ_ENTRY(vclprog)	list;
 	char			*name;
 	char			*fname;
-	int			active;
 	int			warm;
 	char			state[8];
 	double			go_cold;
 };
 
 static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
-
+static struct vclprog		*active_vcl;
+static struct vev *e_poker;
 
 /*--------------------------------------------------------------------*/
 
@@ -81,8 +81,8 @@ mgt_vcl_add(const char *name, const char *libfile, const char *state)
 
 	bprintf(vp->state, "%s", state);
 
-	if (VTAILQ_EMPTY(&vclhead))
-		vp->active = 1;
+	if (active_vcl == NULL)
+		active_vcl = vp;
 	VTAILQ_INSERT_TAIL(&vclhead, vp, list);
 	return (vp);
 }
@@ -134,8 +134,17 @@ static void
 mgt_vcl_setstate(struct vclprog *vp, int warm)
 {
 	unsigned status;
+	double now;
 	char *p;
 
+	if (warm == -1) {
+		now = VTIM_mono();
+		warm = vp->warm;
+		if (vp->go_cold > 0 && !strcmp(vp->state, "auto") &&
+		    vp->go_cold + mgt_param.vcl_cooldown < now)
+			warm = 0;
+	}
+
 	if (vp->warm == warm)
 		return;
 
@@ -147,8 +156,11 @@ mgt_vcl_setstate(struct vclprog *vp, int warm)
 	if (child_pid < 0)
 		return;
 
-	AZ(mgt_cli_askchild(&status, &p, "vcl.state %s %d%s\n",
-	    vp->name, vp->warm, vp->state));
+	/*
+	 * We ignore the result here so we don't croak if the child did.
+	 */
+	(void)mgt_cli_askchild(&status, &p, "vcl.state %s %d%s\n",
+	    vp->name, vp->warm, vp->state);
 
 	free(p);
 }
@@ -227,19 +239,16 @@ mgt_push_vcls_and_start(unsigned *status, char **p)
 {
 	struct vclprog *vp;
 
+	AN(active_vcl);
 	VTAILQ_FOREACH(vp, &vclhead, list) {
-		if (mgt_cli_askchild(status, p,
-		    "vcl.load \"%s\" %s %d%s\n",
+		if (mgt_cli_askchild(status, p, "vcl.load \"%s\" %s %d%s\n",
 		    vp->name, vp->fname, vp->warm, vp->state))
 			return (1);
 		free(*p);
-		if (!vp->active)
-			continue;
-		if (mgt_cli_askchild(status, p,
-		    "vcl.use \"%s\"\n", vp->name))
-			return (1);
-		free(*p);
 	}
+	if (mgt_cli_askchild(status, p, "vcl.use \"%s\"\n", active_vcl->name))
+		return (1);
+	free(*p);
 	if (mgt_cli_askchild(status, p, "start\n"))
 		return (1);
 	free(*p);
@@ -319,9 +328,10 @@ mcf_vcl_state(struct cli *cli, const char * const *av, void *priv)
 
 	if (!strcmp(av[3], "auto")) {
 		bprintf(vp->state, "%s", "auto");
+		mgt_vcl_setstate(vp, -1);
 	} else if (!strcmp(av[3], "cold")) {
-		if (vp->active) {
-			VCLI_Out(cli, "Cannot set active VCL cold.");
+		if (vp == active_vcl) {
+			VCLI_Out(cli, "Cannot set the active VCL cold.");
 			VCLI_SetResult(cli, CLIS_PARAM);
 			return;
 		}
@@ -341,13 +351,13 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv)
 {
 	unsigned status;
 	char *p = NULL;
-	struct vclprog *vp, *vp2;
+	struct vclprog *vp;
 
 	(void)priv;
 	vp = mcf_find_vcl(cli, av[2]);
 	if (vp == NULL)
 		return;
-	if (vp->active != 0)
+	if (vp == active_vcl)
 		return;
 	mgt_vcl_setstate(vp, 1);
 	if (child_pid >= 0 &&
@@ -356,14 +366,9 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv)
 		VCLI_Out(cli, "%s", p);
 	} else {
 		VCLI_Out(cli, "VCL '%s' now active", av[2]);
-		VTAILQ_FOREACH(vp2, &vclhead, list) {
-			if (vp2->active) {
-				vp2->active = 0;
-				vp2->go_cold = VTIM_mono();
-				break;
-			}
-		}
-		vp->active = 1;
+		if (active_vcl != NULL)
+			active_vcl->go_cold = VTIM_mono();
+		active_vcl = vp;
 	}
 	free(p);
 }
@@ -377,7 +382,7 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
 
 	(void)priv;
 	vp = mcf_find_vcl(cli, av[2]);
-	if (vp != NULL && vp->active) {
+	if (vp == active_vcl) {
 		VCLI_SetResult(cli, CLIS_PARAM);
 		VCLI_Out(cli, "Cannot discard active VCL program\n");
 	} else if (vp != NULL) {
@@ -398,7 +403,6 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv)
 {
 	unsigned status;
 	char *p;
-	const char *flg;
 	struct vclprog *vp;
 
 	(void)av;
@@ -411,12 +415,10 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv)
 		free(p);
 	} else {
 		VTAILQ_FOREACH(vp, &vclhead, list) {
-			if (vp->active) {
-				flg = "active";
-			} else
-				flg = "available";
-			VCLI_Out(cli, "%-10s %4s/%s  %s\n", flg, vp->state,
-			    vp->warm ? "warm" : "cold", vp->name);
+			VCLI_Out(cli, "%-10s %4s/%s  %6s %s\n",
+			    vp == active_vcl ? "active" : "available",
+			    vp->state,
+			    vp->warm ? "warm" : "cold", "", vp->name);
 		}
 	}
 }
@@ -427,18 +429,11 @@ static int __match_proto__(vev_cb_f)
 mgt_vcl_poker(const struct vev *e, int what)
 {
 	struct vclprog *vp;
-	double now = VTIM_mono();
 
 	(void)e;
 	(void)what;
-	VTAILQ_FOREACH(vp, &vclhead, list) {
-		if (vp->go_cold == 0)
-			continue;
-		if (strcmp(vp->state, "auto"))
-			continue;
-		if (vp->go_cold + mgt_param.vcl_cooldown < now)
-			mgt_vcl_setstate(vp, 0);
-	}
+	VTAILQ_FOREACH(vp, &vclhead, list)
+		mgt_vcl_setstate(vp, -1);
 	return (0);
 }
 
@@ -463,14 +458,13 @@ mgt_vcl_atexit(void)
 void
 mgt_vcl_init(void)
 {
-	struct vev *e;
-
-	e = vev_new();
-	AN(e);
-	e->timeout = 23;		// random, prime
-	e->callback = mgt_vcl_poker;
-	e->name = "vcl poker";
-	AZ(vev_add(mgt_evb, e));
+
+	e_poker = vev_new();
+	AN(e_poker);
+	e_poker->timeout = 3;		// random, prime
+	e_poker->callback = mgt_vcl_poker;
+	e_poker->name = "vcl poker";
+	AZ(vev_add(mgt_evb, e_poker));
 
 	AZ(atexit(mgt_vcl_atexit));
 }



More information about the varnish-commit mailing list