[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