[master] 6a5e89c Fix the VSM segment update for real (I hope)

Nils Goroll nils.goroll at uplex.de
Tue Nov 7 00:27:04 UTC 2017


commit 6a5e89cb11f8aeea8be70f71d652163ca6589faa
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Mon Nov 6 23:20:25 2017 +0100

    Fix the VSM segment update for real (I hope)
    
    Somehow I was unable to see that the code did not actually do what I
    thought (and documented) it would do.
    
    Fixes #2470

diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index d623538..53fb98b 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -449,9 +449,17 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
 
 	/*
 	 * Efficient comparison walking the two lists side-by-side is ok because
-	 * segment inserts always happen at the tail (VSMW_Allocv)
+	 * segment inserts always happen at the tail (VSMW_Allocv()). So, as
+	 * soon as vg is exhausted, we only insert.
+	 *
+	 * For restarts, we require a tabula rasa
 	 */
-	vg = VTAILQ_FIRST(&vs->segs);
+
+	if (retval & VSM_MGT_RESTARTED)
+		vg = NULL;
+	else
+		vg = VTAILQ_FIRST(&vs->segs);
+
 	while (p != NULL && *p != '\0') {
 		e = strchr(p, '\n');
 		if (e == NULL)
@@ -467,14 +475,8 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
 			VAV_Free(av);
 			break;
 		}
-		while (vg != NULL && !vsm_cmp_av(&vg->av[1], &av[1]))
-			vg = VTAILQ_NEXT(vg, list);
 
-		if (vg != NULL) {
-			VAV_Free(av);
-			vg->markscan = 1;
-			vg = VTAILQ_NEXT(vg, list);
-		} else {
+		if (vg == NULL) {
 			ALLOC_OBJ(vg2, VSM_SEG_MAGIC);
 			AN(vg2);
 			vg2->av = av;
@@ -482,9 +484,21 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
 			vg2->markscan = 1;
 			vg2->serial = ++vd->serial;
 			VTAILQ_INSERT_TAIL(&vs->segs, vg2, list);
+			continue;
+		}
+
+		while (vg != NULL && vsm_cmp_av(&vg->av[1], &av[1])) {
+			vg = VTAILQ_NEXT(vg, list);
 		}
 
+		VAV_Free(av);
+
+		if (vg == NULL)
+			continue;
 
+		/* entry compared equal, so it survives */
+		vg->markscan = 1;
+		vg = VTAILQ_NEXT(vg, list);
 	}
 	return (retval);
 }


More information about the varnish-commit mailing list