[master] 07c4179 ...and make it all work again.

Poul-Henning Kamp phk at varnish-cache.org
Mon Nov 21 00:39:25 CET 2011


commit 07c41790c25e31914a5f6e6297f3591537efd9fd
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sun Nov 20 23:38:24 2011 +0000

    ...and make it all work again.
    
    At least "work" in the sense that varnishtest does not obviously
    break, but since it doesn't test the utils at all (but does use
    the varnishapi) more work & testing will be needed.

diff --git a/bin/varnishd/common/heritage.h b/bin/varnishd/common/heritage.h
index 9169bd5..b62a6ca 100644
--- a/bin/varnishd/common/heritage.h
+++ b/bin/varnishd/common/heritage.h
@@ -67,7 +67,6 @@ struct heritage {
 
 	char				*panic_str;
 	ssize_t				panic_str_len;
-	
 };
 
 extern struct heritage heritage;
diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c
index cf1742d..080f48a 100644
--- a/bin/varnishtest/vtc_varnish.c
+++ b/bin/varnishtest/vtc_varnish.c
@@ -200,17 +200,12 @@ varnishlog_thread(void *priv)
 	vsl = VSM_New();
 	VSL_Setup(vsl);
 	(void)VSL_Arg(vsl, 'n', v->workdir);
-	VSL_NonBlocking(vsl, 1);
 	while (v->pid  && VSL_Open(vsl, 0) != 0) {
 		assert(usleep(VSL_SLEEP_USEC) == 0 || errno == EINTR);
 	}
 	while (v->pid) {
-		if (VSL_Dispatch(vsl, h_addlog, v) < 0) {
-			assert(usleep(v->vsl_sleep) == 0 || errno == EINTR);
-			v->vsl_sleep += v->vsl_sleep;
-			if (v->vsl_sleep > VSL_SLEEP_USEC)
-				v->vsl_sleep = VSL_SLEEP_USEC;
-		}
+		if (VSL_Dispatch(vsl, h_addlog, v) <= 0)
+			break;
 	}
 	VSM_Delete(vsl);
 	return (NULL);
