[master] 02acb35b5 More work to turn our VCL dependency tracking into a proper symboltable with references.

Poul-Henning Kamp phk at FreeBSD.org
Mon May 27 08:01:10 UTC 2019


commit 02acb35b54eb22b39eada5e2ef12120d835718b9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon May 27 07:32:02 2019 +0000

    More work to turn our VCL dependency tracking into a proper symboltable
    with references.

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index 86ec2d460..41fffd334 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -89,6 +89,7 @@ varnishd_SOURCES = \
 	mgt/mgt_param_tweak.c \
 	mgt/mgt_pool.c \
 	mgt/mgt_shmem.c \
+	mgt/mgt_symtab.c \
 	mgt/mgt_util.c \
 	mgt/mgt_vcc.c \
 	mgt/mgt_vcl.c \
@@ -137,6 +138,7 @@ noinst_HEADERS = \
 	http1/cache_http1.h \
 	http2/cache_http2.h \
 	mgt/mgt.h \
+	mgt/mgt_vcl.h \
 	mgt/mgt_param.h \
 	storage/storage.h \
 	storage/storage_persistent.h \
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 78f79ce4d..82c34b52a 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -215,9 +215,7 @@ void mgt_vcl_init(void);
 void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin,
     const char *vclname, int Cflag);
 int mgt_push_vcls(struct cli *, unsigned *status, char **p);
-void mgt_vcl_export_labels(struct vcc *);
 int mgt_has_vcl(void);
-void mgt_vcl_symtab(struct vclprog *, struct vjsn *);
 extern char *mgt_cc_cmd;
 extern const char *mgt_vcl_path;
 extern const char *mgt_vmod_path;
