[4.1] 2899efd Relive the VMODs of the responsibility of tracking dynamic backends connection count.

Poul-Henning Kamp phk at FreeBSD.org
Fri Sep 4 15:54:49 CEST 2015


commit 2899efd1055dab6b8ba47caace51e580ae3b56cd
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Jul 7 22:43:35 2015 +0000

    Relive the VMODs of the responsibility of tracking dynamic backends
    connection count.
    
    Instead we mark the dynamic backends unhealthy with the status "deleted",
    hide it from CLI displays, prevent new connections from being opened
    and clean the backend up when the connection count goes to zero.
    
    Radically different from patch from: Dridi

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 0cfbd40..6574278 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -675,6 +675,7 @@ void VCA_Shutdown(void);
 
 /* cache_backend_cfg.c */
 void VBE_InitCfg(void);
+void VBE_Poll(void);
 
 /* cache_backend_poll.c */
 void VBP_Init(void);
@@ -1052,8 +1053,6 @@ void VCL_Poll(void);
 void VCL_Ref(struct vcl *);
 void VCL_Refresh(struct vcl **);
 void VCL_Rel(struct vcl **);
-void VCL_AddBackend(struct vcl *, struct backend *);
-void VCL_DelBackend(struct vcl *, const struct backend *);
 const char *VCL_Return_Name(unsigned);
 
 #define VCL_MET_MAC(l,u,b) \
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index 06f50e1..97e70c1 100644
--- a/bin/varnishd/cache/cache_backend.h
+++ b/bin/varnishd/cache/cache_backend.h
@@ -57,7 +57,7 @@ struct backend {
 
 	VRT_BACKEND_FIELDS()
 
-	const struct vcl	*vcl;
+	struct vcl		*vcl;
 	char			*display_name;
 
 	unsigned		n_conn;
@@ -109,13 +109,14 @@ void VBE_Event(struct backend *, enum vcl_event_e);
 #endif
 void VBE_Delete(struct backend *be);
 
-/* cache_backend_poll.c */
+/* cache_backend_probe.c */
 void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p,
     struct tcp_pool *);
 void VBP_Remove(struct backend *b);
 void VBP_Control(const struct backend *b, int stop);
 void VBP_Status(struct cli *cli, const struct backend *, int details);
 
+/* cache_backend_tcp.c */
 struct tcp_pool *VBT_Ref(const struct suckaddr *ip4,
     const struct suckaddr *ip6);
 void VBT_Rel(struct tcp_pool **tpp);
@@ -125,3 +126,7 @@ void VBT_Close(struct tcp_pool *tp, struct vbc **vbc);
 struct vbc *VBT_Get(struct tcp_pool *, double tmo, const struct backend *,
     struct worker *);
 void VBT_Wait(struct worker *, struct vbc *);
+
+/* cache_vcl.c */
+void VCL_AddBackend(struct vcl *, struct backend *);
+void VCL_DelBackend(const struct backend *);
diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index aba8e8b..23d0d44 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -53,6 +53,7 @@ static struct lock backends_mtx;
 static const char * const vbe_ah_healthy	= "healthy";
 static const char * const vbe_ah_sick		= "sick";
 static const char * const vbe_ah_probe		= "probe";
