[master] 2e9560056 Prototypical code to make VEXTs containing VMODs work.

Poul-Henning Kamp phk at FreeBSD.org
Mon Aug 1 12:28:05 UTC 2022


commit 2e9560056977c3bea957a2c396ebd2ca66f8f2e1
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Aug 1 12:27:46 2022 +0000

    Prototypical code to make VEXTs containing VMODs work.

diff --git a/bin/varnishd/mgt/mgt_symtab.c b/bin/varnishd/mgt/mgt_symtab.c
index 754a6d528..7b9dec65f 100644
--- a/bin/varnishd/mgt/mgt_symtab.c
+++ b/bin/varnishd/mgt/mgt_symtab.c
@@ -122,10 +122,15 @@ mgt_vcl_import_vmod(struct vclprog *vp, const struct vjsn_val *vv)
 	const char *v_name;
 	const char *v_file;
 	const char *v_dst;
+	const struct vjsn_val *jv;
 
 	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
 	AN(vv);
 
+	jv = vjsn_child(vv, "vext");
+	if (vjsn_is_true(jv))
+		return;
+	AN(jv);
 	v_name = mgt_vcl_symtab_val(vv, "name");
 	v_file = mgt_vcl_symtab_val(vv, "file");
 	v_dst = mgt_vcl_symtab_val(vv, "dst");
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index d029ab057..0fcef8a72 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -88,8 +88,16 @@ mgt_DumpBuiltin(void)
 static void
 vcc_vext_iter_func(const char *filename, void *priv)
 {
+	struct vsb *sb;
 
-	VCC_VEXT(priv, filename);
+	/* VCC runs in the per-VCL subdir */
+	sb = VSB_new_auto();
+	AN(sb);
+	VSB_cat(sb, "../");
+	VSB_cat(sb, filename);
+	AZ(VSB_finish(sb));
+	VCC_VEXT(priv, VSB_data(sb));
+	VSB_destroy(&sb);
 }
 
 static void v_noreturn_ v_matchproto_(vsub_func_f)
diff --git a/bin/varnishtest/tests/README b/bin/varnishtest/tests/README
index 0f78207b7..a39d117d1 100644
--- a/bin/varnishtest/tests/README
+++ b/bin/varnishtest/tests/README
@@ -34,5 +34,6 @@ Naming scheme
 	id ~ ^t02	--> HTTP2
 	id ~ ^u		--> Utilities and background processes
 	id ~ ^v		--> VCL tests: execute VRT functions
+	id ~ ^x		--> VEXT tests
 
 	Coverage for individual VMODs is in "${top_srcdir}vmod/tests".
diff --git a/bin/varnishtest/tests/x00000.vtc b/bin/varnishtest/tests/x00000.vtc
new file mode 100644
index 000000000..7069f4c2c
--- /dev/null
+++ b/bin/varnishtest/tests/x00000.vtc
@@ -0,0 +1,25 @@
+varnishtest "Test VMOD import from VEXT"
+
+feature topbuild
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 \
+	-arg "-pvmod_path=/nonexistent" \
+	-arg "-E${topbuild}/vmod/.libs/libvmod_std.so" \
+	-vcl+backend {
+		import std;
+
+		sub vcl_deliver {
+			set resp.http.foobar = std.random(10,99);
+		}
+	} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.http.foobar ~ [0-9]
+} -run
diff --git a/lib/libvcc/flint.lnt b/lib/libvcc/flint.lnt
index 4e90fc671..4705d651c 100644
--- a/lib/libvcc/flint.lnt
+++ b/lib/libvcc/flint.lnt
@@ -4,6 +4,7 @@
 
 
 -sem(vcc_new_source, custodial(1))
+-sem(vcc_VmodLoad, custodial(2))
 -sem(acl_tree_VRBT_INSERT, custodial(2))
 
 -emacro(835, EXPR_VAR)	// Info 835: A zero has been given as right argument to operator '<<'
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index a23791dca..e0b065a8a 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -961,5 +961,5 @@ void
 VCC_VEXT(struct vcc *vcc, const char *filename)
 {
 	CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);
