[PATCH 1/2] Add a ban_max runtime parameter.

Martin Blix Grydeland martin at varnish-software.com
Fri Feb 15 15:37:25 CET 2013


This parameter controls the maximum ban list length we aim for. When
the ban list grows beyond this limit, we allow the ban lurker to force
evict the objects hanging on the last bans to get below the limit.
---
 bin/varnishd/cache/cache_ban.c   |   31 +++++++++++++++++++++----------
 bin/varnishd/common/params.h     |    3 +++
 bin/varnishd/mgt/mgt_param_tbl.c |    6 ++++++
 bin/varnishtest/tests/b00036.vtc |   34 ++++++++++++++++++++++++++++++++++
 include/tbl/vsc_f_main.h         |    5 +++++
 5 files changed, 69 insertions(+), 10 deletions(-)
 create mode 100644 bin/varnishtest/tests/b00036.vtc

diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c
index 2e1488f..79eb9cf 100644
--- a/bin/varnishd/cache/cache_ban.c
+++ b/bin/varnishd/cache/cache_ban.c
@@ -833,7 +833,7 @@ ban_evaluate(const uint8_t *bs, const struct http *objhttp,
 
 static int
 ban_check_object(struct object *o, struct vsl_log *vsl,
-    const struct http *req_http)
+    const struct http *req_http, int force)
 {
 	struct ban *b;
 	struct objcore *oc;
@@ -861,6 +861,8 @@ ban_check_object(struct object *o, struct vsl_log *vsl,
 	skipped = 0;
 	for (b = b0; b != oc->ban; b = VTAILQ_NEXT(b, list)) {
 		CHECK_OBJ_NOTNULL(b, BAN_MAGIC);
+		if (force)
+			break;
 		if (b->flags & BAN_F_GONE)
 			continue;
 		if ((b->flags & BAN_F_LURK) &&
@@ -880,7 +882,10 @@ ban_check_object(struct object *o, struct vsl_log *vsl,
 	}
 
 	Lck_Lock(&ban_mtx);
-	VSC_C_main->bans_tested++;
+	if (force)
+		VSC_C_main->bans_forced++;
+	else
+		VSC_C_main->bans_tested++;
 	VSC_C_main->bans_tests_tested += tests;
 
 	if (b == oc->ban && skipped > 0) {
@@ -922,7 +927,7 @@ int
 BAN_CheckObject(struct object *o, struct req *req)
 {
 
-	return (ban_check_object(o, req->vsl, req->http) > 0);
+	return (ban_check_object(o, req->vsl, req->http, 0) > 0);
 }
 
 static void
@@ -958,7 +963,7 @@ ban_cleantail(void)
  */
 
 static int
-ban_lurker_work(struct worker *wrk, struct vsl_log *vsl)
+ban_lurker_work(struct worker *wrk, struct vsl_log *vsl, int force)
 {
 	struct ban *b, *b0;
 	struct objhead *oh;
@@ -1057,10 +1062,10 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl)
 			 * Get the object and check it against all relevant bans
 			 */
 			o = oc_getobj(&wrk->stats, oc);
-			i = ban_check_object(o, vsl, NULL);
+			i = ban_check_object(o, vsl, NULL, force);
 			if (DO_DEBUG(DBG_LURKER))
-				VSLb(vsl, SLT_Debug, "lurker got: %p %d",
-				    oc, i);
+				VSLb(vsl, SLT_Debug, "lurker got: %p %d %d",
+				    oc, force, i);
 			if (i == -1) {
 				/* Not banned, not moved */
 				oc->flags |= pass;
@@ -1076,6 +1081,8 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl)
 			(void)HSH_Deref(&wrk->stats, NULL, &o);
 			VTIM_sleep(cache_param->ban_lurker_sleep);
 		}
+		if (force > 0)
+			force--;
 		Lck_AssertHeld(&ban_mtx);
 		if (!(b->flags & BAN_F_REQ)) {
 			if (!(b->flags & BAN_F_GONE))
@@ -1104,19 +1111,23 @@ ban_lurker(struct worker *wrk, void *priv)
 	struct vsl_log vsl;
 	volatile double d;
 	int i = 0, n = 0;
+	int force;
 
 	VSL_Setup(&vsl, NULL, 0);
 
 	(void)priv;
 	while (!ban_shutdown) {
 		d = cache_param->ban_lurker_sleep;
-		if (d > 0.0) {
-			i = ban_lurker_work(wrk, &vsl);
+		force = VSC_C_main->bans - cache_param->ban_max;
+		if (force < 0)
+			force = 0;
+		if (d > 0.0 || force) {
+			i = ban_lurker_work(wrk, &vsl, force);
 			VSL_Flush(&vsl, 0);
 			WRK_SumStat(wrk);
 			if (i && !ban_shutdown) {
 				VTIM_sleep(d);
-				if (++n > 10) {
+				if (++n > 10 || force) {
 					ban_cleantail();
 					n = 0;
 				}
diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h
index ebeff0f..714a44e 100644
--- a/bin/varnishd/common/params.h
+++ b/bin/varnishd/common/params.h
@@ -185,6 +185,9 @@ struct params {
 	/* How long time does the ban lurker sleep */
 	double			ban_lurker_sleep;
 
+	/* Max ban list length */
+	unsigned		ban_max;
+
 	/* Max size of the saintmode list. 0 == no saint mode. */
 	unsigned		saintmode_threshold;
 
diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c
index b92c71b..e8e491d 100644
--- a/bin/varnishd/mgt/mgt_param_tbl.c
+++ b/bin/varnishd/mgt/mgt_param_tbl.c
@@ -446,6 +446,12 @@ const struct parspec mgt_parspec[] = {
 		"A value of zero disables the ban lurker.",
 		0,
 		"0.01", "s" },
+	{ "ban_max", tweak_uint, &mgt_param.ban_max, 1, UINT_MAX,
+		"The maximum number of bans allowed on the ban list before "
+		"the ban lurker starts to force evict the objects on the last "
+		"ban.",
+		EXPERIMENTAL,
+		"5000", "bans" },
 	{ "saintmode_threshold", tweak_uint,
 		&mgt_param.saintmode_threshold, 0, UINT_MAX,
 		"The maximum number of objects held off by saint mode before "
diff --git a/bin/varnishtest/tests/b00036.vtc b/bin/varnishtest/tests/b00036.vtc
new file mode 100644
index 0000000..8cb3157
--- /dev/null
+++ b/bin/varnishtest/tests/b00036.vtc
@@ -0,0 +1,34 @@
+varnishtest "Test force evicting of bans"
+
+server s1 {
+	rxreq
+	txresp -hdr "x-foo: first"
+	rxreq
+	txresp -hdr "x-foo: second"
+} -start
+
+varnish v1 -arg "-p ban_max=1 -p ban_lurker_sleep=0" -vcl+backend {
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+	expect resp.http.x-foo == "first"
+} -run
+
+varnish v1 -expect bans == 1
+
+varnish v1 -cliok "ban obj.http.x-bar == non-existant"
+
+delay 2
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+	expect resp.http.x-foo == "second"
+} -run
+
+varnish v1 -expect bans == 1
+varnish v1 -expect bans_forced == 1
diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h
index f487471..4d246d4 100644
--- a/include/tbl/vsc_f_main.h
+++ b/include/tbl/vsc_f_main.h
@@ -501,6 +501,11 @@ VSC_F(bans_tests_tested,	uint64_t, 0, 'c',
 	" each other.  'ban req.url == foo && req.http.host == bar'"
 	" counts as one in 'bans_tested' and as two in 'bans_tests_tested'"
 )
+VSC_F(bans_forced,		uint64_t, 0, 'c',
+    "Bans forced upon objects",
+	"Count of how many bans were forced upon objects to meet ban list"
+	" limits."
+)
 VSC_F(bans_dups,		uint64_t, 0, 'c',
     "Bans superseded by other bans",
 	"Count of bans replaced by later identical bans."
-- 
1.7.10.4




More information about the varnish-dev mailing list