[master] 5ed9aece4 Teardown straggler backends by sending them DISCARD event
Poul-Henning Kamp
phk at FreeBSD.org
Wed Nov 24 12:33:06 UTC 2021
commit 5ed9aece431e5f0d3a6c4cf337fc90ca2a52c1be
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Nov 24 11:57:35 2021 +0000
Teardown straggler backends by sending them DISCARD event
(3rd part of #3599)
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 063048931..dada7f2b7 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -408,6 +408,8 @@ vbe_dir_event(const struct director *d, enum vcl_event_e ev)
if (bp->probe != NULL)
VBP_Control(bp, 0);
VRT_VSC_Hide(bp->vsc_seg);
+ } else if (ev == VCL_EVENT_DISCARD) {
+ VRT_Assign_Backend(&bp->director, NULL);
}
}
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index c69e1e5c7..48ee357ba 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -447,24 +447,19 @@ vcl_BackendEvent(const struct vcl *vcl, enum vcl_event_e e)
}
static void
-vcl_KillBackends(struct vcl *vcl)
+vcl_KillBackends(const struct vcl *vcl)
{
- struct vcldir *vdir;
+ struct vcldir *vdir, *vdir2;
CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
- AZ(vcl->busy);
- assert(VTAILQ_EMPTY(&vcl->ref_list));
- Lck_Lock(&vcl_mtx);
- while (1) {
- vdir = VTAILQ_FIRST(&vcl->director_list);
- if (vdir == NULL)
- break;
- VTAILQ_REMOVE(&vcl->director_list, vdir, list);
- AN(vdir->methods->destroy);
- vdir->methods->destroy(vdir->dir);
- vcldir_free(vdir);
- }
- Lck_Unlock(&vcl_mtx);
+ assert(vcl->temp == VCL_TEMP_COLD || vcl->temp == VCL_TEMP_INIT);
+ /*
+ * Unlocked because no further directors can be added, and the
+ * remaining ones need to be able to remove themselves.
+ */
+ VTAILQ_FOREACH_SAFE(vdir, &vcl->director_list, list, vdir2)
+ VDI_Event(vdir->dir, VCL_EVENT_DISCARD);
+ assert(VTAILQ_EMPTY(&vcl->director_list));
}
/*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c
index 4144c13f2..6e4592c06 100644
--- a/bin/varnishd/cache/cache_vrt_vcl.c
+++ b/bin/varnishd/cache/cache_vrt_vcl.c
@@ -146,6 +146,7 @@ vcldir_free(struct vcldir *vdir)
CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC);
CHECK_OBJ_NOTNULL(vdir->dir, DIRECTOR_MAGIC);
+ AZ(vdir->refcnt);
Lck_Delete(&vdir->dlck);
free(vdir->cli_name);
FREE_OBJ(vdir->dir);
@@ -225,10 +226,9 @@ VRT_AddDirector(VRT_CTX, const struct vdi_methods *m, void *priv,
return (vdir->dir);
}
-void
-VRT_DelDirector(VCL_BACKEND *bp)
+static void
+retire_backend(VCL_BACKEND *bp)
{
- struct vcl *vcl;
struct vcldir *vdir;
const struct vcltemp *temp;
VCL_BACKEND d;
@@ -236,17 +236,13 @@ VRT_DelDirector(VCL_BACKEND *bp)
TAKE_OBJ_NOTNULL(d, bp, DIRECTOR_MAGIC);
vdir = d->vdir;
CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC);
- vcl = vdir->vcl;
- CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
-
- Lck_Lock(d->mtx);
- assert(vdir->refcnt == 1);
- --vdir->refcnt;
- Lck_Unlock(d->mtx);
+ assert(vdir->refcnt == 0);
+ assert (d == vdir->dir);
+ CHECK_OBJ_NOTNULL(vdir->vcl, VCL_MAGIC);
Lck_Lock(&vcl_mtx);
- temp = vcl->temp;
- VTAILQ_REMOVE(&vcl->director_list, vdir, list);
+ temp = vdir->vcl->temp;
+ VTAILQ_REMOVE(&vdir->vcl->director_list, vdir, list);
Lck_Unlock(&vcl_mtx);
if (temp->is_warm)
@@ -257,9 +253,25 @@ VRT_DelDirector(VCL_BACKEND *bp)
vcldir_free(vdir);
}
+void
+VRT_DelDirector(VCL_BACKEND *bp)
+{
+ struct vcldir *vdir;
+
+ AN(bp);
+ vdir = (*bp)->vdir;
+ CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC);
+ Lck_Lock(&vdir->dlck);
+ assert(vdir->refcnt == 1);
+ vdir->refcnt = 0;
+ Lck_Unlock(&vdir->dlck);
+ retire_backend(bp);
+}
+
void
VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src)
{
+ int busy;
AN(dst);
CHECK_OBJ_ORNULL((*dst), DIRECTOR_MAGIC);
@@ -268,8 +280,10 @@ VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src)
CHECK_OBJ_NOTNULL((*dst)->vdir, VCLDIR_MAGIC);
Lck_Lock((*dst)->mtx);
assert((*dst)->vdir->refcnt > 0);
- --(*dst)->vdir->refcnt;
+ busy = --(*dst)->vdir->refcnt;
Lck_Unlock((*dst)->mtx);
+ if (!busy)
+ retire_backend(dst);
}
if (src != NULL) {
CHECK_OBJ_NOTNULL(src->vdir, VCLDIR_MAGIC);
More information about the varnish-commit
mailing list