[master] 99c0a17 Hmm, I still don't understand the args to git commit it seems...
Poul-Henning Kamp
phk at varnish-cache.org
Mon Feb 7 22:39:28 CET 2011
commit 99c0a172f83ca4141a8ca9ee8bd095ba6ee36e64
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Feb 7 21:38:22 2011 +0000
Hmm, I still don't understand the args to git commit it seems...
Commit the code that prevents all the evils mentionend in the
previous commit message (see tests/p00007.vtc)
diff --git a/bin/varnishd/storage_persistent.c b/bin/varnishd/storage_persistent.c
index 9868d8d..aab14bb 100644
--- a/bin/varnishd/storage_persistent.c
+++ b/bin/varnishd/storage_persistent.c
@@ -101,7 +101,9 @@ struct smp_seg {
struct smp_segptr p;
- unsigned must_load;
+ unsigned flags;
+#define SMP_SEG_MUSTLOAD (1 << 0)
+#define SMP_SEG_LOADED (1 << 1)
uint32_t nobj; /* Number of objects */
uint32_t nalloc; /* Allocations */
@@ -120,7 +122,7 @@ struct smp_sc {
struct stevedore *parent;
unsigned flags;
-#define SMP_F_LOADED (1 << 0)
+#define SMP_SC_LOADED (1 << 0)
const struct stevedore *stevedore;
int fd;
@@ -676,6 +678,54 @@ smp_find_so(const struct smp_seg *sg, const struct objcore *oc)
}
/*---------------------------------------------------------------------
+ * Check if a given storage structure is valid to use
+ */
+
+static int
+smp_loaded_st(const struct smp_sc *sc, const struct smp_seg *sg,
+ const struct storage *st)
+{
+ struct smp_seg *sg2;
+ const uint8_t *pst;
+ uint64_t o;
+
+ (void)sg; /* XXX: faster: Start search from here */
+ pst = (const void *)st;
+
+ if (pst < (sc->base + sc->ident->stuff[SMP_SPC_STUFF]))
+ return (0x01); /* Before silo payload start */
+ if (pst > (sc->base + sc->ident->stuff[SMP_END_STUFF]))
+ return (0x02); /* After silo end */
+
+ o = pst - sc->base;
+
+ /* Find which segment contains the storage structure */
+ VTAILQ_FOREACH(sg2, &sc->segments, list)
+ if (o > sg2->p.offset && (o + sizeof(*st)) < sg2->p.objlist)
+ break;
+ if (sg2 == NULL)
+ return (0x04); /* No claiming segment */
+ if (!(sg2->flags & SMP_SEG_LOADED))
+ return (0x08); /* Claiming segment not loaded */
+
+ /* It is now safe to access the storage structure */
+ if (st->magic != STORAGE_MAGIC)
+ return (0x10); /* Not enough magic */
+
+ if (o + st->space >= sg2->p.objlist)
+ return (0x20); /* Allocation not inside segment */
+
+ if (st->len > st->space)
+ return (0x40); /* Plain bad... */
+
+ /*
+ * XXX: We could patch up st->stevedore and st->priv here
+ * XXX: but if things go right, we will never need them.
+ */
+ return (0);
+}
+
+/*---------------------------------------------------------------------
* objcore methods for persistent objects
*/
@@ -685,6 +735,9 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc)
struct object *o;
struct smp_seg *sg;
struct smp_object *so;
+ struct storage *st;
+ uint64_t l;
+ int bad;
/* Some calls are direct, but they should match anyway */
assert(oc->methods->getobj == smp_oc_getobj);
@@ -717,9 +770,26 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc)
Lck_Lock(&sg->sc->mtx);
/* Check again, we might have raced. */
if (oc->flags & OC_F_NEEDFIXUP) {
- /* refcnt is >=1 because the object is in the hash */
+ /* We trust caller to have a refcnt for us */
o->objcore = oc;
+ bad = 0;
+ l = 0;
+ VTAILQ_FOREACH(st, &o->store, list) {
+ bad |= smp_loaded_st(sg->sc, sg, st);
+ if (bad)
+ break;
+ l += st->len;
+ }
+ if (l != o->len)
+ bad |= 0x100;
+
+ if(bad) {
+ o->ttl = 0;
+ o->grace = 0;
+ so->ttl = 0;
+ }
+
sg->nfixed++;
wrk->stats.n_object++;
wrk->stats.n_vampireobject--;
@@ -939,8 +1009,8 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_seg *sg)
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC);
- assert(sg->must_load == 1);
- sg->must_load = 0;
+ assert(sg->flags & SMP_SEG_MUSTLOAD);
+ sg->flags &= ~SMP_SEG_MUSTLOAD;
AN(sg->p.offset);
if (sg->p.objlist == 0)
return;
@@ -975,6 +1045,7 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_seg *sg)
sg->nobj++;
}
WRK_SumStat(sp->wrk);
+ sg->flags |= SMP_SEG_LOADED;
}
/*--------------------------------------------------------------------
@@ -1062,7 +1133,7 @@ smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx)
CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC);
sg->p = *ss;
- sg->must_load = 1;
+ sg->flags |= SMP_SEG_MUSTLOAD;
/*
* HACK: prevent save_segs from nuking segment until we have
@@ -1248,10 +1319,10 @@ smp_thread(struct sess *sp, void *priv)
/* First, load all the objects from all segments */
VTAILQ_FOREACH(sg, &sc->segments, list)
- if (sg->must_load)
+ if (sg->flags & SMP_SEG_MUSTLOAD)
smp_load_seg(sp, sc, sg);
- sc->flags |= SMP_F_LOADED;
+ sc->flags |= SMP_SC_LOADED;
BAN_Deref(&sc->tailban);
sc->tailban = NULL;
printf("Silo completely loaded\n");
@@ -1535,7 +1606,7 @@ SMP_Ready(void)
ASSERT_CLI();
do {
VTAILQ_FOREACH(sc, &silos, list)
- if (!(sc->flags & SMP_F_LOADED))
+ if (!(sc->flags & SMP_SC_LOADED))
break;
if (sc != NULL)
(void)sleep(1);
More information about the varnish-commit
mailing list