-	(void)filename;
+	vcc_ImportVext(vcc, filename);
 }
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 6f8b71f3b..a3e5d51e0 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -458,6 +458,7 @@ sym_wildcard_t vcc_Var_Wildcard;
 
 /* vcc_vmod.c */
 void vcc_ParseImport(struct vcc *tl);
+void vcc_ImportVext(struct vcc *tl, const char *filename);
 sym_act_f vcc_Act_New;
 
 /* vcc_xref.c */
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index a5e3990c4..cfa99d1c6 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -53,6 +53,8 @@ struct vmod_import {
 	struct vsb			*json;
 	char				*path;
 	VTAILQ_ENTRY(vmod_import)	list;
+	int				from_vext;
+	int				unimported_vext;
 
 	// From $VMOD
 	double				vmod_syntax;
@@ -195,13 +197,6 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
 	vim->minor = strtoul(vv3->value, &p, 10);
 	assert(p == NULL || *p == '\0' || *p == 'U');
 
-	if (!vcc_IdIs(vim->t_mod, vim->name)) {
-		VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n",
-		    PF(vim->t_mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", vim->path);
-		VSB_printf(tl->sb, "\tContains vmod \"%s\"\n", vim->name);
-		return ("");
-	}
 
 	if (vim->major == 0 && vim->minor == 0 &&
 	    strcmp(vim->abi, VMOD_ABI_Version)) {
@@ -353,8 +348,14 @@ vcc_emit_setup(struct vcc *tl, const struct vmod_import *vim)
 	VSB_cat(ifp->ini, ",\n");
 	AN(vim->file_id);
 	VSB_printf(ifp->ini, "\t    \"%s\",\n", vim->file_id);
-	VSB_printf(ifp->ini, "\t    \"./vmod_cache/_vmod_%.*s.%s\"\n",
-	    PF(mod), vim->file_id);
+	if (vim->from_vext) {
+		VSB_cat(ifp->ini, "\t    ");
+		VSB_quote(ifp->ini, vim->path, -1, VSB_QUOTE_CSTR);
+		VSB_cat(ifp->ini, "\n");
+	} else {
+		VSB_printf(ifp->ini, "\t    \"./vmod_cache/_vmod_%.*s.%s\"\n",
+		    PF(mod), vim->file_id);
+	}
 	VSB_cat(ifp->ini, "\t    ))\n");
 	VSB_cat(ifp->ini, "\t\treturn(1);");
 
@@ -362,6 +363,10 @@ vcc_emit_setup(struct vcc *tl, const struct vmod_import *vim)
 	VSB_cat(tl->symtab, "\t\"dir\": \"import\",\n");
 	VSB_cat(tl->symtab, "\t\"type\": \"$VMOD\",\n");
 	VSB_printf(tl->symtab, "\t\"name\": \"%.*s\",\n", PF(mod));
+	if (vim->from_vext)
+		VSB_printf(tl->symtab, "\t\"vext\": true,\n");
+	else
+		VSB_printf(tl->symtab, "\t\"vext\": false,\n");
 	VSB_printf(tl->symtab, "\t\"file\": \"%s\",\n", vim->path);
 	VSB_printf(tl->symtab, "\t\"dst\": \"./vmod_cache/_vmod_%.*s.%s\"\n",
 	    PF(mod), vim->file_id);
@@ -417,7 +422,7 @@ vcc_ParseImport(struct vcc *tl)
 	const char *p;
 	struct token *mod, *tmod, *t1;
 	struct symbol *msym, *vsym;
-	struct vmod_import *vim;
+	struct vmod_import *vim = NULL;
 	const struct vmod_import *vimold;
 
 	t1 = tl->t;
@@ -438,6 +443,7 @@ vcc_ParseImport(struct vcc *tl)
 	ERRCHK(tl);
 	AN(msym);
 
+	bprintf(fn, "libvmod_%.*s.so", PF(mod));
 	if (tl->t->tok == ID) {
 		if (!vcc_IdIs(tl->t, "from")) {
 			VSB_cat(tl->sb, "Expected 'from path ...'\n");
@@ -460,34 +466,56 @@ vcc_ParseImport(struct vcc *tl)
 			bprintf(fn, "%s", tl->t->dec);
 		vcc_NextToken(tl);
 	} else {
-		bprintf(fn, "libvmod_%.*s.so", PF(mod));
+		VTAILQ_FOREACH(vim, &imports, list) {
+			if (!vcc_IdIs(mod, vim->name))
+				continue;
+			if (!vim->unimported_vext)
+				continue;
+			fprintf(stderr, "IMPORT %s from VEXT\n", vim->name);
+			vim->unimported_vext = 0;
+			vim->t_mod = mod;
+			vim->sym = msym;
+			break;
+		}
 	}
 
 	SkipToken(tl, ';');
 
-	ALLOC_OBJ(vim, VMOD_IMPORT_MAGIC);
-	AN(vim);
-	vim->t_mod = mod;
-	vim->sym = msym;
+	if (vim == NULL) {
+		ALLOC_OBJ(vim, VMOD_IMPORT_MAGIC);
+		AN(vim);
+		vim->t_mod = mod;
+		vim->sym = msym;
+
+		if (VFIL_searchpath(tl->vmod_path, vcc_path_open, vim, fn, &vim->path)) {
+			if (vim->err == NULL) {
+				VSB_printf(tl->sb,
+				    "Could not find VMOD %.*s\n", PF(mod));
+			} else {
+				VSB_printf(tl->sb,
+				    "Could not open VMOD %.*s\n", PF(mod));
+				VSB_printf(tl->sb, "\tFile name: %s\n",
+				    vim->path != NULL ? vim->path : fn);
+				VSB_printf(tl->sb, "\tError: %s\n", vim->err);
+			}
+			vcc_ErrWhere(tl, mod);
+			vcc_vim_destroy(&vim);
+			return;
+		}
 
-	if (VFIL_searchpath(tl->vmod_path, vcc_path_open, vim, fn, &vim->path)) {
-		if (vim->err == NULL) {
-			VSB_printf(tl->sb,
-			    "Could not find VMOD %.*s\n", PF(mod));
-		} else {
-			VSB_printf(tl->sb,
-			    "Could not open VMOD %.*s\n", PF(mod));
-			VSB_printf(tl->sb, "\tFile name: %s\n",
-			    vim->path != NULL ? vim->path : fn);
-			VSB_printf(tl->sb, "\tError: %s\n", vim->err);
+		if (vcc_VmodLoad(tl, vim) < 0 || tl->err) {
+			vcc_ErrWhere(tl, vim->t_mod);
+			vcc_vim_destroy(&vim);
+			return;
 		}
-		vcc_ErrWhere(tl, mod);
-		vcc_vim_destroy(&vim);
-		return;
 	}
 
-	if (vcc_VmodLoad(tl, vim) < 0 || tl->err) {
+	if (!vcc_IdIs(vim->t_mod, vim->name)) {
 		vcc_ErrWhere(tl, vim->t_mod);
+		VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n",
+		    PF(vim->t_mod));
+		VSB_printf(tl->sb, "\tFile name: %s\n", vim->path);
+		VSB_printf(tl->sb, "\tContains vmod \"%s\"\n", vim->name);
 		vcc_vim_destroy(&vim);
 		return;
 	}
@@ -534,3 +562,29 @@ vcc_ParseImport(struct vcc *tl)
 
 	vcc_emit_setup(tl, vim);
 }
+
+void
+vcc_ImportVext(struct vcc *tl, const char *filename)
+{
+	struct vmod_import *vim;
+
+	ALLOC_OBJ(vim, VMOD_IMPORT_MAGIC);
+	AN(vim);
+
+	if (vcc_Extract_JSON(vim, filename)) {
+		FREE_OBJ(vim);
+		return;
+	}
+	fprintf(stderr, "FOUND VMOD in VEXT %s\n", filename);
+	if (vcc_VmodLoad(tl, vim) < 0 || tl->err) {
+		// vcc_ErrWhere(tl, vim->t_mod);
+		vcc_vim_destroy(&vim);
+		return;
+	}
+	vim->from_vext = 1;
+	vim->unimported_vext = 1;
+	vim->path = strdup(filename);
+	vim->path += 1;
+	AN(vim->path);
+	fprintf(stderr, "GOOD VMOD %s in VEXT %s\n", vim->name, filename);
+}


More information about the varnish-commit mailing list