[master] 2d1c467 Track VCL->VCL dependencies

Poul-Henning Kamp phk at FreeBSD.org
Tue Aug 16 11:20:16 CEST 2016


commit 2d1c4679a5300e21c23bc2292f8e7be03141250f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Aug 16 09:02:37 2016 +0000

    Track VCL->VCL dependencies

diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 29ada85..1877424 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -36,6 +36,7 @@
 struct cli;
 struct parspec;
 struct vcc;
+struct vclprog;
 
 extern struct vev_base	*mgt_evb;
 extern unsigned		d_flag;
@@ -170,8 +171,8 @@ void STV_Config(const char *spec);
 void STV_Config_Transient(void);
 
 /* mgt_vcc.c */
-char *mgt_VccCompile(struct cli *, const char *vclname, const char *vclsrc,
-    const char *vclsrcfile, int C_flag);
+char *mgt_VccCompile(struct cli *, struct vclprog *, const char *vclname,
+    const char *vclsrc, const char *vclsrcfile, int C_flag);
 
 void mgt_vcl_init(void);
 void mgt_vcc_startup(struct cli *, const char *b_arg, const char *f_arg,
@@ -179,6 +180,7 @@ void mgt_vcc_startup(struct cli *, const char *b_arg, const char *f_arg,
 int mgt_push_vcls_and_start(struct cli *, unsigned *status, char **p);
 void mgt_vcl_export_labels(struct vcc *);
 int mgt_has_vcl(void);
+void mgt_vcl_depends(struct vclprog *vp1, const char *name);
 extern char *mgt_cc_cmd;
 extern const char *mgt_vcl_path;
 extern const char *mgt_vmod_path;
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index 36dbbd4..f8d6224 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -47,6 +47,7 @@
 #include "vcli_serve.h"
 #include "vfil.h"
 #include "vsub.h"
+#include "vav.h"
 #include "vtim.h"
 
 struct vcc_priv {
@@ -258,12 +259,16 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
 /*--------------------------------------------------------------------*/
 
 char *
-mgt_VccCompile(struct cli *cli, const char *vclname, const char *vclsrc,
-    const char *vclsrcfile, int C_flag)
+mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
+    const char *vclsrc, const char *vclsrcfile, int C_flag)
 {
 	struct vcc_priv vp;
 	struct vsb *sb;
 	unsigned status;
+	char buf[1024];
+	FILE *fcs;
+	char **av;
+	int ac;
 
 	AN(cli);
 
@@ -339,10 +344,9 @@ mgt_VccCompile(struct cli *cli, const char *vclname, const char *vclsrc,
 		VCLI_Out(cli, "%s", VSB_data(sb));
 	VSB_destroy(&sb);
 
-	(void)unlink(vp.csrcfile);
-	free(vp.csrcfile);
-
 	if (status || C_flag) {
+		(void)unlink(vp.csrcfile);
+		free(vp.csrcfile);
 		(void)unlink(vp.libfile);
 		free(vp.libfile);
 		(void)rmdir(vp.dir);
@@ -354,6 +358,26 @@ mgt_VccCompile(struct cli *cli, const char *vclname, const char *vclsrc,
 		return (NULL);
 	}
 
+	fcs = fopen(vp.csrcfile, "r");
+	AN(fcs);
+	while (1) {
+		AN(fgets(buf, sizeof buf, fcs));
+		if (memcmp(buf, VCC_INFO_PREFIX, strlen(VCC_INFO_PREFIX)))
+			break;
+		av = VAV_Parse(buf, &ac, 0);
+		AN(av);
+		AZ(av[0]);
+		AZ(strcmp(av[1], "/*"));
+		AZ(strcmp(av[ac-1], "*/"));
+		AZ(strcmp(av[3], "VCL"));
+		mgt_vcl_depends(vcl, av[4]);
+		VAV_Free(av);
+	}
+	AZ(fclose(fcs));
+
+	(void)unlink(vp.csrcfile);
+	free(vp.csrcfile);
+
 	free(vp.dir);
 
 	VCLI_Out(cli, "VCL compiled.\n");
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 245fa54..6b873a5 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -109,7 +109,7 @@ mgt_vcl_dep_del(struct vcldep *vd)
 /*--------------------------------------------------------------------*/
 
 static struct vclprog *
-mgt_vcl_add(const char *name, const char *libfile, const char *state)
+mgt_vcl_add(const char *name, const char *state)
 {
 	struct vclprog *vp;
 
@@ -120,7 +120,6 @@ mgt_vcl_add(const char *name, const char *libfile, const char *state)
 	ALLOC_OBJ(vp, VCLPROG_MAGIC);
 	XXXAN(vp);
 	REPLACE(vp->name, name);
-	REPLACE(vp->fname, libfile);
 	VTAILQ_INIT(&vp->dfrom);
 	VTAILQ_INIT(&vp->dto);
 	vp->state = state;
@@ -144,7 +143,7 @@ mgt_vcl_del(struct vclprog *vp)
 		mgt_vcl_dep_del(VTAILQ_FIRST(&vp->dfrom));
 
 	VTAILQ_REMOVE(&vclhead, vp, list);
-	if (strcmp(vp->state, VCL_STATE_LABEL)) {
+	if (vp->fname != NULL) {
 		AZ(unlink(vp->fname));
 		p = strrchr(vp->fname, '/');
 		AN(p);
@@ -175,6 +174,18 @@ mgt_vcl_byname(const char *name)
 	return (NULL);
 }
 
+void
+mgt_vcl_depends(struct vclprog *vp1, const char *name)
+{
+	struct vclprog *vp2;
+
+	CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
+
+	vp2 = mgt_vcl_byname(name);
+	CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
+	mgt_vcl_dep_add(vp1, vp2);
+}
+
 int
 mgt_has_vcl(void)
 {
@@ -261,13 +272,15 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc,
 		return;
 	}
 
-	lib = mgt_VccCompile(cli, vclname, vclsrc, vclsrcfile, C_flag);
-	if (lib == NULL)
+	vp = mgt_vcl_add(vclname, state);
+	lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfile, C_flag);
+	if (lib == NULL) {
+		mgt_vcl_del(vp);
 		return;
+	}
 
 	AZ(C_flag);
-	vp = mgt_vcl_add(vclname, lib, state);
-	free(lib);
+	vp->fname = lib;
 
 	if (child_pid < 0)
 		return;
@@ -311,8 +324,10 @@ void
 mgt_vcl_export_labels(struct vcc *vcc)
 {
 	struct vclprog *vp;
-	VTAILQ_FOREACH(vp, &vclhead, list)
-		VCC_Predef(vcc, "VCL_VCL", vp->name);
+	VTAILQ_FOREACH(vp, &vclhead, list) {
+		if (!strcmp(vp->state, VCL_STATE_LABEL))
+			VCC_Predef(vcc, "VCL_VCL", vp->name);
+	}
 }
 
 /*--------------------------------------------------------------------*/
@@ -493,6 +508,8 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
 	unsigned status;
 	char *p = NULL;
 	struct vclprog *vp;
+	struct vcldep *vd;
+	int n;
 
 	(void)priv;
 	vp = mcf_find_vcl(cli, av[2]);
@@ -504,7 +521,7 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
 		return;
 	}
 	if (!VTAILQ_EMPTY(&vp->dto)) {
-		if (vp->label != NULL) {
+		if (vp->label != NULL && strcmp(vp->state, VCL_STATE_LABEL)) {
 			AN(vp->warm);
 			VCLI_SetResult(cli, CLIS_PARAM);
 			VCLI_Out(cli,
@@ -512,7 +529,19 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
 			    vp->label->name);
 			return;
 		}
-		INCOMPL();
+		VCLI_SetResult(cli, CLIS_PARAM);
+		VCLI_Out(cli,
+		    "Cannot discard \"%s\" VCL label, "
+		    "other VCLs depend on it.\n", vp->name);
+		n = 0;
+		VTAILQ_FOREACH(vd, &vp->dto, lto) {
+			if (n++ == 5) {
+				VCLI_Out(cli, "\t[...]");
+				break;
+			}
+			VCLI_Out(cli, "\t%s\n", vd->from->name);
+		}
+		return;
 	}
 	if (!strcmp(vp->state, VCL_STATE_LABEL)) {
 		AN(vp->warm);
@@ -600,7 +629,13 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
 		mgt_vcl_dep_del(VTAILQ_FIRST(&vpl->dfrom));
 		AN(VTAILQ_EMPTY(&vpl->dfrom));
 	} else {
-		vpl = mgt_vcl_add(av[2], NULL, VCL_STATE_LABEL);
+		/* XXX should check for C-syntax */
+		if (strchr(av[2], '.')) {
+			VCLI_SetResult(cli, CLIS_PARAM);
+			VCLI_Out(cli, "VCL labels cannot contain '.'");
+			return;
+		}
+		vpl = mgt_vcl_add(av[2], VCL_STATE_LABEL);
 	}
 	AN(vpl);
 	mgt_vcl_dep_add(vpl, vpt);



More information about the varnish-commit mailing list