[PATCH 07/13] Don't exit on full silo

Martin Blix Grydeland martin at varnish-software.com
Mon Oct 1 12:26:14 CEST 2012


This then also breaks the previous expectation that cur_seg would
always be non-NULL. Change the code to take this into account.
---
 bin/varnishd/storage/storage_persistent.c      |   24 +++++---
 bin/varnishd/storage/storage_persistent_silo.c |   71 ++++++++++++------------
 2 files changed, 54 insertions(+), 41 deletions(-)

diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c
index b54f497..744a5da 100644
--- a/bin/varnishd/storage/storage_persistent.c
+++ b/bin/varnishd/storage/storage_persistent.c
@@ -368,7 +368,9 @@ smp_close(const struct stevedore *st)
 
 	CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC);
 	Lck_Lock(&sc->mtx);
-	smp_close_seg(sc, sc->cur_seg);
+	if (sc->cur_seg != NULL)
+		smp_close_seg(sc, sc->cur_seg);
+	AZ(sc->cur_seg);
 	Lck_Unlock(&sc->mtx);
 
 	/* XXX: reap thread */
@@ -393,7 +395,6 @@ smp_allocx(struct stevedore *st, size_t min_size, size_t max_size,
 	struct smp_sc *sc;
 	struct storage *ss;
 	struct smp_seg *sg;
-	unsigned tries;
 	uint64_t left, extra;
 
 	CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC);
@@ -411,14 +412,22 @@ smp_allocx(struct stevedore *st, size_t min_size, size_t max_size,
 	Lck_Lock(&sc->mtx);
 	sg = NULL;
 	ss = NULL;
-	for (tries = 0; tries < 3; tries++) {
+
+	left = 0;
+	if (sc->cur_seg != NULL)
 		left = smp_spaceleft(sc, sc->cur_seg);
-		if (left >= extra + min_size)
-			break;
-		smp_close_seg(sc, sc->cur_seg);
+	if (left < extra + min_size) {
+		if (sc->cur_seg != NULL)
+			smp_close_seg(sc, sc->cur_seg);
 		smp_new_seg(sc);
+		if (sc->cur_seg != NULL)
+			left = smp_spaceleft(sc, sc->cur_seg);
+		else
+			left = 0;
 	}
+
 	if (left >= extra + min_size)  {
+		AN(sc->cur_seg);
 		if (left < extra + max_size)
 			max_size = IRNDN(sc, left - extra);
 
@@ -611,7 +620,8 @@ debug_persistent(struct cli *cli, const char * const * av, void *priv)
 	}
 	Lck_Lock(&sc->mtx);
 	if (!strcmp(av[3], "sync")) {
-		smp_close_seg(sc, sc->cur_seg);
+		if (sc->cur_seg != NULL)
+			smp_close_seg(sc, sc->cur_seg);
 		smp_new_seg(sc);
 	} else if (!strcmp(av[3], "dump")) {
 		debug_report_silo(cli, sc, 1);
diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c
index d433cde..0014647 100644
--- a/bin/varnishd/storage/storage_persistent_silo.c
+++ b/bin/varnishd/storage/storage_persistent_silo.c
@@ -171,48 +171,50 @@ smp_load_seg(struct worker *wrk, const struct smp_sc *sc,
 void
 smp_new_seg(struct smp_sc *sc)
 {
-	struct smp_seg *sg, *sg2;
+	struct smp_seg tmpsg;
+	struct smp_seg *sg;
 
+	AZ(sc->cur_seg);
 	Lck_AssertHeld(&sc->mtx);
-	ALLOC_OBJ(sg, SMP_SEG_MAGIC);
-	AN(sg);
-	sg->sc = sc;
-	sg->lru = LRU_Alloc();
-	CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC);
 
 	/* XXX: find where it goes in silo */
 
-	sg->p.offset = sc->free_offset;
-	// XXX: align */
-	assert(sg->p.offset >= sc->ident->stuff[SMP_SPC_STUFF]);
-	assert(sg->p.offset < sc->mediasize);
-
-	sg->p.length = sc->aim_segl;
-	sg->p.length &= ~7;
-
-	if (smp_segend(sg) > sc->mediasize) {
-		sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF];
-		sg->p.offset = sc->free_offset;
-		sg2 = VTAILQ_FIRST(&sc->segments);
-		if (smp_segend(sg) > sg2->p.offset) {
-			printf("Out of space in persistent silo\n");
-			printf("Committing suicide, restart will make space\n");
-			exit (0);
-		}
+	memset(&tmpsg, 0, sizeof tmpsg);
+	tmpsg.magic = SMP_SEG_MAGIC;
+	tmpsg.sc = sc;
+	tmpsg.p.offset = sc->free_offset;
+	/* XXX: align */
+	assert(tmpsg.p.offset >= sc->ident->stuff[SMP_SPC_STUFF]);
+	assert(tmpsg.p.offset < sc->mediasize);
+
+	tmpsg.p.length = sc->aim_segl;
+	tmpsg.p.length &= ~7;
+
+	if (smp_segend(&tmpsg) > sc->mediasize)
+		/* XXX: Consider truncation in this case */
+		tmpsg.p.offset = sc->ident->stuff[SMP_SPC_STUFF];
+
+	assert(smp_segend(&tmpsg) <= sc->mediasize);
+
+	sg = VTAILQ_FIRST(&sc->segments);
+	if (sg != NULL && tmpsg.p.offset <= sg->p.offset) {
+		if (smp_segend(&tmpsg) > sg->p.offset)
+			/* No more space, return (cur_seg will be NULL) */
+			/* XXX: Consider truncation instead of failing */
+			return;
+		assert(smp_segend(&tmpsg) <= sg->p.offset);
 	}
 
+	if (tmpsg.p.offset == sc->ident->stuff[SMP_SPC_STUFF])
+		printf("Wrapped silo\n");
 
-	assert(smp_segend(sg) <= sc->mediasize);
-
-	sg2 = VTAILQ_FIRST(&sc->segments);
-	if (sg2 != NULL && sg2->p.offset > sc->free_offset) {
-		if (smp_segend(sg) > sg2->p.offset) {
-			printf("Out of space in persistent silo\n");
-			printf("Committing suicide, restart will make space\n");
-			exit (0);
-		}
-		assert(smp_segend(sg) <= sg2->p.offset);
-	}
+	ALLOC_OBJ(sg, SMP_SEG_MAGIC);
+	if (sg == NULL)
+		/* Failed allocation */
+		return;
+	*sg = tmpsg;
+	sg->lru = LRU_Alloc();
+	CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC);
 
 	sg->p.offset = IRNUP(sc, sg->p.offset);
 	sg->p.length = IRNDN(sc, sg->p.length);
@@ -248,6 +250,7 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg)
 
 	Lck_AssertHeld(&sc->mtx);
 
+	CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
 	assert(sg == sc->cur_seg);
 	AN(sg->p.offset);
 	sc->cur_seg = NULL;
-- 
1.7.9.5




More information about the varnish-dev mailing list