[master] 667256f Fix the spinlock loop in VBE_Poll

Martin Blix Grydeland martin at varnish-software.com
Mon Apr 3 13:46:06 CEST 2017


commit 667256f191066672ec85c79e35bc9f995409c034
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Fri Mar 31 13:12:24 2017 +0200

    Fix the spinlock loop in VBE_Poll
    
    VBE_Poll would not advance to test the next backend on the cooling
    list when the backend's n_conn is non-zero. This would create a
    spinlock effect, causing delays that could make the master kill the
    child because of CLI timeout.
    
    Fixes: #2295

diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index 767a87c..e4acf8a 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -435,15 +435,13 @@ static struct cli_proto backend_cmds[] = {
 void
 VBE_Poll(void)
 {
-	struct backend *be;
+	struct backend *be, *be2;
 	double now = VTIM_real();
 
 	ASSERT_CLI();
 	Lck_Lock(&backends_mtx);
-	while (1) {
-		be = VTAILQ_FIRST(&cool_backends);
-		if (be == NULL)
-			break;
+	VTAILQ_FOREACH_SAFE(be, &cool_backends, list, be2) {
+		CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
 		if (be->cooled > now)
 			break;
 		if (be->n_conn > 0)
diff --git a/bin/varnishtest/tests.disabled/r02295.vtc b/bin/varnishtest/tests.disabled/r02295.vtc
new file mode 100644
index 0000000..f7a06e1
--- /dev/null
+++ b/bin/varnishtest/tests.disabled/r02295.vtc
@@ -0,0 +1,53 @@
+varnishtest "Test cooled dynamic backend clean up"
+
+# This test is disabled because it needs a timeout of 80 seconds (-t80 to
+# varnishtest). This is because the cooled backend timeout in varnish core
+# is hard coded to 60 seconds.
+
+server s1 {
+	rxreq
+	delay 70
+	txresp
+} -start
+
+varnish v1 -arg "-p cli_timeout=2 -p first_byte_timeout=80" -vcl {
+	import debug;
+
+	backend dummy { .host = "${bad_backend}"; }
+
+	sub vcl_init {
+		new s1 = debug.dyn("${s1_addr}", "${s1_port}");
+	}
+
+	sub vcl_recv {
+		if (req.url == "/refresh") {
+			s1.refresh("${s1_addr}", "${s1_port}");
+			return (synth(200, "OK"));
+		}
+	}
+
+	sub vcl_backend_fetch {
+		set bereq.backend = s1.backend();
+	}
+} -start
+
+client c1 {
+	timeout 120
+	txreq
+	rxresp
+	expect resp.status == 200
+} -start
+
+delay 1
+
+client c2 {
+	txreq -url /refresh
+	rxresp
+	expect resp.status == 200
+} -run
+
+delay 61
+
+varnish v1 -cliok "ping"
+
+client c1 -wait



More information about the varnish-commit mailing list