[master] bed0195 Make vcl_backend_fetch{ return(abandon); } work.

Poul-Henning Kamp phk at varnish-cache.org
Wed Jun 19 12:10:47 CEST 2013


commit bed0195729eed00b6ed964978c7a3317257d1db8
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Jun 19 10:10:22 2013 +0000

    Make vcl_backend_fetch{ return(abandon); } work.

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 875ddb6..b51cabb 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -38,12 +38,22 @@
 
 #include "hash/hash_slinger.h"
 
-#include "cache_backend.h"
-#include "vcli_priv.h"
 #include "vcl.h"
 #include "vtim.h"
 
 /*--------------------------------------------------------------------
+ */
+
+static void
+vbf_release_req(struct req ***reqpp)
+{
+	if (*reqpp != NULL) {
+		**reqpp = NULL;
+		*reqpp = NULL;
+	}
+}
+
+/*--------------------------------------------------------------------
  * Copy req->bereq and run it by VCL::vcl_backend_fetch{}
  */
 
@@ -86,19 +96,22 @@ vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo, const struct req *req)
 	http_PrintfHeader(bo->bereq,
 	    "X-Varnish: %u", bo->vsl->wid & VSL_IDENTMASK);
 	/* XXX: Missing ABANDON */
+	if (wrk->handling == VCL_RET_ABANDON) {
+		return (F_STP_ABANDON);
+	}
 	return (F_STP_FETCHHDR);
 }
+
 /*--------------------------------------------------------------------
  */
 
 static enum fetch_step
-vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo, struct req **reqp)
+vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo, struct req ***reqpp)
 {
 	int i;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
-	AN(reqp);
-	CHECK_OBJ_NOTNULL((*reqp), REQ_MAGIC);
+	AN(reqpp);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
 	xxxassert (wrk->handling == VCL_RET_FETCH);
@@ -106,9 +119,9 @@ vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo, struct req **reqp)
 	HTTP_Setup(bo->beresp, bo->ws, bo->vsl, HTTP_Beresp);
 
 	if (!bo->do_pass)
-		*reqp = NULL;
+		vbf_release_req(reqpp);
 
-	i = V1F_fetch_hdr(wrk, bo, *reqp);
+	i = V1F_fetch_hdr(wrk, bo, *reqpp ? **reqpp : NULL);
 	/*
 	 * If we recycle a backend connection, there is a finite chance
 	 * that the backend closed it before we get a request to it.
@@ -116,11 +129,11 @@ vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo, struct req **reqp)
 	 */
 	if (i == 1) {
 		VSC_C_main->backend_retry++;
-		i = V1F_fetch_hdr(wrk, bo, *reqp);
+		i = V1F_fetch_hdr(wrk, bo, *reqpp ? **reqpp : NULL);
 	}
 
 	if (bo->do_pass)
-		*reqp = NULL;
+		vbf_release_req(reqpp);
 
 	if (i) {
 		AZ(bo->vbc);
@@ -251,6 +264,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
 	assert(wrk->handling == VCL_RET_DELIVER);
+
 #if 0
 	if (wrk->handling != VCL_RET_DELIVER)
 		VDI_CloseFd(&bo->vbc);
@@ -416,13 +430,15 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
  */
 
 static enum fetch_step
-vbf_stp_abandon(struct worker *wrk, struct busyobj *bo)
+vbf_stp_abandon(struct worker *wrk, struct busyobj *bo, struct req ***reqp)
 {
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	AN(reqp);
 
 	bo->state = BOS_FAILED;
 	VBO_DerefBusyObj(wrk, &bo);	// XXX ?
+	vbf_release_req(reqp);
 	return (F_STP_DONE);
 }
 
@@ -435,6 +451,9 @@ vbf_stp_notyet(void)
 	WRONG("Patience, grashopper, patience...");
 }
 
+/*--------------------------------------------------------------------
+ */
+
 static enum fetch_step
 vbf_stp_done(void)
 {
@@ -451,6 +470,21 @@ struct vbf_secret_handshake {
 	struct req		**reqp;
 };
 
+static const char *
+vbf_step_name(enum fetch_step stp)
+{
+	switch (stp) {
+#define FETCH_STEP(l, U, arg)						\
+		case F_STP_##U:						\
+			return (#U);
+#include "tbl/steps.h"
+#undef FETCH_STEP
+	default:
+		return ("F-step ?");
+	}
+}
+
+
 static void
 vbf_fetch_thread(struct worker *wrk, void *priv)
 {
@@ -473,6 +507,8 @@ vbf_fetch_thread(struct worker *wrk, void *priv)
 #define FETCH_STEP(l, U, arg)						\
 		case F_STP_##U:						\
 			bo->step = vbf_stp_##l arg;			\
+			VSLb(bo->vsl, SLT_Debug,			\
+			    "%s -> %s", #l, vbf_step_name(bo->step));	\
 			break;
 #include "tbl/steps.h"
 #undef FETCH_STEP
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index 0e808b3..a6ed005 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -409,6 +409,7 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
 		else
 			VDI_RecycleFd(&bo->vbc);
 	}
+	AZ(bo->vbc);
 
 	if (bo->state == BOS_FAILED) {
 		wrk->stats.fetch_failed++;
diff --git a/bin/varnishtest/tests/b00038.vtc b/bin/varnishtest/tests/b00038.vtc
new file mode 100644
index 0000000..963dc48
--- /dev/null
+++ b/bin/varnishtest/tests/b00038.vtc
@@ -0,0 +1,18 @@
+varnishtest "vcl_backend_fetch abandon"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_backend_fetch {
+		return (abandon);
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 503
+} -run
diff --git a/include/tbl/steps.h b/include/tbl/steps.h
index 5f9b3b2..b0589ff 100644
--- a/include/tbl/steps.h
+++ b/include/tbl/steps.h
@@ -51,9 +51,9 @@ REQ_STEP(error,		ERROR,		(wrk, req))
 
 #ifdef FETCH_STEP
 FETCH_STEP(mkbereq,	MKBEREQ,	(wrk, bo, *reqp))
-FETCH_STEP(fetchhdr,	FETCHHDR,	(wrk, bo, reqp))
+FETCH_STEP(fetchhdr,	FETCHHDR,	(wrk, bo, &reqp))
 FETCH_STEP(fetch,	FETCH,		(wrk, bo))
-FETCH_STEP(abandon,	ABANDON,	(wrk, bo))
+FETCH_STEP(abandon,	ABANDON,	(wrk, bo, &reqp))
 FETCH_STEP(notyet,	NOTYET,		())
 FETCH_STEP(done,	DONE,		())
 #endif
diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py
index c4a8a49..fd2573d 100755
--- a/lib/libvcl/generate.py
+++ b/lib/libvcl/generate.py
@@ -85,7 +85,7 @@ returns =(
 	('purge',		"C", ('error', 'fetch',)),
 	('miss',		"C", ('error', 'restart', 'pass', 'fetch',)),
 	('lookup',		"C", ('error', 'restart', 'pass', 'deliver',)),
-	('backend_fetch',	"B", ('fetch', 'error')),
+	('backend_fetch',	"B", ('fetch', 'abandon')),
 	('backend_response',	"B", ('deliver', 'restart', 'error')),
 	('deliver',		"C", ('restart', 'deliver',)),
 	('error',		"C", ('restart', 'deliver',)),



More information about the varnish-commit mailing list