[master] d912ffe4f fix probe not started for already warm vcl

Nils Goroll nils.goroll at uplex.de
Thu Jun 28 14:24:08 UTC 2018


commit d912ffe4f7a5e643275699c94b2722d486fd9e7f
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Thu Jun 28 15:57:29 2018 +0200

    fix probe not started for already warm vcl
    
    For (real) backends, we used to assign the probe after adding the
    director via VRT_AddDirector(). For an already warm vcl, this lead to
    a VCL_WARM event missed because the event was issued by
    VRT_AddDirector() when the probe did not exist yet.
    
    We fix this by preparing all of the backend before adding the
    director, undoing the work for a failure doing do.
    
    In addition, if adding a backend while the vcl is cold, we need to set
    the initial director state based on the probe configuration after
    adding the director.
    
    We avoid the overhead of the vcl temperature lock because no harm is
    done: If, after the director was added, the temperature goes cold, we
    just run an additional update, and if it goes warm, the update will
    already have happened.
    
    Likely related to https://github.com/nigoroll/libvmod-dynamic/issues/35

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index c56081332..9f08c2385 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -43,6 +43,7 @@
 #include "cache_backend.h"
 #include "cache_tcp_pool.h"
 #include "cache_transport.h"
+#include "cache_vcl.h"
 #include "http1/cache_http1.h"
 
 #include "VSC_vbe.h"
@@ -525,25 +526,38 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc,
 	    "%s.%s", VCL_Name(ctx->vcl), vrt->vcl_name);
 	AN(be->vsc);
 
+	be->tcp_pool = VTP_Ref(vrt->ipv4_suckaddr, vrt->ipv6_suckaddr,
+	    vrt->path, vbe_proto_ident);
+	AN(be->tcp_pool);
+
+	vbp = vrt->probe;
+	if (vbp == NULL)
+		vbp = VCL_DefaultProbe(vcl);
+
+	if (vbp != NULL)
+		VBP_Insert(be, vbp, be->tcp_pool);
+
 	be->director = VRT_AddDirector(ctx, vbe_methods, be,
 	    "%s", vrt->vcl_name);
+
 	if (be->director != NULL) {
-		vbp = vrt->probe;
-		if (vbp == NULL)
-			vbp = VCL_DefaultProbe(vcl);
+		/* for cold VCL, update initial director state */
+		if (be->probe != NULL && ! VCL_WARM(vcl))
+			VBP_Update_Backend(be->probe);
 
 		Lck_Lock(&backends_mtx);
 		VTAILQ_INSERT_TAIL(&backends, be, list);
 		VSC_C_main->n_backend++;
-		be->tcp_pool = VTP_Ref(vrt->ipv4_suckaddr, vrt->ipv6_suckaddr,
-				       vrt->path, vbe_proto_ident);
 		Lck_Unlock(&backends_mtx);
-
-		if (vbp != NULL)
-			VBP_Insert(be, vbp, be->tcp_pool);
-
 		return (be->director);
 	}
+
+	/* undo */
+	if (vbp != NULL)
+		VBP_Remove(be);
+
+	VTP_Rel(&be->tcp_pool);
+
 	VSC_vbe_Destroy(&be->vsc_seg);
 #define DA(x)	do { if (be->x != NULL) free(be->x); } while (0)
 #define DN(x)	/**/
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index 706fea428..f5c016860 100644
--- a/bin/varnishd/cache/cache_backend.h
+++ b/bin/varnishd/cache/cache_backend.h
@@ -77,6 +77,7 @@ struct backend {
 void VBE_SetHappy(const struct backend *, uint64_t);
 
 /* cache_backend_probe.c */
+void VBP_Update_Backend(struct vbp_target *vt);
 void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p,
     struct tcp_pool *);
 void VBP_Remove(struct backend *b);
diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c
index b5a665a9d..e63cd02c4 100644
--- a/bin/varnishd/cache/cache_backend_probe.c
+++ b/bin/varnishd/cache/cache_backend_probe.c
@@ -150,8 +150,8 @@ vbp_has_poked(struct vbp_target *vt)
 	vt->good = j;
 }
 
-static void
-vbp_update_backend(struct vbp_target *vt)
+void
+VBP_Update_Backend(struct vbp_target *vt)
 {
 	unsigned i = 0;
 	char bits[10];
@@ -433,7 +433,7 @@ vbp_task(struct worker *wrk, void *priv)
 	vbp_start_poke(vt);
 	vbp_poke(vt);
 	vbp_has_poked(vt);
-	vbp_update_backend(vt);
+	VBP_Update_Backend(vt);
 
 	Lck_Lock(&vbp_mtx);
 	if (vt->running < 0) {
@@ -637,7 +637,7 @@ VBP_Control(const struct backend *be, int enable)
 	CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC);
 
 	vbp_reset(vt);
-	vbp_update_backend(vt);
+	VBP_Update_Backend(vt);
 
 	Lck_Lock(&vbp_mtx);
 	if (enable) {
@@ -679,7 +679,7 @@ VBP_Insert(struct backend *b, const struct vrt_backend_probe *vp,
 	vbp_build_req(vt, vp, b);
 
 	vbp_reset(vt);
-	vbp_update_backend(vt);
+	VBP_Update_Backend(vt);
 }
 
 void


More information about the varnish-commit mailing list