diff --git a/bin/varnishd/mgt/mgt_symtab.c b/bin/varnishd/mgt/mgt_symtab.c
new file mode 100644
index 000000000..608c3c24e
--- /dev/null
+++ b/bin/varnishd/mgt/mgt_symtab.c
@@ -0,0 +1,200 @@
+/*-
+ * Copyright (c) 2019 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * VCL/VMOD symbol table
+ */
+
+#include "config.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "mgt/mgt.h"
+#include "mgt/mgt_vcl.h"
+
+#include "libvcc.h"
+#include "vjsn.h"
+
+/*--------------------------------------------------------------------*/
+
+static const char *
+mgt_vcl_symtab_val(const struct vjsn_val *vv, const char *val)
+{
+	const struct vjsn_val *jv;
+
+	jv = vjsn_child(vv, val);
+	AN(jv);
+	assert(jv->type == VJSN_STRING);
+	AN(jv->value);
+	return (jv->value);
+}
+
+static void
+mgt_vcl_import_vcl(struct vclprog *vp1, const struct vjsn_val *vv)
+{
+	struct vclprog *vp2;
+
+	CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
+	AN(vv);
+
+	vp2 = mcf_vcl_byname(mgt_vcl_symtab_val(vv, "name"));
+	CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
+	mgt_vcl_dep_add(vp1, vp2);
+}
+
+static int
+mgt_vcl_cache_vmod(const char *nm, const char *fm, const char *to)
+{
+	int fi, fo;
+	int ret = 0;
+	ssize_t sz;
+	char buf[BUFSIZ];
+
+	fo = open(to, O_WRONLY | O_CREAT | O_EXCL, 0744);
+	if (fo < 0 && errno == EEXIST)
+		return (0);
+	if (fo < 0) {
+		fprintf(stderr, "While creating copy of vmod %s:\n\t%s: %s\n",
+		    nm, to, vstrerror(errno));
+		return (1);
+	}
+	fi = open(fm, O_RDONLY);
+	if (fi < 0) {
+		fprintf(stderr, "Opening vmod %s from %s: %s\n",
+		    nm, fm, vstrerror(errno));
+		AZ(unlink(to));
+		closefd(&fo);
+		return (1);
+	}
+	while (1) {
+		sz = read(fi, buf, sizeof buf);
+		if (sz == 0)
+			break;
+		if (sz < 0 || sz != write(fo, buf, sz)) {
+			fprintf(stderr, "Copying vmod %s: %s\n",
+			    nm, vstrerror(errno));
+			AZ(unlink(to));
+			ret = 1;
+			break;
+		}
+	}
+	closefd(&fi);
+	AZ(fchmod(fo, 0444));
+	closefd(&fo);
+	return (ret);
+}
+
+static void
+mgt_vcl_import_vmod(struct vclprog *vp, const struct vjsn_val *vv)
+{
+	struct vmodfile *vf;
+	struct vmoddep *vd;
+	const char *v_name;
+	const char *v_file;
+	const char *v_dst;
+
+	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+	AN(vv);
+
+	v_name = mgt_vcl_symtab_val(vv, "name");
+	v_file = mgt_vcl_symtab_val(vv, "file");
+	v_dst = mgt_vcl_symtab_val(vv, "dst");
+
+	VTAILQ_FOREACH(vf, &vmodhead, list)
+		if (!strcmp(vf->fname, v_dst))
+			break;
+	if (vf == NULL) {
+		ALLOC_OBJ(vf, VMODFILE_MAGIC);
+		AN(vf);
+		REPLACE(vf->fname, v_dst);
+		AN(vf->fname);
+		VTAILQ_INIT(&vf->vcls);
+		AZ(mgt_vcl_cache_vmod(v_name, v_file, v_dst));
+		VTAILQ_INSERT_TAIL(&vmodhead, vf, list);
+	}
+	ALLOC_OBJ(vd, VMODDEP_MAGIC);
+	AN(vd);
+	vd->to = vf;
+	VTAILQ_INSERT_TAIL(&vp->vmods, vd, lfrom);
+	VTAILQ_INSERT_TAIL(&vf->vcls, vd, lto);
+}
+
+void
+mgt_vcl_symtab(struct vclprog *vp, const char *input)
+{
+	struct vjsn *vj;
+	struct vjsn_val *v1, *v2;
+	const char *typ, *err;
+
+	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+	AN(input);
+	vj = vjsn_parse(input, &err);
+	if (err != NULL) {
+		fprintf(stderr, "FATAL: Symtab parse error: %s\n%s\n",
+		    err, input);
+	}
+	AZ(err);
+	AN(vj);
+	vp->symtab = vj;
+	assert(vj->value->type == VJSN_ARRAY);
+	VTAILQ_FOREACH(v1, &vj->value->children, list) {
+		assert(v1->type == VJSN_OBJECT);
+		v2 = vjsn_child(v1, "dir");
+		if (v2 == NULL)
+			continue;
+		assert(v2->type == VJSN_STRING);
+		if (strcmp(v2->value, "import"))
+			continue;
+		typ = mgt_vcl_symtab_val(v1, "type");
+		if (!strcmp(typ, "$VMOD"))
+			mgt_vcl_import_vmod(vp, v1);
+		else if (!strcmp(typ, "$VCL"))
+			mgt_vcl_import_vcl(vp, v1);
+		else
+			WRONG("Bad symtab import entry");
+	}
+}
+
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_vcl_export_labels(struct vcc *vcc)
+{
+	struct vclprog *vp;
+	VTAILQ_FOREACH(vp, &vclhead, list) {
+		if (mcf_is_label(vp))
+			VCC_Predef(vcc, "VCL_VCL", vp->name);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index adb98efe6..5316ab299 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -39,25 +39,25 @@
 #include <sys/stat.h>
 
 #include "mgt/mgt.h"
+#include "mgt/mgt_vcl.h"
 #include "common/heritage.h"
 #include "storage/storage.h"
 
 #include "libvcc.h"
 #include "vcli_serve.h"
 #include "vfil.h"
-#include "vjsn.h"
 #include "vsub.h"
 #include "vtim.h"
 
 struct vcc_priv {
 	unsigned	magic;
 #define VCC_PRIV_MAGIC	0x70080cb8
-	char		*dir;
 	const char	*vclsrc;
 	const char	*vclsrcfile;
-	char		*csrcfile;
-	char		*libfile;
-	char		*symfile;
+	struct vsb	*dir;
+	struct vsb	*csrcfile;
+	struct vsb	*libfile;
+	struct vsb	*symfile;
 };
 
 char *mgt_cc_cmd;
@@ -96,7 +96,7 @@ run_vcc(void *priv)
 	VJ_subproc(JAIL_SUBPROC_VCC);
 	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
 
-	AZ(chdir(vp->dir));
+	AZ(chdir(VSB_data(vp->dir)));
 
 	vcc = VCC_New();
 	AN(vcc);
@@ -132,7 +132,7 @@ run_cc(void *priv)
 	VJ_subproc(JAIL_SUBPROC_CC);
 	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
 
-	AZ(chdir(vp->dir));
+	AZ(chdir(VSB_data(vp->dir)));
 
 	sb = VSB_new_auto();
 	AN(sb);
@@ -180,7 +180,7 @@ run_dlopen(void *priv)
 
 	VJ_subproc(JAIL_SUBPROC_VCLLOAD);
 	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
-	if (VCL_TestLoad(vp->libfile))
+	if (VCL_TestLoad(VSB_data(vp->libfile)))
 		exit(1);
 	exit(0);
 }
@@ -215,13 +215,13 @@ static unsigned
 mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
 {
 	char *csrc;
-	const char *err;
 	unsigned subs;
-	struct vjsn *vj;
 
-	if (mgt_vcc_touchfile(vp->csrcfile, sb))
+	AN(sb);
+	VSB_clear(sb);
+	if (mgt_vcc_touchfile(VSB_data(vp->csrcfile), sb))
 		return (2);
-	if (mgt_vcc_touchfile(vp->libfile, sb))
+	if (mgt_vcc_touchfile(VSB_data(vp->libfile), sb))
 		return (2);
 
 	subs = VSUB_run(sb, run_vcc, vp, "VCC-compiler", -1);
@@ -229,20 +229,15 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
 		return (subs);
 
 	if (C_flag) {
-		csrc = VFIL_readfile(NULL, vp->csrcfile, NULL);
+		csrc = VFIL_readfile(NULL, VSB_data(vp->csrcfile), NULL);
 		AN(csrc);
 		VSB_cat(sb, csrc);
 		free(csrc);
 
 		VSB_printf(sb, "/* EXTERNAL SYMBOL TABLE\n");
-		csrc = VFIL_readfile(NULL, vp->symfile, NULL);
+		csrc = VFIL_readfile(NULL, VSB_data(vp->symfile), NULL);
 		AN(csrc);
 		VSB_cat(sb, csrc);
-		vj = vjsn_parse(csrc, &err);
-		if (err != NULL)
-			VSB_printf(sb, "# Parse error: %s\n", err);
-		if (vj != NULL)
-			vjsn_delete(&vj);
 		VSB_printf(sb, "*/\n");
 		free(csrc);
 	}
@@ -257,25 +252,53 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
 
 /*--------------------------------------------------------------------*/
 
+static void
+mgt_vcc_init_vp(struct vcc_priv *vp)
+{
+	INIT_OBJ(vp, VCC_PRIV_MAGIC);
+	vp->csrcfile = VSB_new_auto();
+	AN(vp->csrcfile);
+	vp->libfile = VSB_new_auto();
+	AN(vp->libfile);
+	vp->symfile = VSB_new_auto();
+	AN(vp->symfile);
+	vp->dir = VSB_new_auto();
+	AN(vp->dir);
+}
+
+static void
+mgt_vcc_fini_vp(struct vcc_priv *vp, int leave_lib)
+{
+	if (!MGT_DO_DEBUG(DBG_VCL_KEEP)) {
+		(void)unlink(VSB_data(vp->csrcfile));
+		(void)unlink(VSB_data(vp->symfile));
+		if (!leave_lib)
+			(void)unlink(VSB_data(vp->libfile));
+	}
+	(void)rmdir(VSB_data(vp->dir));
+	VSB_destroy(&vp->csrcfile);
+	VSB_destroy(&vp->libfile);
+	VSB_destroy(&vp->symfile);
+	VSB_destroy(&vp->dir);
+}
+
 char *
 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 vcc_priv vp[1];
 	struct vsb *sb;
-	struct vjsn *vj;
 	unsigned status;
-	const char *err;
 	char *p;
 
 	AN(cli);
 
 	sb = VSB_new_auto();
-	XXXAN(sb);
+	AN(sb);
 
-	INIT_OBJ(&vp, VCC_PRIV_MAGIC);
-	vp.vclsrc = vclsrc;
-	vp.vclsrcfile = vclsrcfile;
+	mgt_vcc_init_vp(vp);
+	vp->vclsrc = vclsrc;
+	vp->vclsrcfile = vclsrcfile;
 
 	/*
 	 * The subdirectory must have a unique name to 100% certain evade
@@ -309,56 +332,35 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
 	 *
 	 * The Best way to reproduce this is to have regexps in the VCL.
 	 */
-	VSB_printf(sb, "vcl_%s.%.6f", vclname, VTIM_real());
-	AZ(VSB_finish(sb));
-	vp.dir = strdup(VSB_data(sb));
-	AN(vp.dir);
 
-	if (VJ_make_subdir(vp.dir, "VCL", cli->sb)) {
-		free(vp.dir);
+	VSB_printf(vp->dir, "vcl_%s.%.6f", vclname, VTIM_real());
+	AZ(VSB_finish(vp->dir));
+
+	VSB_printf(vp->csrcfile, "%s/%s", VSB_data(vp->dir), VGC_SRC);
+	AZ(VSB_finish(vp->csrcfile));
+
+	VSB_printf(vp->libfile, "%s/%s", VSB_data(vp->dir), VGC_LIB);
+	AZ(VSB_finish(vp->libfile));
+
+	VSB_printf(vp->symfile, "%s/%s", VSB_data(vp->dir), VGC_SYM);
+	AZ(VSB_finish(vp->symfile));
+
+	if (VJ_make_subdir(VSB_data(vp->dir), "VCL", cli->sb)) {
+		mgt_vcc_fini_vp(vp, 0);
 		VSB_destroy(&sb);
 		VCLI_Out(cli, "VCL compilation failed");
 		VCLI_SetResult(cli, CLIS_PARAM);
 		return (NULL);
 	}
 
-	VSB_clear(sb);
-	VSB_printf(sb, "%s/%s", vp.dir, VGC_SRC);
-	AZ(VSB_finish(sb));
-	vp.csrcfile = strdup(VSB_data(sb));
-	AN(vp.csrcfile);
-	VSB_clear(sb);
-
-	VSB_printf(sb, "%s/%s", vp.dir, VGC_LIB);
-	AZ(VSB_finish(sb));
-	vp.libfile = strdup(VSB_data(sb));
-	AN(vp.csrcfile);
-	VSB_clear(sb);
-
-	VSB_printf(sb, "%s/%s", vp.dir, VGC_SYM);
-	AZ(VSB_finish(sb));
-	vp.symfile = strdup(VSB_data(sb));
-	AN(vp.symfile);
-	VSB_clear(sb);
-
-	status = mgt_vcc_compile(&vp, sb, C_flag);
-
+	status = mgt_vcc_compile(vp, sb, C_flag);
 	AZ(VSB_finish(sb));
 	if (VSB_len(sb) > 0)
 		VCLI_Out(cli, "%s", VSB_data(sb));
 	VSB_destroy(&sb);
 
 	if (status || C_flag) {
-		if (!MGT_DO_DEBUG(DBG_VCL_KEEP)) {
-			(void)unlink(vp.csrcfile);
-			(void)unlink(vp.libfile);
-			(void)unlink(vp.symfile);
-			(void)rmdir(vp.dir);
-		}
-		free(vp.csrcfile);
-		free(vp.libfile);
-		free(vp.symfile);
-		free(vp.dir);
+		mgt_vcc_fini_vp(vp, 0);
 		if (status) {
 			VCLI_Out(cli, "VCL compilation failed");
 			VCLI_SetResult(cli, CLIS_PARAM);
@@ -366,26 +368,13 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
 		return (NULL);
 	}
 
-	p = VFIL_readfile(NULL, vp.symfile, NULL);
+	p = VFIL_readfile(NULL, VSB_data(vp->symfile), NULL);
 	AN(p);
-	vj = vjsn_parse(p, &err);
-	if (err != NULL)
-		fprintf(stderr, "FATAL: Symtab parse error: %s\n%s\n",
-		    err, p);
-	AZ(err);
-	AN(vj);
-	free(p);
-	mgt_vcl_symtab(vcl, vj);
-	(void)unlink(vp.symfile);
-	free(vp.symfile);
-
-	if (!MGT_DO_DEBUG(DBG_VCL_KEEP))
-		(void)unlink(vp.csrcfile);
-	free(vp.csrcfile);
-
-	free(vp.dir);
+	mgt_vcl_symtab(vcl, p);
 
 	VCLI_Out(cli, "VCL compiled.\n");
 
-	return (vp.libfile);
+	REPLACE(p, VSB_data(vp->libfile));
+	mgt_vcc_fini_vp(vp, 1);
+	return (p);
 }
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 1a388248c..88e8bcce0 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -31,17 +31,15 @@
 
 #include "config.h"
 
-#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/stat.h>
 
 #include "mgt/mgt.h"
+#include "mgt/mgt_vcl.h"
 #include "common/heritage.h"
 
-#include "libvcc.h"
 #include "vcli_serve.h"
 #include "vct.h"
 #include "vev.h"
@@ -56,53 +54,8 @@ static const char * const VCL_STATE_LABEL = "label";
 
 static int vcl_count;
 
-struct vclprog;
-struct vmodfile;
-
-struct vmoddep {
-	unsigned		magic;
-#define VMODDEP_MAGIC		0xc1490542
-	VTAILQ_ENTRY(vmoddep)	lfrom;
-	struct vmodfile		*to;
-	VTAILQ_ENTRY(vmoddep)	lto;
-};
-
-struct vcldep {
-	unsigned		magic;
-#define VCLDEP_MAGIC		0xa9a17dc2
-	struct vclprog		*from;
-	VTAILQ_ENTRY(vcldep)	lfrom;
-	struct vclprog		*to;
-	VTAILQ_ENTRY(vcldep)	lto;
-};
-
-struct vclprog {
-	unsigned		magic;
-#define VCLPROG_MAGIC		0x9ac09fea
-	VTAILQ_ENTRY(vclprog)	list;
-	char			*name;
-	char			*fname;
-	unsigned		warm;
-	const char *		state;
-	double			go_cold;
-	struct vjsn		*symtab;
-	VTAILQ_HEAD(, vcldep)	dfrom;
-	VTAILQ_HEAD(, vcldep)	dto;
-	int			nto;
-	int			loaded;
-	VTAILQ_HEAD(, vmoddep)	vmods;
-};
-
-struct vmodfile {
-	unsigned		magic;
-#define VMODFILE_MAGIC		0xffa1a0d5
-	char			*fname;
-	VTAILQ_ENTRY(vmodfile)	list;
-	VTAILQ_HEAD(, vmoddep)	vcls;
-};
-
-static VTAILQ_HEAD(, vclprog)	vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
-static VTAILQ_HEAD(, vmodfile)	vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead);
+struct vclproghead vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
+struct vmodfilehead vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead);
 static struct vclprog		*active_vcl;
 static struct vev *e_poker;
 
@@ -127,7 +80,7 @@ mcf_vcl_parse_state(struct cli *cli, const char *s)
 	return (NULL);
 }
 
