r4514 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Mon Feb 1 09:29:16 CET 2010


Author: phk
Date: 2010-02-01 09:29:16 +0100 (Mon, 01 Feb 2010)
New Revision: 4514

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_backend.c
   trunk/varnish-cache/bin/varnishd/cache_backend.h
   trunk/varnish-cache/bin/varnishd/cache_dir_random.c
   trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c
   trunk/varnish-cache/bin/varnishd/cache_hash.c
   trunk/varnish-cache/bin/varnishd/cache_vrt.c
Log:
Make the trouble-list hold a uintptr_t of the objhead, instead of the
actual objhead, to make it painfully obvious, that no dereference is
allowed.

Various strokes with the polishing cloth along the way.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2010-02-01 08:29:16 UTC (rev 4514)
@@ -456,7 +456,8 @@
 /* cache_backend.c */
 
 struct vbe_conn *VBE_GetFd(const struct director *, struct sess *sp);
-int VBE_Healthy(const struct director *, const struct sess *sp);
+int VBE_Healthy(double now, const struct director *, uintptr_t target);
+int VBE_Healthy_sp(const struct sess *sp, const struct director *);
 void VBE_ClosedFd(struct sess *sp);
 void VBE_RecycleFd(struct sess *sp);
 void VBE_AddHostHeader(const struct sess *sp);

Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend.c	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache_backend.c	2010-02-01 08:29:16 UTC (rev 4514)
@@ -243,18 +243,18 @@
  */
 
 static unsigned int
-vbe_Healthy(const struct sess *sp, struct backend *backend)
+vbe_Healthy(double now, uintptr_t target, struct backend *backend)
 {
 	struct trouble *tr;
 	struct trouble *tr2;
-	struct trouble *old = NULL;
-	unsigned i = 0;
+	struct trouble *old;
+	unsigned i = 0, retval;
 	unsigned int threshold;
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+
 	CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC);
 
 	if (!backend->healthy)
-		return 0;
+		return (0);
 
 	/* VRT/VCC sets threshold to UINT_MAX to mark that it's not
 	 * specified by VCL (thus use param).
@@ -266,43 +266,47 @@
 
 	/* Saintmode is disabled */
 	if (threshold == 0)
-		return 1;
+		return (1);
 
 	/* No need to test if we don't have an object head to test against.
 	 * FIXME: Should check the magic too, but probably not assert?
 	 */
-	if (!sp->objhead)
-		return 1;
+	if (target == 0)
+		return (1);
 
