[master] f9b7f1818 Add coverage for backend creation in a cold VCL

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Dec 26 11:40:06 UTC 2019


commit f9b7f1818c83b1bfa20a09120f6d41e43023df81
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Thu Dec 26 12:31:00 2019 +0100

    Add coverage for backend creation in a cold VCL
    
    Refs #3176

diff --git a/bin/varnishtest/tests/v00063.vtc b/bin/varnishtest/tests/v00063.vtc
new file mode 100644
index 000000000..6e8508530
--- /dev/null
+++ b/bin/varnishtest/tests/v00063.vtc
@@ -0,0 +1,20 @@
+varnishtest "Create a backend after a COLD event"
+
+server s1 -start
+
+varnish v1 -cliok "param.set feature +no_coredump"
+varnish v1 -expectexit 0x20
+varnish v1 -vcl+backend {
+	import debug;
+	sub vcl_init {
+		debug.cold_backend();
+	}
+} -start
+
+# load and use a new VCL
+varnish v1 -vcl+backend {}
+
+# expect a panic during the COLD event
+varnish v1 -clierr 400 "vcl.state vcl1 cold"
+varnish v1 -cliexpect "Dynamic Backends can only be added to warm VCLs" panic.show
+varnish v1 -cliok panic.clear
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index c58397fcb..b8fe56f73 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -247,11 +247,15 @@ should now only be used for diagnostic purposes.
 
 $Function VOID vcl_prevent_cold(PRIV_VCL)
 
-Prevent VCL from going cold
+Prevent VCL from going cold.
 
 $Function VOID vcl_allow_cold(PRIV_VCL)
 
-Allow VCL to go cold
+Allow VCL to go cold.
+
+$Function VOID cold_backend(PRIV_VCL)
+
+Schedule a backend creation attempt when the VCL cools down, panic guaranteed.
 
 $Function VOID sndbuf(BYTES sndbuf)
 
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index 5b85a6fc8..e379f5c08 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -51,6 +51,7 @@ struct priv_vcl {
 	struct vclref		*vclref_cold;
 	VCL_DURATION		vcl_discard_delay;
 	VCL_BACKEND		be;
+	unsigned		cold_be;
 };
 
 
@@ -385,6 +386,8 @@ xyzzy_vcl_prevent_cold(VRT_CTX, struct vmod_priv *priv)
 	struct priv_vcl *priv_vcl;
 	char buf[32];
 
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	AN(priv);
 	CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
 	AZ(priv_vcl->vclref_cold);
 
@@ -397,13 +400,24 @@ xyzzy_vcl_allow_cold(VRT_CTX, struct vmod_priv *priv)
 {
 	struct priv_vcl *priv_vcl;
 
-	(void)ctx;
-
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	AN(priv);
 	CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
 	AN(priv_vcl->vclref_cold);
 	VRT_VCL_Allow_Cold(&priv_vcl->vclref_cold);
 }
 
+VCL_VOID
+xyzzy_cold_backend(VRT_CTX, struct vmod_priv *priv)
+{
+	struct priv_vcl *priv_vcl;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	AN(priv);
+	CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
+	priv_vcl->cold_be = 1;
+}
+
 static const struct vdi_methods empty_methods[1] = {{
 	.magic =	VDI_METHODS_MAGIC,
 	.type =	"debug.dummy"
@@ -426,8 +440,11 @@ event_warm(VRT_CTX, const struct vmod_priv *priv)
 	CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
 	AZ(priv_vcl->vclref_discard);
 
-	bprintf(buf, "vmod-debug ref on %s", VCL_Name(ctx->vcl));
-	priv_vcl->vclref_discard = VRT_VCL_Prevent_Discard(ctx, buf);
+	if (!priv_vcl->cold_be) {
+		/* NB: set up a COOLING step unless we want a COLD backend. */
+		bprintf(buf, "vmod-debug ref on %s", VCL_Name(ctx->vcl));
+		priv_vcl->vclref_discard = VRT_VCL_Prevent_Discard(ctx, buf);
+	}
 
 	AZ(priv_vcl->be);
 	priv_vcl->be = VRT_AddDirector(ctx, empty_methods,
@@ -454,15 +471,25 @@ event_cold(VRT_CTX, const struct vmod_priv *priv)
 {
 	pthread_t thread;
 	struct priv_vcl *priv_vcl;
+	struct vrt_backend be[1];
 
 	CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
-	AN(priv_vcl->vclref_discard);
 
 	VSL(SLT_Debug, 0, "%s: VCL_EVENT_COLD", VCL_Name(ctx->vcl));
 
 	VRT_DelDirector(&priv_vcl->be);
 
+	if (priv_vcl->cold_be) {
+		AZ(priv_vcl->vclref_discard);
+		INIT_OBJ(be, VRT_BACKEND_MAGIC);
+		be->path = "/";
+		be->vcl_name = "doomed";
+		priv_vcl->be = VRT_new_backend(ctx, be);
+		WRONG("unreachable");
+	}
+
 	if (priv_vcl->vcl_discard_delay == 0.0) {
+		AN(priv_vcl->vclref_discard);
 		VRT_VCL_Allow_Discard(&priv_vcl->vclref_discard);
 		return (0);
 	}


More information about the varnish-commit mailing list