[PATCH] Make random/hash director exhaust the backend list when looking for healthy backend.

Martin Blix Grydeland martin at varnish-software.com
Fri Aug 29 14:48:30 CEST 2014


Fixes: #1575
---
 bin/varnishtest/tests/r01575.vtc | 56 ++++++++++++++++++++++++++++++++++++++++
 lib/libvmod_directors/hash.c     |  6 ++---
 lib/libvmod_directors/random.c   |  6 ++---
 lib/libvmod_directors/vdir.c     |  2 +-
 4 files changed, 63 insertions(+), 7 deletions(-)
 create mode 100644 bin/varnishtest/tests/r01575.vtc

diff --git a/bin/varnishtest/tests/r01575.vtc b/bin/varnishtest/tests/r01575.vtc
new file mode 100644
index 0000000..11c82c1
--- /dev/null
+++ b/bin/varnishtest/tests/r01575.vtc
@@ -0,0 +1,56 @@
+varnishtest "#1575 - random director exhaust backend list"
+
+# Add 5 backends to a random director, with the 5th having very low weight.
+# Mark the first 4 sick, and make sure that the 5th will be selected.
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+server s2 {
+	rxreq
+	txresp
+} -start
+
+server s3 {
+	rxreq
+	txresp
+} -start
+
+server s4 {
+	rxreq
+	txresp
+} -start
+
+server s5 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	import ${vmod_directors};
+	sub vcl_init {
+		new rd = directors.random();
+		rd.add_backend(s1, 10000);
+		rd.add_backend(s2, 10000);
+		rd.add_backend(s3, 10000);
+		rd.add_backend(s4, 10000);
+		rd.add_backend(s5, 1);
+	}
+
+	sub vcl_backend_fetch {
+		set bereq.backend = rd.backend();
+	}
+} -start
+
+varnish v1 -cliok "backend.set_health s1 sick"
+varnish v1 -cliok "backend.set_health s2 sick"
+varnish v1 -cliok "backend.set_health s3 sick"
+varnish v1 -cliok "backend.set_health s4 sick"
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+} -run
diff --git a/lib/libvmod_directors/hash.c b/lib/libvmod_directors/hash.c
index afef7ed..090039f 100644
--- a/lib/libvmod_directors/hash.c
+++ b/lib/libvmod_directors/hash.c
@@ -47,7 +47,7 @@ struct vmod_directors_hash {
 	unsigned				magic;
 #define VMOD_DIRECTORS_HASH_MAGIC		0xc08dd611
 	struct vdir				*vd;
-	unsigned				nloops;
+	unsigned				n_backend;
 	struct vbitmap				*vbm;
 };
 
@@ -64,7 +64,6 @@ vmod_hash__init(const struct vrt_ctx *ctx, struct vmod_directors_hash **rrp,
 	AN(rr);
 	rr->vbm = vbit_init(8);
 	AN(rr->vbm);
-	rr->nloops = 3; //
 	*rrp = rr;
 	vdir_new(&rr->vd, vcl_name, NULL, NULL, rr);
 }
@@ -90,6 +89,7 @@ vmod_hash_add_backend(const struct vrt_ctx *ctx,
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
 	(void)vdir_add_backend(rr->vd, be, w);
+	rr->n_backend++;
 }
 
 VCL_BACKEND __match_proto__()
@@ -120,6 +120,6 @@ vmod_hash_backend(const struct vrt_ctx *ctx, struct vmod_directors_hash *rr,
 	r = vbe32dec(sha256);
 	r = scalbn(r, -32);
 	assert(r >= 0 && r <= 1.0);
-	be = vdir_pick_be(rr->vd, r, rr->nloops);
+	be = vdir_pick_be(rr->vd, r, rr->n_backend);
 	return (be);
 }
diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c
index 22f0bb9..8ae36a7 100644
--- a/lib/libvmod_directors/random.c
+++ b/lib/libvmod_directors/random.c
@@ -45,7 +45,7 @@ struct vmod_directors_random {
 	unsigned				magic;
 #define VMOD_DIRECTORS_RANDOM_MAGIC		0x4732d092
 	struct vdir				*vd;
-	unsigned				nloops;
+	unsigned				n_backend;
 	struct vbitmap				*vbm;
 };
 
@@ -68,7 +68,7 @@ vmod_rr_getfd(const struct director *dir, struct busyobj *bo)
 	CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC);
 	r = scalbn(random(), -31);
 	assert(r >= 0 && r < 1.0);
-	be = vdir_pick_be(rr->vd, r, rr->nloops);
+	be = vdir_pick_be(rr->vd, r, rr->n_backend);
 	if (be == NULL)
 		return (NULL);
 	return (be->getfd(be, bo));
@@ -87,7 +87,6 @@ vmod_random__init(const struct vrt_ctx *ctx, struct vmod_directors_random **rrp,
 	AN(rr);
 	rr->vbm = vbit_init(8);
 	AN(rr->vbm);
-	rr->nloops = 3; //
 	*rrp = rr;
 	vdir_new(&rr->vd, vcl_name, vmod_rr_healthy, vmod_rr_getfd, rr);
 }
@@ -113,6 +112,7 @@ vmod_random_add_backend(const struct vrt_ctx *ctx,
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
 	(void)vdir_add_backend(rr->vd, be, w);
+	rr->n_backend++;
 }
 
 VCL_BACKEND __match_proto__()
diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c
index 12268eb..aae7a14 100644
--- a/lib/libvmod_directors/vdir.c
+++ b/lib/libvmod_directors/vdir.c
@@ -186,7 +186,7 @@ vdir_pick_be(struct vdir *vd, double w, unsigned nloops)
 	nbe = vd->n_backend;
 	assert(w >= 0.0 && w < 1.0);
 	vdir_lock(vd);
-	for (l = 0; nbe > 0 && tw > 0.0 && l <nloops; l++) {
+	for (l = 0; nbe > 0 && tw > 0.0 && l < nloops; l++) {
 		u = vdir_pick_by_weight(vd, w * tw, vbm);
 		be = vd->backend[u];
 		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
-- 
2.1.0.rc1




More information about the varnish-dev mailing list