[master] 9ba9a8b Introduce beresp.backend.

Poul-Henning Kamp phk at FreeBSD.org
Tue Sep 23 17:32:18 CEST 2014


commit 9ba9a8bb1b40d0007e903ccfd948178fdf467176
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Sep 23 15:29:58 2014 +0000

    Introduce beresp.backend.
    
    Now bereq.backend is the backend or director we chose, whereas
    beresp.backend is the actual backend, after directors have done their
    picking and choosing, which sent us the reply.
    
    Constify the VCL_BACKEND datatype.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index a3b0cd7..92a4f71 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -511,7 +511,8 @@ struct busyobj {
 	struct acct_bereq	acct;
 
 	const char		*storage_hint;
-	struct director		*director;
+	const struct director	*director_req;
+	const struct director	*director_resp;
 	struct VCL_conf		*vcl;
 
 	struct vsl_log		vsl[1];
@@ -564,7 +565,7 @@ struct req {
 	uint16_t		err_code;
 	const char		*err_reason;
 
-	struct director		*director_hint;
+	const struct director	*director_hint;
 	struct VCL_conf		*vcl;
 
 	char			*ws_req;	/* WS above request data */
@@ -696,7 +697,8 @@ void VBE_DiscardHealth(const struct director *vdi);
 
 
 int VDI_GetHdr(struct worker *wrk, struct busyobj *bo);
-struct vbc *VDI_GetFd(struct busyobj *);
+struct vbc *VDI_GetFd(const struct director *d, struct worker *wrk,
+    struct busyobj *);
 int VDI_Healthy(const struct director *);
 void VDI_CloseFd(struct vbc **vbp, const struct acct_bereq *);
 void VDI_RecycleFd(struct vbc **vbp, const struct acct_bereq *);
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index ccd4cf4..4c00753 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -273,7 +273,7 @@ vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs)
 			/* XXX locking of stats */
 			VSC_C_main->backend_reuse += 1;
 			VSLb(bo->vsl, SLT_Backend, "%d %s %s",
-			    vc->fd, bo->director->vcl_name,
+			    vc->fd, bo->director_resp->vcl_name,
 			    bp->display_name);
 			vc->vdis = vs;
 			vc->recycled = 1;
@@ -312,7 +312,7 @@ vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs)
 	vc->backend = bp;
 	VSC_C_main->backend_conn++;
 	VSLb(bo->vsl, SLT_Backend, "%d %s %s",
-	    vc->fd, bo->director->vcl_name, bp->display_name);
+	    vc->fd, bo->director_resp->vcl_name, bp->display_name);
 	vc->vdis = vs;
 	return (vc);
 }