+static const char * const vbe_ah_deleted	= "deleted";
 
 /*--------------------------------------------------------------------
  * Create a new static or dynamic director::backend instance.
@@ -131,6 +132,7 @@ VRT_delete_backend(VRT_CTX, struct director **dp)
 {
 	struct director *d;
 	struct backend *be;
+	int r;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	AN(dp);
@@ -138,8 +140,20 @@ VRT_delete_backend(VRT_CTX, struct director **dp)
 	*dp = NULL;
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
-	VCL_DelBackend(ctx->vcl, be);
-	VBE_Delete(be);
+	Lck_Lock(&be->mtx);
+	be->admin_health = vbe_ah_deleted;
+	be->health_changed = VTIM_real();
+	r = be->n_conn;
+	if (r > 0) {
+		/* move to front of list for fast access */
+		VTAILQ_REMOVE(&backends, be, list);
+		VTAILQ_INSERT_HEAD(&backends, be, list);
+	}
+	Lck_Unlock(&be->mtx);
+	if (r == 0) {
+		VCL_DelBackend(be);
+		VBE_Delete(be);
+	}
 }
 
 /*---------------------------------------------------------------------
@@ -231,6 +245,9 @@ VBE_Healthy(const struct backend *backend, double *changed)
 	if (backend->admin_health == vbe_ah_sick)
 		return (0);
 
+	if (backend->admin_health == vbe_ah_deleted)
+		return (0);
+
 	if (backend->admin_health == vbe_ah_healthy)
 		return (1);
 
@@ -275,6 +292,8 @@ backend_find(struct cli *cli, const char *matcher, bf_func *func, void *priv)
 	AZ(VSB_finish(vsb));
 	Lck_Lock(&backends_mtx);
 	VTAILQ_FOREACH(b, &backends, list) {
+		if (b->admin_health == vbe_ah_deleted)
+			continue;
 		if (fnmatch(VSB_data(vsb), b->display_name, 0))
 			continue;
 		found++;
@@ -357,7 +376,8 @@ do_set_health(struct cli *cli, struct backend *b, void *priv)
 	AN(*ah);
 	CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
 	prev = VBE_Healthy(b, NULL);
-	b->admin_health = *ah;
+	if (b->admin_health != vbe_ah_deleted)
+		b->admin_health = *ah;
 	if (prev != VBE_Healthy(b, NULL))
 		b->health_changed = VTIM_real();
 
@@ -404,6 +424,27 @@ static struct cli_proto backend_cmds[] = {
 /*---------------------------------------------------------------------*/
 
 void
+VBE_Poll(void)
+{
+	struct backend *be;
+	Lck_Lock(&backends_mtx);
+	while (1) {
+		be = VTAILQ_FIRST(&backends);
+		if (be == NULL)
+			break;
+		if (be->admin_health != vbe_ah_deleted)
+			break;
+		if (be->n_conn > 0)
+			break;
+		VCL_DelBackend(be);
+		VBE_Delete(be);
+	}
+	Lck_Unlock(&backends_mtx);
+}
+
+/*---------------------------------------------------------------------*/
+
+void
 VBE_InitCfg(void)
 {
 
diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c
index 5fbad58..3ba8cdd 100644
--- a/bin/varnishd/cache/cache_cli.c
+++ b/bin/varnishd/cache/cache_cli.c
@@ -78,6 +78,7 @@ cli_cb_before(const struct cli *cli)
 	ASSERT_CLI();
 	VSL(SLT_CLI, 0, "Rd %s", cli->cmd);
 	VCL_Poll();
+	VBE_Poll();
 	Lck_Lock(&cli_mtx);
 }
 
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 0a5eac9..b450361 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -47,6 +47,7 @@
 #include "vcli.h"
 #include "vcli_priv.h"
 
+static const char * const vcl_temp_init = "init";
 static const char * const vcl_temp_cold = "cold";
 static const char * const vcl_temp_warm = "warm";
 static const char * const vcl_temp_cooling = "cooling";
@@ -199,14 +200,18 @@ VCL_AddBackend(struct vcl *vcl, struct backend *be)
 	if (vcl->temp == vcl_temp_warm) {
 		/* Only when adding backend to already warm VCL */
 		VBE_Event(be, VCL_EVENT_WARM);
-	}
+	} else if (vcl->temp != vcl_temp_init)
+		WRONG("Dynamic Backends can only be added to warm VCLs");
 }
 
 void
-VCL_DelBackend(struct vcl *vcl, const struct backend *be)
+VCL_DelBackend(const struct backend *be)
 {
-	CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
+	struct vcl *vcl;
+
 	CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
+	vcl = be->vcl;
+	CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
 	Lck_Lock(&vcl_mtx);
 	VTAILQ_REMOVE(&vcl->backend_list, be, vcl_list);
 	Lck_Unlock(&vcl_mtx);
@@ -395,7 +400,7 @@ vcl_set_state(struct vcl *vcl, const char *state)
 		}
 		break;
 	case '1':
-		if (vcl->temp != vcl_temp_cold)
+		if (vcl->temp == vcl_temp_cooling)
 			vcl->temp = vcl_temp_warm;
 		else {
 			vcl->temp = vcl_temp_warm;
@@ -440,7 +445,7 @@ VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
 	XXXAN(vcl->loaded_name);
 	VTAILQ_INIT(&vcl->backend_list);
 
-	vcl->temp = vcl_temp_cold;
+	vcl->temp = vcl_temp_init;
 
 	INIT_OBJ(&ctx, VRT_CTX_MAGIC);
 	ctx.method = VCL_MET_INIT;



More information about the varnish-commit mailing list