@@ -732,7 +727,7 @@ varnish_expect(const struct varnish *v, char * const *av) {
 	uint64_t ref;
 	int good;
 	char *p;
-	int i;
+	int i, j;
 	struct stat_priv sp;
 
 	good = -1;
@@ -742,9 +737,20 @@ varnish_expect(const struct varnish *v, char * const *av) {
 	ref = 0;
 	for (i = 0; i < 10; i++, (void)usleep(100000)) {
 
-		good = -1;
-		if (!VSC_Iter(v->vd, do_stat_cb, &sp))
-			continue;
+		good = VSC_Iter(v->vd, do_stat_cb, &sp);
+		if (good < 0) {
+			VSM_Close(v->vd);
+			j = VSM_Open(v->vd, 0);
+			if (j == 0)
+				continue;
+			do {
+				(void)usleep(100000);
+				j = VSM_Open(v->vd, 0);
+				i++;
+			} while(i < 10 && j < 0);
+			if (j < 0)
+				break;
+		}
 		good = 0;
 
 		ref = strtoumax(av[2], &p, 0);
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index 5791e85..c9facfd 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -326,6 +326,8 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
 	vsc = vd->vsc;
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	i = 0;
+	if (!VSM_StillValid(vd, NULL))
+		return (-1);
 	VSM_FOREACH_SAFE(&vf, vd) {
 		if (strcmp(vf.chunk->class, VSC_CLASS))
 			continue;
diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c
index 3c90381..3e7eb40 100644
--- a/lib/libvarnishapi/vsl.c
+++ b/lib/libvarnishapi/vsl.c
@@ -51,6 +51,8 @@
 #include "vsl_api.h"
 #include "vsm_api.h"
 
+static void VSL_Close(struct VSM_data *vd);
+
 /*--------------------------------------------------------------------*/
 
 const char *VSL_tags[256] = {
@@ -128,20 +130,30 @@ VSL_NonBlocking(const struct VSM_data *vd, int nb)
 		vsl->flags &= ~F_NON_BLOCKING;
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Return the next log record, if there is one
+ *
+ * Return:
+ *	<0: error
+ *	0: no record
+ *	>0: record available at pp
+ */
 
 static int
 vsl_nextlog(struct vsl *vsl, uint32_t **pp)
 {
-	unsigned w, l;
+	unsigned l;
 	uint32_t t;
 	int i;
 
 	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
 
+	*pp = NULL;
 	if (vsl->r_fd != -1) {
 		assert(vsl->rbuflen >= 8);
 		i = read(vsl->r_fd, vsl->rbuf, 8);
+		if (i == 0)
+			return (0);
 		if (i != 8)
 			return (-1);
 		l = 2 + VSL_WORDS(VSL_LEN(vsl->rbuf));
@@ -157,38 +169,36 @@ vsl_nextlog(struct vsl *vsl, uint32_t **pp)
 		*pp = vsl->rbuf;
 		return (1);
 	}
-	for (w = 0; w < TIMEOUT_USEC;) {
+	while (1) {
+		if (vsl->log_ptr == NULL)
+			return (0);
+		assert(vsl->log_ptr >= vsl->log_start + 1);
+		assert(vsl->log_ptr < vsl->log_end);
 		t = *vsl->log_ptr;
 
 		if (t == VSL_WRAPMARKER) {
 			/* Wrap around not possible at front */
-			assert(vsl->log_ptr != vsl->log_start + 1);
+			if (vsl->log_ptr == vsl->log_start + 1)
+				return (-1);
 			vsl->log_ptr = vsl->log_start + 1;
-			VRMB();
 			continue;
 		}
+
 		if (t == VSL_ENDMARKER) {
 			if (vsl->log_ptr != vsl->log_start + 1 &&
 			    vsl->last_seq != vsl->log_start[0]) {
 				/* ENDMARKER not at front and seq wrapped */
 				vsl->log_ptr = vsl->log_start + 1;
-				VRMB();
 				continue;
 			}
-			if (vsl->flags & F_NON_BLOCKING)
-				return (-1);
-			w += SLEEP_USEC;
-			assert(usleep(SLEEP_USEC) == 0 || errno == EINTR);
-			VRMB();
-			continue;
+			return (0);
 		}
+
 		if (t == 0) {
-			/* Zero-initialized VSL */
-			w += SLEEP_USEC;
-			assert(usleep(SLEEP_USEC) == 0 || errno == EINTR);
-			VRMB();
-			continue;
+			/* Uninitialized VSL */
+			return (0);
 		}
+
 		if (vsl->log_ptr == vsl->log_start + 1)
 			vsl->last_seq = vsl->log_start[0];
 
@@ -196,8 +206,6 @@ vsl_nextlog(struct vsl *vsl, uint32_t **pp)
 		vsl->log_ptr = VSL_NEXT(vsl->log_ptr);
 		return (1);
 	}
-	*pp = NULL;
-	return (0);
 }
 
 int
@@ -214,7 +222,7 @@ VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
 
 	while (1) {
 		i = vsl_nextlog(vsl, &p);
-		if (i != 1)
+		if (i <= 0)
 			return (i);
 		t = VSL_TAG(p);
 		if (vsl->skip) {
@@ -275,17 +283,37 @@ VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv)
 	unsigned u, l, s;
 	uint32_t *p;
 	uint64_t bitmap;
+	int tmo;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
 	vsl = vd->vsl;
 	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
 
+	tmo = 0;
 	while (1) {
 		bitmap = 0;
 		i = VSL_NextLog(vd, &p, &bitmap);
-		if (i == 0 && VSM_ReOpen(vd, 0) == 1)
+		if (i == 0) {
+			if (vsl->r_fd != -1)
+				return(0);
+			if (vsl->flags & F_NON_BLOCKING)
+				return (0);
+			if (VSM_StillValid(vd, &vsl->vf) != 1) {
+				VSL_Close(vd);
+				if (VSL_Open(vd, 0))
+					return (-1);
+				AN(vsl->log_ptr);
+				assert(vsl->log_ptr >= vsl->log_start + 1);
+				assert(vsl->log_ptr < vsl->log_end);
+				continue;
+			}
+			tmo += SLEEP_USEC;
+			if (tmo > TIMEOUT_USEC)
+				return (0);
+			(void)usleep(SLEEP_USEC);
 			continue;
-		if (i != 1)
+		}
+		if (i <= 0)
 			return (i);
 		u = VSL_ID(p);
 		l = VSL_LEN(p);
@@ -294,7 +322,8 @@ VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv)
 			s |= VSL_S_CLIENT;
 		if (VSL_BACKEND(p))
 			s |= VSL_S_BACKEND;
-		if (func(priv, (enum VSL_tag_e)VSL_TAG(p), u, l, s, VSL_DATA(p), bitmap))
+		if (func(priv, (enum VSL_tag_e)VSL_TAG(p),
+		    u, l, s, VSL_DATA(p), bitmap))
 			return (1);
 	}
 }
@@ -333,6 +362,23 @@ VSL_H_Print(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len,
 
 /*--------------------------------------------------------------------*/
 
+static void
+VSL_Close(struct VSM_data *vd)
+{
+	struct vsl *vsl;
+
+	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
+	vsl = vd->vsl;
+	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+
+	VSM_Close(vd);
+	vsl->log_start = NULL;
+	vsl->log_end = NULL;
+	vsl->log_ptr = NULL;
+}
+
+/*--------------------------------------------------------------------*/
+
 int
 VSL_Open(struct VSM_data *vd, int diag)
 {
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index c410fde..6c78baa 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -297,19 +297,25 @@ VSM__iter0(const struct VSM_data *vd, struct VSM_fantom *vf)
 int
 VSM__itern(const struct VSM_data *vd, struct VSM_fantom *vf)
 {
+	void *p;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	if (vf->priv != 0) {
+	if (vd->head->alloc_seq == 0)
+		return (0);	/* abandonned VSM */
+	else if (vf->priv != 0) {
 		if (vf->priv != vd->head->alloc_seq)
 			return (0);
 		if (vf->chunk->len == 0)
 			return (0);
 		if (vf->chunk->next == 0)
 			return (0);
-		vf->chunk = (void*)(vd->b + vf->chunk->next);
+		p = (void*)(vd->b + vf->chunk->next);
+		assert(p != vf->chunk);
+		vf->chunk = p;
 	} else if (vd->head->first == 0) {
 		return (0);
 	} else {
+		AZ(vf->chunk);
 		vf->chunk = (void*)(vd->b + vd->head->first);
 	}
 	if (memcmp(vf->chunk->marker, VSM_CHUNK_MARKER,
@@ -318,8 +324,13 @@ VSM__itern(const struct VSM_data *vd, struct VSM_fantom *vf)
 	vf->priv = vd->head->alloc_seq;
 	vf->b = (void*)(vf->chunk + 1);
 	vf->e = (char*)vf->b + vf->chunk->len;
+
+	if (vd->priv == 0)
+		return (0);	/* abandonned VSM */
 	if (vf->b == vf->e)
-		return (0);
+		return (0);	/* freed chunk */
+	AN(vf->priv);
+	AN(vf->chunk);
 	return (1);
 }
 
@@ -331,6 +342,8 @@ VSM_StillValid(const struct VSM_data *vd, struct VSM_fantom *vf)
 	struct VSM_fantom f2;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
+	if (vf == NULL)
+		return (vd->head->alloc_seq ? 1 : 0);
 	if (vf->priv == vd->head->alloc_seq)
 		return (1);
 	VSM_FOREACH_SAFE(&f2, vd) {



More information about the varnish-commit mailing list