[master] 8c4658a Add support for directors reporting time of last health-change

Poul-Henning Kamp phk at varnish-cache.org
Tue Sep 10 09:25:47 CEST 2013


commit 8c4658af548dfb056c81085aa8f4873323968b32
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Sep 10 07:25:30 2013 +0000

    Add support for directors reporting time of last health-change

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 092f43f..3c3e460 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -230,15 +230,14 @@ vbe_NewConn(void)
  * items would never time out once the threshold is reached.
  */
 
-static unsigned int
-vbe_Healthy(const struct vdi_simple *vs)
+unsigned
+VBE_Healthy(const struct backend *backend, double *changed)
 {
-	struct backend *backend;
-
-	CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC);
-	backend = vs->backend;
 	CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC);
 
+	if (changed != NULL)
+		*changed = backend->health_changed;
+
 	if (backend->admin_health == ah_probe && !backend->healthy)
 		return (0);
 
@@ -301,7 +300,7 @@ vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs)
 		VBE_ReleaseConn(vc);
 	}
 
-	if (!vbe_Healthy(vs)) {
+	if (!VBE_Healthy(bp, NULL)) {
 		VSC_C_main->backend_unhealthy++;
 		return (NULL);
 	}
@@ -391,13 +390,16 @@ vdi_simple_getfd(const struct director *d, struct busyobj *bo)
 }
 
 static unsigned
-vdi_simple_healthy(const struct director *d)
+vdi_simple_healthy(const struct director *d, double *changed)
 {
 	struct vdi_simple *vs;
+	struct backend *be;
 
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
-	return (vbe_Healthy(vs));
+	be = vs->backend;
+	CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
+	return (VBE_Healthy(be, changed));
 }
 
 static void
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index d186ecc..f3931e9 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 void vdi_fini_f(const struct director *);
-typedef unsigned vdi_healthy(const struct director *);
+typedef unsigned vdi_healthy(const struct director *, double *changed);
 
 struct director {
 	unsigned		magic;
@@ -124,6 +124,7 @@ struct backend {
 	struct vbp_target	*probe;
 	unsigned		healthy;
 	enum admin_health	admin_health;
+	double			health_changed;
 
 	struct VSC_C_vbe	*vsc;
 };
@@ -156,6 +157,7 @@ void VBE_ReleaseConn(struct vbc *vc);
 void VBE_DropRefConn(struct backend *);
 void VBE_DropRefVcl(struct backend *);
 void VBE_DropRefLocked(struct backend *b);
+unsigned VBE_Healthy(const struct backend *b, double *changed);
 
 /* cache_backend_poll.c */
 void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p,
diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index 24ed727..2d55147 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -43,6 +43,7 @@
 #include "vcli_priv.h"
 #include "vsa.h"
 #include "vrt.h"
+#include "vtim.h"
 
 /*
  * The list of backends is not locked, it is only ever accessed from
@@ -230,6 +231,7 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
 	assert(b->ipv4 != NULL || b->ipv6 != NULL);
 
 	b->healthy = 1;
+	b->health_changed = VTIM_real();
 	b->admin_health = ah_probe;
 
 	VTAILQ_INSERT_TAIL(&backends, b, list);
@@ -415,6 +417,8 @@ do_list(struct cli *cli, struct backend *b, void *priv)
 		VBP_Summary(cli, b->probe);
 	}
 
+	/* XXX: report b->health_changed */
+
 	return (0);
 }
 
@@ -435,11 +439,16 @@ static int __match_proto__()
 do_set_health(struct cli *cli, struct backend *b, void *priv)
 {
 	enum admin_health state;
+	unsigned prev;
 
 	(void)cli;
 	state = *(enum admin_health*)priv;
 	CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+	prev = VBE_Healthy(b, NULL);
 	b->admin_health = state;
+	if (prev != VBE_Healthy(b, NULL))
+		b->health_changed = VTIM_real();
+
 	return (0);
 }
 
diff --git a/bin/varnishd/cache/cache_backend_poll.c b/bin/varnishd/cache/cache_backend_poll.c
index f93fe2f..4cc03ce 100644
--- a/bin/varnishd/cache/cache_backend_poll.c
+++ b/bin/varnishd/cache/cache_backend_poll.c
@@ -280,13 +280,16 @@ vbp_has_poked(struct vbp_target *vt)
 	if (vt->good >= vt->probe.threshold) {
 		if (vt->backend->healthy)
 			logmsg = "Still healthy";
-		else
+		else {
 			logmsg = "Back healthy";
+			vt->backend->health_changed = VTIM_real();
+		}
 		vt->backend->healthy = 1;
 	} else {
-		if (vt->backend->healthy)
+		if (vt->backend->healthy) {
 			logmsg = "Went sick";
-		else
+			vt->backend->health_changed = VTIM_real();
+		} else
 			logmsg = "Still sick";
 		vt->backend->healthy = 0;
 	}