-static struct vclprog *
+struct vclprog *
 mcf_vcl_byname(const char *name)
 {
 	struct vclprog *vp;
@@ -189,7 +142,7 @@ mcf_find_no_vcl(struct cli *cli, const char *name)
 	return (1);
 }
 
-static int
+int
 mcf_is_label(const struct vclprog *vp)
 {
 	return (vp->state == VCL_STATE_LABEL);
@@ -197,7 +150,7 @@ mcf_is_label(const struct vclprog *vp)
 
 /*--------------------------------------------------------------------*/
 
-static void
+void
 mgt_vcl_dep_add(struct vclprog *vp_from, struct vclprog *vp_to)
 {
 	struct vcldep *vd;
@@ -316,135 +269,6 @@ mgt_vcl_del(struct vclprog *vp)
 	FREE_OBJ(vp);
 }
 
-static const char *
-mgt_vcl_symtab_val(const struct vjsn_val *vv, const char *val)
-{
-	const struct vjsn_val *jv;
-
-	jv = vjsn_child(vv, val);
-	AN(jv);
-	assert(jv->type == VJSN_STRING);
-	AN(jv->value);
-	return (jv->value);
-}
-
-static void
-mgt_vcl_import_vcl(struct vclprog *vp1, const struct vjsn_val *vv)
-{
-	struct vclprog *vp2;
-
-	CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
-	AN(vv);
-
-	vp2 = mcf_vcl_byname(mgt_vcl_symtab_val(vv, "name"));
-	CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
-	mgt_vcl_dep_add(vp1, vp2);
-}
-
-static int
-mgt_vcl_cache_vmod(const char *nm, const char *fm, const char *to)
-{
-	int fi, fo;
-	int ret = 0;
-	ssize_t sz;
-	char buf[BUFSIZ];
-
-	fo = open(to, O_WRONLY | O_CREAT | O_EXCL, 0744);
-	if (fo < 0 && errno == EEXIST)
-		return (0);
-	if (fo < 0) {
-		fprintf(stderr, "While creating copy of vmod %s:\n\t%s: %s\n",
-		    nm, to, vstrerror(errno));
-		return (1);
-	}
-	fi = open(fm, O_RDONLY);
-	if (fi < 0) {
-		fprintf(stderr, "Opening vmod %s from %s: %s\n",
-		    nm, fm, vstrerror(errno));
-		AZ(unlink(to));
-		closefd(&fo);
-		return (1);
-	}
-	while (1) {
-		sz = read(fi, buf, sizeof buf);
-		if (sz == 0)
-			break;
-		if (sz < 0 || sz != write(fo, buf, sz)) {
-			fprintf(stderr, "Copying vmod %s: %s\n",
-			    nm, vstrerror(errno));
-			AZ(unlink(to));
-			ret = 1;
-			break;
-		}
-	}
-	closefd(&fi);
-	AZ(fchmod(fo, 0444));
-	closefd(&fo);
-	return (ret);
-}
-
-static void
-mgt_vcl_import_vmod(struct vclprog *vp, const struct vjsn_val *vv)
-{
-	struct vmodfile *vf;
-	struct vmoddep *vd;
-	const char *v_name;
-	const char *v_file;
-	const char *v_dst;
-
-	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
-	AN(vv);
-
-	v_name = mgt_vcl_symtab_val(vv, "name");
-	v_file = mgt_vcl_symtab_val(vv, "file");
-	v_dst = mgt_vcl_symtab_val(vv, "dst");
-
-	VTAILQ_FOREACH(vf, &vmodhead, list)
-		if (!strcmp(vf->fname, v_dst))
-			break;
-	if (vf == NULL) {
-		ALLOC_OBJ(vf, VMODFILE_MAGIC);
-		AN(vf);
-		REPLACE(vf->fname, v_dst);
-		AN(vf->fname);
-		VTAILQ_INIT(&vf->vcls);
-		AZ(mgt_vcl_cache_vmod(v_name, v_file, v_dst));
-		VTAILQ_INSERT_TAIL(&vmodhead, vf, list);
-	}
-	ALLOC_OBJ(vd, VMODDEP_MAGIC);
-	AN(vd);
-	vd->to = vf;
-	VTAILQ_INSERT_TAIL(&vp->vmods, vd, lfrom);
-	VTAILQ_INSERT_TAIL(&vf->vcls, vd, lto);
-}
-
-void
-mgt_vcl_symtab(struct vclprog *vp, struct vjsn *vj)
-{
-	struct vjsn_val *v1, *v2;
-	const char *typ;
-
-	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
-	vp->symtab = vj;
-	assert(vj->value->type == VJSN_ARRAY);
-	VTAILQ_FOREACH(v1, &vj->value->children, list) {
-		assert(v1->type == VJSN_OBJECT);
-		v2 = vjsn_child(v1, "dir");
-		if (v2 == NULL)
-			continue;
-		assert(v2->type == VJSN_STRING);
-		if (strcmp(v2->value, "import"))
-			continue;
-		typ = mgt_vcl_symtab_val(v1, "type");
-		if (!strcmp(typ, "$VMOD"))
-			mgt_vcl_import_vmod(vp, v1);
-		else if (!strcmp(typ, "$VCL"))
-			mgt_vcl_import_vcl(vp, v1);
-		else
-			WRONG("Bad symtab import entry");
-	}
-}
-
 int
 mgt_has_vcl(void)
 {
@@ -673,18 +497,6 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname,
 
 /*--------------------------------------------------------------------*/
 
-void
-mgt_vcl_export_labels(struct vcc *vcc)
-{
-	struct vclprog *vp;
-	VTAILQ_FOREACH(vp, &vclhead, list) {
-		if (mcf_is_label(vp))
-			VCC_Predef(vcc, "VCL_VCL", vp->name);
-	}
-}
-
-/*--------------------------------------------------------------------*/
-
 int
 mgt_push_vcls(struct cli *cli, unsigned *status, char **p)
 {
diff --git a/bin/varnishd/mgt/mgt_vcl.h b/bin/varnishd/mgt/mgt_vcl.h
new file mode 100644
index 000000000..21163d7ae
--- /dev/null
+++ b/bin/varnishd/mgt/mgt_vcl.h
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2019 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * VCL/VMOD symbol table
+ */
+
+struct vclprog;
+struct vmodfile;
+
+struct vmoddep {
+	unsigned		magic;
+#define VMODDEP_MAGIC		0xc1490542
+	VTAILQ_ENTRY(vmoddep)	lfrom;
+	struct vmodfile		*to;
+	VTAILQ_ENTRY(vmoddep)	lto;
+};
+
+struct vcldep {
+	unsigned		magic;
+#define VCLDEP_MAGIC		0xa9a17dc2
+	struct vclprog		*from;
+	VTAILQ_ENTRY(vcldep)	lfrom;
+	struct vclprog		*to;
+	VTAILQ_ENTRY(vcldep)	lto;
+};
+
+struct vclprog {
+	unsigned		magic;
+#define VCLPROG_MAGIC		0x9ac09fea
+	VTAILQ_ENTRY(vclprog)	list;
+	char			*name;
+	char			*fname;
+	unsigned		warm;
+	const char *		state;
+	double			go_cold;
+	struct vjsn		*symtab;
+	VTAILQ_HEAD(, vcldep)	dfrom;
+	VTAILQ_HEAD(, vcldep)	dto;
+	int			nto;
+	int			loaded;
+	VTAILQ_HEAD(, vmoddep)	vmods;
+};
+
+struct vmodfile {
+	unsigned		magic;
+#define VMODFILE_MAGIC		0xffa1a0d5
+	char			*fname;
+	VTAILQ_ENTRY(vmodfile)	list;
+	VTAILQ_HEAD(, vmoddep)	vcls;
+};
+
+extern VTAILQ_HEAD(vclproghead, vclprog)	vclhead;
+extern VTAILQ_HEAD(vmodfilehead, vmodfile)	vmodhead;
+
+struct vclprog *mcf_vcl_byname(const char *name);
+void mgt_vcl_dep_add(struct vclprog *vp_from, struct vclprog *vp_to);
+int mcf_is_label(const struct vclprog *vp);
+
+void mgt_vcl_export_labels(struct vcc *vcc);
+void mgt_vcl_symtab(struct vclprog *vp, const char *input);
+


More information about the varnish-commit mailing list