[experimental-ims] b3690c6 Make it possible for VCL initializtion to fail gracefully, particularly so VMOD loading can emit sensible diagnostics.

Geoff Simmons geoff at varnish-cache.org
Mon Jan 9 21:51:46 CET 2012


commit b3690c63fdbb06caf6b33aa55b8ca83a1b8455d2
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Sep 7 19:30:48 2011 +0000

    Make it possible for VCL initializtion to fail gracefully, particularly
    so VMOD loading can emit sensible diagnostics.

diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c
index 49f3fbb..ac712fb 100644
--- a/bin/varnishd/cache_vcl.c
+++ b/bin/varnishd/cache_vcl.c
@@ -170,10 +170,15 @@ VCL_Load(const char *fn, const char *name, struct cli *cli)
 		FREE_OBJ(vcl);
 		return (1);
 	}
+	if (vcl->conf->init_vcl(cli)) {
+		VCLI_Out(cli, "VCL \"%s\" Failed to initialize", name);
+		(void)dlclose(vcl->dlh);
+		FREE_OBJ(vcl);
+		return (1);
+	}
 	REPLACE(vcl->name, name);
-	VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
 	VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
-	vcl->conf->init_vcl(cli);
+	VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
 	(void)vcl->conf->init_func(NULL);
 	Lck_Lock(&vcl_mtx);
 	if (vcl_active == NULL)
diff --git a/bin/varnishd/cache_vrt_vmod.c b/bin/varnishd/cache_vrt_vmod.c
index 4a4d230..84a2bb7 100644
--- a/bin/varnishd/cache_vrt_vmod.c
+++ b/bin/varnishd/cache_vrt_vmod.c
@@ -60,12 +60,12 @@ struct vmod {
 
 static VTAILQ_HEAD(,vmod)	vmods = VTAILQ_HEAD_INITIALIZER(vmods);
 
-void
-VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
+int
+VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
+    const char *path, struct cli *cli)
 {
 	struct vmod *v;
-	void *x;
-	const int *i;
+	void *x, *y, *z;
 
 	ASSERT_CLI();
 
@@ -76,31 +76,46 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
 		ALLOC_OBJ(v, VMOD_MAGIC);
 		AN(v);
 
-		VTAILQ_INSERT_TAIL(&vmods, v, list);
-		VSC_C_main->vmods++;
-
-		REPLACE(v->nm, nm);
-		REPLACE(v->path, path);
-
-		v->hdl = dlopen(v->path, RTLD_NOW | RTLD_LOCAL);
-		if (! v->hdl) {
-			char buf[1024];
-			sprintf(buf, "dlopen failed (child process lacks permission?): %.512s", dlerror());
-			VAS_Fail(__func__, __FILE__, __LINE__, buf, 0, 0);
+		v->hdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+		if (v->hdl == NULL) {
+			VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+			VCLI_Out(cli, "dlopen() failed: %s\n", dlerror());
+			VCLI_Out(cli, "Check child process permissions.\n"); 
+			FREE_OBJ(v);
+			return (1);
 		}
 
 		x = dlsym(v->hdl, "Vmod_Name");
+		y = dlsym(v->hdl, "Vmod_Len");
+		z = dlsym(v->hdl, "Vmod_Func");
+		if (x == NULL || y == NULL || z == NULL) {
+			VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+			VCLI_Out(cli, "VMOD symbols not found\n");
+			VCLI_Out(cli, "Check relative pathnames.\n");
+			(void)dlclose(v->hdl);
+			FREE_OBJ(v);
+			return (1);
+		}
 		AN(x);
-		/* XXX: check that name is correct */
+		AN(y);
+		AN(z);
+		if (strcmp(x, nm)) {
+			VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+			VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n", x);
+			VCLI_Out(cli, "Check relative pathnames ?.\n");
+			(void)dlclose(v->hdl);
+			FREE_OBJ(v);
+			return (1);
+		}
 
-		x = dlsym(v->hdl, "Vmod_Len");
-		AN(x);
-		i = x;
-		v->funclen = *i;
+		v->funclen = *(const int *)y;
+		v->funcs = z;
 
-		x = dlsym(v->hdl, "Vmod_Func");
-		AN(x);
-		v->funcs = x;
+		REPLACE(v->nm, nm);
+		REPLACE(v->path, path);
+
+		VSC_C_main->vmods++;
+		VTAILQ_INSERT_TAIL(&vmods, v, list);
 	}
 
 	assert(len == v->funclen);
@@ -108,6 +123,7 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
 	v->ref++;
 
 	*hdl = v;
+	return (0);
 }
 
 void
diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c
index 2664931..ebdf57b 100644
--- a/bin/varnishd/mgt_child.c
+++ b/bin/varnishd/mgt_child.c
@@ -385,7 +385,7 @@ start_child(struct cli *cli)
 	mgt_cli_start_child(child_cli_in, child_VCLI_Out);
 	child_pid = pid;
 	if (mgt_push_vcls_and_start(&u, &p)) {
-		REPORT(LOG_ERR, "Pushing vcls failed: %s", p);
+		REPORT(LOG_ERR, "Pushing vcls failed:\n%s", p);
 		free(p);
 		child_state = CH_RUNNING;
 		mgt_stop_child();
diff --git a/include/vrt.h b/include/vrt.h
index cfafe75..9f0228f 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -183,8 +183,8 @@ void VRT_init_dir(struct cli *, struct director **, const char *name,
 void VRT_fini_dir(struct cli *, struct director *);
 
 /* VMOD/Modules related */
-void VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
-    const char *path);
+int VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
+    const char *path, struct cli *cli);
 void VRT_Vmod_Fini(void **hdl);
 
 struct vmod_priv;
diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py
index 5407a51..fde8bb2 100755
--- a/lib/libvcl/generate.py
+++ b/lib/libvcl/generate.py
@@ -712,7 +712,7 @@ fo.write("""
 struct sess;
 struct cli;
 
-typedef void vcl_init_f(struct cli *);
+typedef int vcl_init_f(struct cli *);
 typedef void vcl_fini_f(struct cli *);
 typedef int vcl_func_f(struct sess *sp);
 """)
diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c
index b0019ca..c2a52d4 100644
--- a/lib/libvcl/vcc_compile.c
+++ b/lib/libvcl/vcc_compile.c
@@ -310,9 +310,10 @@ static void
 EmitInitFunc(const struct vcc *tl)
 {
 
-	Fc(tl, 0, "\nstatic void\nVGC_Init(struct cli *cli)\n{\n\n");
+	Fc(tl, 0, "\nstatic int\nVGC_Init(struct cli *cli)\n{\n\n");
 	AZ(VSB_finish(tl->fi));
 	VSB_cat(tl->fc, VSB_data(tl->fi));
+	Fc(tl, 0, "\treturn(0);\n");
 	Fc(tl, 0, "}\n");
 }
 
@@ -321,7 +322,7 @@ EmitFiniFunc(const struct vcc *tl)
 {
 	unsigned u;
 
-	Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
+	Fc(tl, 0, "\nstatic int\nVGC_Fini(struct cli *cli)\n{\n\n");
 
 	/*
 	 * We do this here, so we are sure they happen before any
@@ -332,6 +333,7 @@ EmitFiniFunc(const struct vcc *tl)
 
 	AZ(VSB_finish(tl->ff));
 	VSB_cat(tl->fc, VSB_data(tl->ff));
+	Fc(tl, 0, "\treturn(0);\n");
 	Fc(tl, 0, "}\n");
 }
 
diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c
index 35cc702..f74f874 100644
--- a/lib/libvcl/vcc_vmod.c
+++ b/lib/libvcl/vcc_vmod.c
@@ -102,13 +102,15 @@ vcc_ParseImport(struct vcc *tl)
 
 	Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod));
 
-	Fi(tl, 0, "\tVRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
+	Fi(tl, 0, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
 	Fi(tl, 0, "\t    &Vmod_Func_%.*s,\n", PF(mod));
 	Fi(tl, 0, "\t    sizeof(Vmod_Func_%.*s),\n", PF(mod));
 	Fi(tl, 0, "\t    \"%.*s\",\n", PF(mod));
 	Fi(tl, 0, "\t    ");
 	EncString(tl->fi, fn, NULL, 0);
-	Fi(tl, 0, ");\n");
+	Fi(tl, 0, ",\n\t    ");
+	Fi(tl, 0, "cli))\n");
+	Fi(tl, 0, "\t\treturn(1);\n");
 
 	SkipToken(tl, ';');
 



More information about the varnish-commit mailing list