+	old = NULL;
+	retval = 1;
 	Lck_Lock(&backend->mtx);
 	VTAILQ_FOREACH_SAFE(tr, &backend->troublelist, list, tr2) {
 		CHECK_OBJ_NOTNULL(tr, TROUBLE_MAGIC);
-		if (tr->timeout < sp->t_req) {
+
+		if (tr->timeout < now) {
 			VTAILQ_REMOVE(&backend->troublelist, tr, list);
 			old = tr;
+			retval = 1;
 			break;
 		}
 
-		if (tr->objhead == sp->objhead) {
-			Lck_Unlock(&backend->mtx);
-			return 0;
+		if (tr->target == target) {
+			retval = 0;
+			break;
 		}
 
 		/* If the threshold is at 1, a single entry on the list
 		 * will disable the backend. Since 0 is disable, ++i
 		 * instead of i++ to allow this behavior.
 		 */
-		if (++i >=threshold) {
-			Lck_Unlock(&backend->mtx);
-			return 0;
+		if (++i >= threshold) {
+			retval = 0;
+			break;
 		}
 	}
 	Lck_Unlock(&backend->mtx);
 
-	if (old)
+	if (old != NULL)
 		FREE_OBJ(old);
 
-	return 1;
+	return (retval);
 }
 
 /*--------------------------------------------------------------------
@@ -342,7 +346,7 @@
 		VBE_ClosedFd(sp);
 	}
 
-	if (!vbe_Healthy(sp, bp)) {
+	if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, bp)) {
 		VSL_stats->backend_unhealthy++;
 		return (NULL);
 	}
@@ -423,19 +427,30 @@
 	return (d->getfd(d, sp));
 }
 
-/* Check health ------------------------------------------------------*/
+/* Check health ------------------------------------------------------
+ *
+ * The target is really an objhead pointer, but since it can not be
+ * dereferenced during health-checks, we pass it as uintptr_t, which
+ * hopefully will make people investigate, before mucking about with it.
+ */
 
 int
-VBE_Healthy(const struct director *d, const struct sess *sp)
+VBE_Healthy_sp(const struct sess *sp, const struct director *d)
 {
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-	if (d == NULL)
-		d = sp->director;
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
-	return (d->healthy(d, sp));
+	return (d->healthy(sp->t_req, d, (uintptr_t)sp->objhead));
 }
 
+int
+VBE_Healthy(double now, const struct director *d, uintptr_t target)
+{
+
+	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+	return (d->healthy(now, d, target));
+}
+
 /*--------------------------------------------------------------------
  * The "simple" director really isn't, since thats where all the actual
  * connections happen.  Nontheless, pretend it is simple by sequestering
@@ -469,14 +484,13 @@
 }
 
 static unsigned
-vdi_simple_healthy(const struct director *d, const struct sess *sp)
+vdi_simple_healthy(double now, const struct director *d, uintptr_t target)
 {
 	struct vdi_simple *vs;
 
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
-	return (vbe_Healthy(sp, vs->backend));
+	return (vbe_Healthy(now, target, vs->backend));
 }
 
 /*lint -e{818} not const-able */

Modified: trunk/varnish-cache/bin/varnishd/cache_backend.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend.h	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache_backend.h	2010-02-01 08:29:16 UTC (rev 4514)
@@ -79,7 +79,8 @@
 
 typedef struct vbe_conn *vdi_getfd_f(const struct director *, struct sess *sp);
 typedef void vdi_fini_f(struct director *);
-typedef unsigned vdi_healthy(const struct director *, const struct sess *sp);
+typedef unsigned vdi_healthy(double now, const struct director *,
+    uintptr_t target);
 
 struct director {
 	unsigned		magic;
@@ -99,7 +100,7 @@
 struct trouble {
 	unsigned		magic;
 #define TROUBLE_MAGIC		0x4211ab21
-	void			*objhead; /* NB: only comparison */
+	uintptr_t		target;
 	double			timeout;
 	VTAILQ_ENTRY(trouble)	list;
 };

Modified: trunk/varnish-cache/bin/varnishd/cache_dir_random.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_dir_random.c	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache_dir_random.c	2010-02-01 08:29:16 UTC (rev 4514)
@@ -137,7 +137,7 @@
 			if (r >= s1)
 				continue;
 			d2 = vs->hosts[i].backend;
-			if (!VBE_Healthy(d2, sp))
+			if (!VBE_Healthy_sp(sp, d2))
 				break;
 			vbe = VBE_GetFd(d2, sp);
 			if (vbe != NULL)
@@ -152,7 +152,7 @@
 		for (i = 0; i < vs->nhosts; i++) {
 			d2 = vs->hosts[i].backend;
 			/* XXX: cache result of healty to avoid double work */
-			if (VBE_Healthy(d2, sp))
+			if (VBE_Healthy_sp(sp, d2))
 				s1 += vs->hosts[i].weight;
 		}
 
@@ -171,7 +171,7 @@
 		s1 = 0.0;
 		for (i = 0; i < vs->nhosts; i++)  {
 			d2 = vs->hosts[i].backend;
-			if (!VBE_Healthy(d2, sp))
+			if (!VBE_Healthy_sp(sp, d2))
 				continue;
 			s1 += vs->hosts[i].weight;
 			if (r >= s1)
@@ -187,17 +187,16 @@
 }
 
 static unsigned
-vdi_random_healthy(const struct director *d, const struct sess *sp)
+vdi_random_healthy(double now, const struct director *d, uintptr_t target)
 {
 	struct vdi_random *vs;
 	int i;
 
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CAST_OBJ_NOTNULL(vs, d->priv, VDI_RANDOM_MAGIC);
 
 	for (i = 0; i < vs->nhosts; i++) {
-		if (VBE_Healthy(vs->hosts[i].backend, sp))
+		if (VBE_Healthy(now, vs->hosts[i].backend, target))
 			return 1;
 	}
 	return 0;

Modified: trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c	2010-02-01 08:29:16 UTC (rev 4514)
@@ -75,7 +75,7 @@
 	for (i = 0; i < vs->nhosts; i++) {
 		backend = vs->hosts[vs->next_host].backend;
 		vs->next_host = (vs->next_host + 1) % vs->nhosts;
-		if (!VBE_Healthy(backend, sp))
+		if (!VBE_Healthy_sp(sp, backend))
 			continue;
 		vbe = VBE_GetFd(backend, sp);
 		if (vbe != NULL)
@@ -86,19 +86,18 @@
 }
 
 static unsigned
-vdi_round_robin_healthy(const struct director *d, const struct sess *sp)
+vdi_round_robin_healthy(double now, const struct director *d, uintptr_t target)
 {
 	struct vdi_round_robin *vs;
 	struct director *backend;
 	int i;
 
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CAST_OBJ_NOTNULL(vs, d->priv, VDI_ROUND_ROBIN_MAGIC);
 
 	for (i = 0; i < vs->nhosts; i++) {
 		backend = vs->hosts[i].backend;
-		if (VBE_Healthy(backend, sp))
+		if (VBE_Healthy(now, backend, target))
 			return 1;
 	}
 	return 0;

Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2010-02-01 08:29:16 UTC (rev 4514)
@@ -187,7 +187,7 @@
 		WSP(sp, SLT_Hash, "%s", str);
 }
 
-/**********************************************************************
+/*---------------------------------------------------------------------
  * This is a debugging hack to enable testing of boundary conditions
  * in the hash algorithm.
  * We trap the first 9 different digests and translate them to different
@@ -394,15 +394,16 @@
 	 * mode'. Is this entirely wrong, or just ugly? Why isn't objhead
 	 * set here? FIXME:Grace.
 	 */
-	sp->objhead = oh;
-	if (oc == NULL && grace_oc != NULL &&
-	    (busy_oc != NULL || !VBE_Healthy(NULL, sp))) {
+	if (oc == NULL			/* We found no live object */
+	    && grace_oc != NULL		/* There is a grace candidate */
+	    && (busy_oc != NULL		/* Somebody else is already busy */
+	    || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) {
+					 /* Or it is impossible to fetch: */
 		o = grace_oc->obj;
 		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 		if (o->ttl + HSH_Grace(sp->grace) >= sp->t_req)
 			oc = grace_oc;
 	}
-	sp->objhead = NULL;
 
 	if (oc != NULL) {
 		o = oc->obj;

Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt.c	2010-02-01 06:48:16 UTC (rev 4513)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt.c	2010-02-01 08:29:16 UTC (rev 4514)
@@ -308,7 +308,7 @@
 
 	ALLOC_OBJ(new, TROUBLE_MAGIC);
 	AN(new);
-	new->objhead = sp->objhead;
+	new->target = (uintptr_t)sp->objhead;
 	new->timeout = sp->t_req + a;
 
 	/* Insert the new item on the list before the first item with a
@@ -782,7 +782,7 @@
 {
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
-	return (VBE_Healthy(NULL, sp));
+	return (VBE_Healthy_sp(sp, sp->director));
 }
 
 /*--------------------------------------------------------------------*/



More information about the varnish-commit mailing list