@@ -401,7 +401,7 @@ vdi_simple_gethdrs(const struct director *d, struct worker *wrk,
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
-	bo->vbc = VDI_GetFd(bo);
+	bo->vbc = VDI_GetFd(d, wrk, bo);
 	if (bo->vbc == NULL) {
 		VSLb(bo->vsl, SLT_FetchError, "no backend connection");
 		return (-1);
@@ -415,7 +415,7 @@ vdi_simple_gethdrs(const struct director *d, struct worker *wrk,
 	 */
 	if (i == 1) {
 		VSC_C_main->backend_retry++;
-		bo->vbc = VDI_GetFd(bo);
+		bo->vbc = VDI_GetFd(d, wrk, bo);
 		if (bo->vbc == NULL) {
 			VSLb(bo->vsl, SLT_FetchError, "no backend connection");
 			return (-1);
@@ -425,34 +425,6 @@ vdi_simple_gethdrs(const struct director *d, struct worker *wrk,
 	return (i);
 }
 
-/*--------------------------------------------------------------------
- */
-
-int
-VDI_GetHdr(struct worker *wrk, struct busyobj *bo)
-{
-
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-
-	if (bo->director == NULL) {
-		VSLb(bo->vsl, SLT_FetchError, "No backend");
-		return (-1);
-	}
-
-	CHECK_OBJ_NOTNULL(bo->director, DIRECTOR_MAGIC);
-	while (bo->director != NULL && bo->director->resolve != NULL)
-		bo->director = bo->director->resolve(bo->director, wrk, bo);
-
-	if (bo->director == NULL) {
-		VSLb(bo->vsl, SLT_FetchError, "Backend selection failed");
-		return (-1);
-	}
-
-	AN(bo->director->gethdrs);
-	return (bo->director->gethdrs(bo->director, wrk, bo));
-}
-
 /*--------------------------------------------------------------------*/
 
 void
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index 5fa79bd..36c31c0 100644
--- a/bin/varnishd/cache/cache_backend.h
+++ b/bin/varnishd/cache/cache_backend.h
@@ -77,7 +77,7 @@ struct vrt_backend_probe;
 
 typedef struct vbc *vdi_getfd_f(const struct director *, struct busyobj *);
 typedef unsigned vdi_healthy_f(const struct director *, double *changed);
-typedef struct director *vdi_resolve_f(const struct director *,
+typedef const struct director *vdi_resolve_f(const struct director *,
     struct worker *, struct busyobj *);
 typedef int vdi_gethdrs_f(const struct director *, struct worker *,
     struct busyobj *);
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index 5195688..9c47154 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -144,7 +144,7 @@ VBO_GetBusyObj(struct worker *wrk, const struct req *req)
 
 	bo->do_stream = 1;
 
-	bo->director = req->director_hint;
+	bo->director_req = req->director_hint;
 	bo->vcl = req->vcl;
 	VCL_Ref(bo->vcl);
 
diff --git a/bin/varnishd/cache/cache_dir.c b/bin/varnishd/cache/cache_dir.c
index 9687366..b8cc79c 100644
--- a/bin/varnishd/cache/cache_dir.c
+++ b/bin/varnishd/cache/cache_dir.c
@@ -90,17 +90,63 @@ VDI_RecycleFd(struct vbc **vbp, const struct acct_bereq *acct_bereq)
 	VBE_DropRefLocked(bp, acct_bereq);
 }
 
+/* Resolve director --------------------------------------------------*/
+
+static const struct director *
+vdi_resolve(struct worker *wrk, struct busyobj *bo, const struct director *d)
+{
+
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+
+	if (d == NULL) {
+		VSLb(bo->vsl, SLT_FetchError, "No backend");
+		return (NULL);
+	}
+
+	while (d != NULL && d->resolve != NULL) {
+		CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+		d = d->resolve(d, wrk, bo);
+	}
+	CHECK_OBJ_ORNULL(d, DIRECTOR_MAGIC);
+	if (d == NULL)
+		VSLb(bo->vsl, SLT_FetchError, "Backend selection failed");
+	bo->director_resp = d;
+	return (d);
+}
+
+/* Get a set of response headers -------------------------------------*/
+
+int
+VDI_GetHdr(struct worker *wrk, struct busyobj *bo)
+{
+
+	const struct director *d;
+
+	d = vdi_resolve(wrk, bo, bo->director_req);
+	if (d == NULL)
+		return (-1);
+
+	AN(d->gethdrs);
+	return (d->gethdrs(d, wrk, bo));
+}
+
 /* Get a connection --------------------------------------------------*/
 
 struct vbc *
-VDI_GetFd(struct busyobj *bo)
+VDI_GetFd(const struct director *d, struct worker *wrk, struct busyobj *bo)
 {
 	struct vbc *vc;
-	struct director *d;
 
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-	d = bo->director;
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+
+	d = vdi_resolve(wrk, bo, d);
+	if (d == NULL)
+		return (NULL);
+
+	AN(d->getfd);
 	vc = d->getfd(d, bo);
 	if (vc != NULL)
 		vc->vsl = bo->vsl;
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index bb58f1b..7884d5e 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -86,7 +86,6 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo)
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-	CHECK_OBJ_NOTNULL(bo->director, DIRECTOR_MAGIC);
 	CHECK_OBJ_NOTNULL(bo->vbc, VBC_MAGIC);
 	CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC);
 
diff --git a/bin/varnishd/cache/cache_pipe.c b/bin/varnishd/cache/cache_pipe.c
index 36ef425..71cf3e6 100644
--- a/bin/varnishd/cache/cache_pipe.c
+++ b/bin/varnishd/cache/cache_pipe.c
@@ -113,7 +113,7 @@ PipeRequest(struct req *req, struct busyobj *bo)
 	acct_pipe.req = req->acct.req_hdrbytes;
 	req->acct.req_hdrbytes = 0;
 
-	vc = VDI_GetFd(bo);
+	vc = VDI_GetFd(bo->director_req, wrk, bo);
 	if (vc == NULL) {
 		VSLb(bo->vsl, SLT_FetchError, "no backend connection");
 		pipecharge(req, &acct_pipe, NULL);
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 439ef46..78d1ea8 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -313,12 +313,12 @@ VRT_r_beresp_backend_name(const struct vrt_ctx *ctx)
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+	if (ctx->bo->director_resp != NULL)
+		return (ctx->bo->director_resp->vcl_name);
 	if (ctx->bo->vbc != NULL) {
 		CHECK_OBJ_NOTNULL(ctx->bo->vbc, VBC_MAGIC);
 		return (ctx->bo->vbc->backend->vcl_name);
 	}
-	if (ctx->bo->director != NULL)
-		return (ctx->bo->director->vcl_name);
 	return (NULL);
 }
 
@@ -390,29 +390,38 @@ VRT_r_req_##nm(const struct vrt_ctx *ctx)				\
 	return(ctx->req->elem);						\
 }
 
-REQ_VAR_L(backend_hint, director_hint, struct director *,)
-REQ_VAR_R(backend_hint, director_hint, struct director *)
+REQ_VAR_L(backend_hint, director_hint, const struct director *,)
+REQ_VAR_R(backend_hint, director_hint, const struct director *)
 REQ_VAR_L(ttl, d_ttl, double, if (!(arg>0.0)) arg = 0;)
 REQ_VAR_R(ttl, d_ttl, double)
 
 /*--------------------------------------------------------------------*/
 
 void
-VRT_l_bereq_backend(const struct vrt_ctx *ctx, struct director *be)
+VRT_l_bereq_backend(const struct vrt_ctx *ctx, const struct director *be)
 {
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
-	ctx->bo->director = be;
+	ctx->bo->director_req = be;
 }
 
-struct director *
+const struct director *
 VRT_r_bereq_backend(const struct vrt_ctx *ctx)
 {
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
-	return (ctx->bo->director);
+	return (ctx->bo->director_req);
+}
+
+const struct director *
+VRT_r_beresp_backend(const struct vrt_ctx *ctx)
+{
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+	return (ctx->bo->director_resp);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishtest/tests/m00009.vtc b/bin/varnishtest/tests/m00009.vtc
index 7fbeec1..01b3e0a 100644
--- a/bin/varnishtest/tests/m00009.vtc
+++ b/bin/varnishtest/tests/m00009.vtc
@@ -37,6 +37,9 @@ varnish v1 -vcl+backend {
 	sub vcl_backend_fetch {
 		set bereq.backend = rr.backend();
 	}
+	sub vcl_backend_response {
+		set beresp.http.where = bereq.backend + "-->" + beresp.backend;
+	}
 } -start
 
 client c1 {
diff --git a/bin/varnishtest/tests/v00007.vtc b/bin/varnishtest/tests/v00007.vtc
index 196f92e..7f9507f 100644
--- a/bin/varnishtest/tests/v00007.vtc
+++ b/bin/varnishtest/tests/v00007.vtc
@@ -19,12 +19,16 @@ varnish v1 -vcl+backend {
 	sub vcl_backend_fetch {
 		set bereq.backend = foo.backend();
 	}
+	sub vcl_backend_response {
+		set beresp.http.where = bereq.backend + "-->" + beresp.backend;
+	}
 } -start
 
 client c1 {
-	timeout 10
 	txreq -url "/foo"
 	rxresp
+	expect resp.http.where == "foo-->s1"
 	txreq -url "/bar"
 	rxresp
+	expect resp.http.where == "foo-->s1"
 } -run
diff --git a/bin/varnishtest/tests/v00026.vtc b/bin/varnishtest/tests/v00026.vtc
index 2b52238..11475dc 100644
--- a/bin/varnishtest/tests/v00026.vtc
+++ b/bin/varnishtest/tests/v00026.vtc
@@ -42,6 +42,9 @@ varnish v1 -vcl+backend {
 			set bereq.backend = h1.backend(bereq.url);
 		}
 	}
+	sub vcl_backend_response {
+		set beresp.http.where = bereq.backend + "-->" + beresp.backend;
+	}
 
 } -start
 
diff --git a/include/vrt.h b/include/vrt.h
index 1bb0b66..e8c322c 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -62,7 +62,7 @@ struct suckaddr;
  * (alphabetic order)
  */
 
-typedef struct director *		VCL_BACKEND;
+typedef const struct director *		VCL_BACKEND;
 typedef const struct vmod_priv *	VCL_BLOB;
 typedef unsigned			VCL_BOOL;
 typedef double				VCL_BYTES;
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index 4fffa57..2bf7133 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -326,6 +326,7 @@ sp_variables = [
 		'BACKEND',
 		( 'pipe', 'backend', ),
 		( 'pipe', 'backend', ), """
+		This is the backend or director we attempt to fetch from.
 		"""
 	),
 	('bereq.method',
@@ -490,6 +491,15 @@ sp_variables = [
 		( 'backend_response', 'backend_error'), """
 		"""
 	),
+	('beresp.backend',
+		'BACKEND',
+		( 'backend_response', 'backend_error'),
+		( ), """
+		This is the backend we fetched from.  If bereq.backend
+		was set to a director, this will be the backend selected
+		by the director.
+		"""
+	),
 	('beresp.backend.name',
 		'STRING',
 		( 'backend_response', 'backend_error'),
diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c
index 272864e..a721617 100644
--- a/lib/libvmod_directors/fall_back.c
+++ b/lib/libvmod_directors/fall_back.c
@@ -53,7 +53,7 @@ vmod_fallback_healthy(const struct director *dir, double *changed)
 	return (vdir_any_healthy(rr->vd, changed));
 }
 
-static struct director * __match_proto__(vdi_resolve_f)
+static const struct director * __match_proto__(vdi_resolve_f)
 vmod_fallback_resolve(const struct director *dir, struct worker *wrk,
     struct busyobj *bo)
 {
diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c
index a7e26d8..0e7c0a4 100644
--- a/lib/libvmod_directors/random.c
+++ b/lib/libvmod_directors/random.c
@@ -58,7 +58,7 @@ vmod_random_healthy(const struct director *dir, double *changed)
 	return (vdir_any_healthy(rr->vd, changed));
 }
 
-static struct director * __match_proto__(vdi_resolve_f)
+static const struct director * __match_proto__(vdi_resolve_f)
 vmod_random_resolve(const struct director *dir, struct worker *wrk,
     struct busyobj *bo)
 {
diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c
index 581eef3..a8fba65 100644
--- a/lib/libvmod_directors/round_robin.c
+++ b/lib/libvmod_directors/round_robin.c
@@ -54,7 +54,7 @@ vmod_rr_healthy(const struct director *dir, double *changed)
 	return (vdir_any_healthy(rr->vd, changed));
 }
 
-static struct director * __match_proto__(vdi_resolve_f)
+static const struct director * __match_proto__(vdi_resolve_f)
 vmod_rr_resolve(const struct director *dir, struct worker *wrk,
     struct busyobj *bo)
 {



More information about the varnish-commit mailing list