[master] 202417a Don't put the cli in VRT_CTX, but give it a vsb for complaints during initialization.

Poul-Henning Kamp phk at FreeBSD.org
Mon Jun 15 09:39:58 CEST 2015


commit 202417a5b9cf0da780eca710c4f057aaf5cd166a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jun 15 07:39:14 2015 +0000

    Don't put the cli in VRT_CTX, but give it a vsb for complaints
    during initialization.
    
    Use vmod_debug to test this.

diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 18631f8..422d6fd 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -197,6 +197,8 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
 	struct VCL_conf const *cnf;
 	struct vrt_ctx ctx;
 	unsigned hand = 0;
+	struct vsb *vsb;
+	int i;
 
 	ASSERT_CLI();
 
@@ -237,26 +239,39 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
 	INIT_OBJ(&ctx, VRT_CTX_MAGIC);
 	ctx.method = VCL_MET_INIT;
 	ctx.handling = &hand;
-	ctx.cli = cli;
 	ctx.vcl = vcl->conf;
 
-	if (vcl->conf->event_vcl(&ctx, VCL_EVENT_LOAD)) {
+	vsb = VSB_new_auto();
+	AN(vsb);
+	ctx.msg = vsb;
+	i = vcl->conf->event_vcl(&ctx, VCL_EVENT_LOAD);
+	AZ(VSB_finish(vsb));
+	if (i) {
 		VCLI_Out(cli, "VCL \"%s\" Failed to initialize", name);
+		if (VSB_len(vsb))
+			VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb));
 		AZ(vcl->conf->event_vcl(&ctx, VCL_EVENT_DISCARD));
 		(void)dlclose(vcl->dlh);
 		FREE_OBJ(vcl);
+		VSB_delete(vsb);
 		return (1);
 	}
+	VSB_clear(vsb);
 	(void)vcl->conf->init_func(&ctx);
+	AZ(VSB_finish(vsb));
 	if (hand == VCL_RET_FAIL) {
 		VCLI_Out(cli, "VCL \"%s\" vcl_init{} failed", name);
+		if (VSB_len(vsb))
+			VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb));
 		ctx.method = VCL_MET_FINI;
 		(void)vcl->conf->fini_func(&ctx);
 		AZ(vcl->conf->event_vcl(&ctx, VCL_EVENT_DISCARD));
 		(void)dlclose(vcl->dlh);
 		FREE_OBJ(vcl);
+		VSB_delete(vsb);
 		return (1);
 	}
+	VSB_delete(vsb);
 	vcl_set_state(vcl, state);
 	assert(hand == VCL_RET_OK);
 	VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
@@ -392,6 +407,8 @@ ccf_config_use(struct cli *cli, const char * const *av, void *priv)
 	struct vcls *vcl;
 	struct vrt_ctx ctx;
 	unsigned hand = 0;
+	struct vsb *vsb;
+	int i;
 
 	ASSERT_CLI();
 	AZ(priv);
@@ -400,16 +417,23 @@ ccf_config_use(struct cli *cli, const char * const *av, void *priv)
 	AN(vcl->warm);			// MGT ensures this
 	INIT_OBJ(&ctx, VRT_CTX_MAGIC);
 	ctx.handling = &hand;
-	ctx.cli = cli;
-	if (vcl->conf->event_vcl(&ctx, VCL_EVENT_USE)) {
+	vsb = VSB_new_auto();
+	AN(vsb);
+	ctx.msg = vsb;
+	i = vcl->conf->event_vcl(&ctx, VCL_EVENT_USE);
+	AZ(VSB_finish(vsb));
+	if (i) {
 		VCLI_Out(cli, "VCL \"%s\" Failed to activate", av[2]);
+		if (VSB_len(vsb) > 0)
+			VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(vsb));
 		VCLI_SetResult(cli, CLIS_CANT);
-		return;
+	} else {
+		Lck_Lock(&vcl_mtx);
+		vcl_active = vcl;
+		Lck_Unlock(&vcl_mtx);
 	}
-
-	Lck_Lock(&vcl_mtx);
-	vcl_active = vcl;
-	Lck_Unlock(&vcl_mtx);
+	VSB_delete(vsb);
+	return;
 }
 
 static void __match_proto__(cli_func_t)
diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c
index 5245708..50e2d61 100644
--- a/bin/varnishd/cache/cache_vrt_vmod.c
+++ b/bin/varnishd/cache/cache_vrt_vmod.c
@@ -72,15 +72,15 @@ VRT_Vmod_Init(struct vmod **hdl, void *ptr, int len, const char *nm,
 
 	ASSERT_CLI();
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	AN(ctx->cli);
+	AN(ctx->msg);
 	AN(hdl);
 	AZ(*hdl);
 
 	dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
 	if (dlhdl == NULL) {
-		VCLI_Out(ctx->cli, "Loading VMOD %s from %s:\n", nm, path);
-		VCLI_Out(ctx->cli, "dlopen() failed: %s\n", dlerror());
-		VCLI_Out(ctx->cli, "Check child process permissions.\n");
+		VSB_printf(ctx->msg, "Loading VMOD %s from %s:\n", nm, path);
+		VSB_printf(ctx->msg, "dlopen() failed: %s\n", dlerror());
+		VSB_printf(ctx->msg, "Check child process permissions.\n");
 		return (1);
 	}
 
@@ -98,9 +98,9 @@ VRT_Vmod_Init(struct vmod **hdl, void *ptr, int len, const char *nm,
 		if (d == NULL ||
 		    d->file_id == NULL ||
 		    strcmp(d->file_id, file_id)) {
-			VCLI_Out(ctx->cli,
+			VSB_printf(ctx->msg,
 			    "Loading VMOD %s from %s:\n", nm, path);
-			VCLI_Out(ctx->cli,
+			VSB_printf(ctx->msg,
 			    "This is no longer the same file seen by"
 			    " the VCL-compiler.\n");
 			(void)dlclose(v->hdl);
@@ -116,9 +116,9 @@ VRT_Vmod_Init(struct vmod **hdl, void *ptr, int len, const char *nm,
 		    d->proto == NULL ||
 		    d->spec == NULL ||
 		    d->abi == NULL) {
-			VCLI_Out(ctx->cli,
+			VSB_printf(ctx->msg,
 			    "Loading VMOD %s from %s:\n", nm, path);
-			VCLI_Out(ctx->cli, "VMOD data is mangled.\n");
+			VSB_printf(ctx->msg, "VMOD data is mangled.\n");
 			(void)dlclose(v->hdl);
 			FREE_OBJ(v);
 			return (1);
diff --git a/bin/varnishtest/tests/m00022.vtc b/bin/varnishtest/tests/m00022.vtc
new file mode 100644
index 0000000..5febb43
--- /dev/null
+++ b/bin/varnishtest/tests/m00022.vtc
@@ -0,0 +1,28 @@
+varnishtest "Test std & debug vmod"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend { } -start
+
+varnish v1 -errvcl "Planned failure in vcl_init" {
+
+	import ${vmod_debug};
+
+	backend default {
+		.host = "${s1_addr}";
+	}
+
+	sub vcl_init {
+		debug.init_fail();
+		return (fail);
+	}
+}
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+} -run
diff --git a/include/vrt.h b/include/vrt.h
index dca5902..4ccadbc 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -54,7 +54,7 @@ struct busyobj;
 struct vsl_log;
 struct http;
 struct ws;
-struct cli;
+struct vsb;
 struct director;
 struct VCL_conf;
 struct suckaddr;
@@ -93,7 +93,7 @@ struct vrt_ctx {
 	unsigned			method;
 	unsigned			*handling;
 
-	struct cli			*cli;	// Only in ...init()
+	struct vsb			*msg;	// Only in ...init()
 	struct vsl_log			*vsl;
 	struct VCL_conf			*vcl;
 	struct ws			*ws;
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index 434ee78..2e08154 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -101,3 +101,7 @@ $Function INT vre_limit()
 $Function VOID register_exp_callback(PRIV_VCL)
 
 Register the vmod to receive expiry callbacks
+
+$Function VOID init_fail()
+
+Function to fail vcl_init{}
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index ccdcab3..9e02297 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -34,6 +34,7 @@
 #include "cache/cache.h"
 
 #include "vrt.h"
+#include "vsb.h"
 #include "vcc_if.h"
 
 struct priv_vcl {
@@ -220,6 +221,14 @@ vmod_register_exp_callback(VRT_CTX, struct vmod_priv *priv)
 	VSL(SLT_Debug, 0, "exp_cb: registered");
 }
 
+VCL_VOID __match_proto__()
+vmod_init_fail(VRT_CTX)
+{
+
+	AN(ctx->msg);
+	VSB_printf(ctx->msg, "Planned failure in vcl_init{}");
+}
+
 static void __match_proto__(vmod_priv_free_f)
 priv_vcl_free(void *priv)
 {



More information about the varnish-commit mailing list