diff --git a/bin/varnishd/cache/cache_dir.c b/bin/varnishd/cache/cache_dir.c
index 5d7939a..ae6cb2d 100644
--- a/bin/varnishd/cache/cache_dir.c
+++ b/bin/varnishd/cache/cache_dir.c
@@ -116,10 +116,6 @@ VDI_GetFd(const struct director *d, struct busyobj *bo)
 }
 
 /* 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
@@ -127,5 +123,5 @@ VDI_Healthy(const struct director *d)
 {
 
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
-	return (d->healthy(d));
+	return (d->healthy(d, NULL));
 }
diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c
index 4c86b7e..edec2af 100644
--- a/lib/libvmod_directors/fall_back.c
+++ b/lib/libvmod_directors/fall_back.c
@@ -45,12 +45,12 @@ struct vmod_directors_fallback {
 };
 
 static unsigned __match_proto__(vdi_healthy)
-vmod_rr_healthy(const struct director *dir)
+vmod_rr_healthy(const struct director *dir, double *changed)
 {
 	struct vmod_directors_fallback *rr;
 
 	CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_FALLBACK_MAGIC);
-	return (vdir_any_healthy(rr->vd));
+	return (vdir_any_healthy(rr->vd, changed));
 }
 
 static struct vbc * __match_proto__(vdi_getfd_f)
@@ -65,7 +65,7 @@ vmod_rr_getfd(const struct director *dir, struct busyobj *bo)
 	for (u = 0; u < rr->vd->n_backend; u++) {
 		be = rr->vd->backend[u];
 		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
-		if (be->healthy(be))
+		if (be->healthy(be, NULL))
 			break;
 	}
 	vdir_unlock(rr->vd);
diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c
index a31ec1b..22f0bb9 100644
--- a/lib/libvmod_directors/random.c
+++ b/lib/libvmod_directors/random.c
@@ -50,12 +50,12 @@ struct vmod_directors_random {
 };
 
 static unsigned __match_proto__(vdi_healthy)
-vmod_rr_healthy(const struct director *dir)
+vmod_rr_healthy(const struct director *dir, double *changed)
 {
 	struct vmod_directors_random *rr;
 
 	CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC);
-	return (vdir_any_healthy(rr->vd));
+	return (vdir_any_healthy(rr->vd, changed));
 }
 
 static struct vbc * __match_proto__(vdi_getfd_f)
diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c
index f4b5eb6..629bbbf 100644
--- a/lib/libvmod_directors/round_robin.c
+++ b/lib/libvmod_directors/round_robin.c
@@ -46,12 +46,12 @@ struct vmod_directors_round_robin {
 };
 
 static unsigned __match_proto__(vdi_healthy)
-vmod_rr_healthy(const struct director *dir)
+vmod_rr_healthy(const struct director *dir, double *changed)
 {
 	struct vmod_directors_round_robin *rr;
 
 	CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
-	return (vdir_any_healthy(rr->vd));
+	return (vdir_any_healthy(rr->vd, changed));
 }
 
 static struct vbc * __match_proto__(vdi_getfd_f)
@@ -68,7 +68,7 @@ vmod_rr_getfd(const struct director *dir, struct busyobj *bo)
 		be = rr->vd->backend[rr->nxt];
 		rr->nxt++;
 		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
-		if (be->healthy(be))
+		if (be->healthy(be, NULL))
 			break;
 	}
 	vdir_unlock(rr->vd);
diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c
index 8108a29..dacd648 100644
--- a/lib/libvmod_directors/vdir.c
+++ b/lib/libvmod_directors/vdir.c
@@ -128,21 +128,25 @@ vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight)
 }
 
 unsigned
-vdir_any_healthy(struct vdir *vd)
+vdir_any_healthy(struct vdir *vd, double *changed)
 {
 	unsigned retval = 0;
 	VCL_BACKEND be;
 	unsigned u;
+	double c;
 
 	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
 	vdir_lock(vd);
+	if (changed != NULL)
+		*changed = 0;
 	for (u = 0; u < vd->n_backend; u++) {
 		be = vd->backend[u];
 		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
-		if (be->healthy(be)) {
-			retval = 1;
+		retval = be->healthy(be, &c);
+		if (changed != NULL && c > *changed)
+			*changed = c;
+		if (retval)
 			break;
-		}
 	}
 	vdir_unlock(vd);
 	return (retval);
@@ -185,7 +189,7 @@ vdir_pick_be(struct vdir *vd, double w, unsigned nloops)
 		u = vdir_pick_by_weight(vd, w * tw, vbm);
 		be = vd->backend[u];
 		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
-		if (be->healthy(be))
+		if (be->healthy(be, NULL))
 			break;
 		if (l == 0) {
 			vbm = vd->vbm;
diff --git a/lib/libvmod_directors/vdir.h b/lib/libvmod_directors/vdir.h
index 39ad9a1..d237b2d 100644
--- a/lib/libvmod_directors/vdir.h
+++ b/lib/libvmod_directors/vdir.h
@@ -47,5 +47,5 @@ void vdir_delete(struct vdir **vdp);
 void vdir_lock(struct vdir *vd);
 void vdir_unlock(struct vdir *vd);
 unsigned vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight);
-unsigned vdir_any_healthy(struct vdir *vd);
+unsigned vdir_any_healthy(struct vdir *vd, double *changed);
 VCL_BACKEND vdir_pick_be(struct vdir *vd, double w, unsigned nloops);



More information about the varnish-commit mailing list