// Ok, a split happened, so we need to walk the osdmaps
set<pg_t> new_pgs; // pgs to scan on each map
new_pgs.insert(pgid);
+ OSDMapRef curmap(get_map(frommap->get_epoch()));
for (epoch_t e = frommap->get_epoch() + 1;
e <= tomap->get_epoch();
++e) {
- OSDMapRef curmap(get_map(e-1));
- OSDMapRef nextmap(get_map(e));
+ OSDMapRef nextmap(try_get_map(e));
+ if (!nextmap)
+ continue;
set<pg_t> even_newer_pgs; // pgs added in this loop
for (set<pg_t>::iterator i = new_pgs.begin(); i != new_pgs.end(); ++i) {
set<pg_t> split_pgs;
}
}
new_pgs.insert(even_newer_pgs.begin(), even_newer_pgs.end());
+ curmap = nextmap;
}
+ assert(curmap == tomap); // we must have had both frommap and tomap
}
}
for (;
next_epoch <= osd_epoch;
++next_epoch) {
- OSDMapRef nextmap = get_map(next_epoch);
+ OSDMapRef nextmap = service.try_get_map(next_epoch);
+ if (!nextmap)
+ continue;
vector<int> newup, newacting;
nextmap->pg_to_up_acting_osds(pg->info.pgid, newup, newacting);
return l;
}
-OSDMapRef OSDService::get_map(epoch_t epoch)
+OSDMapRef OSDService::try_get_map(epoch_t epoch)
{
Mutex::Locker l(map_cache_lock);
OSDMapRef retval = map_cache.lookup(epoch);
if (epoch > 0) {
dout(20) << "get_map " << epoch << " - loading and decoding " << map << dendl;
bufferlist bl;
- assert(_get_map_bl(epoch, bl));
+ if (!_get_map_bl(epoch, bl)) {
+ delete map;
+ return OSDMapRef();
+ }
map->decode(bl);
} else {
dout(20) << "get_map " << epoch << " - return initial " << map << dendl;
SimpleLRU<epoch_t, bufferlist> map_bl_cache;
SimpleLRU<epoch_t, bufferlist> map_bl_inc_cache;
- OSDMapRef get_map(epoch_t e);
+ OSDMapRef try_get_map(epoch_t e);
+ OSDMapRef get_map(epoch_t e) {
+ OSDMapRef ret(try_get_map(e));
+ assert(ret);
+ return ret;
+ }
OSDMapRef add_map(OSDMap *o) {
Mutex::Locker l(map_cache_lock);
return _add_map(o);
vector<int>& newup, vector<int>& newacting,
RecoveryCtx *rctx)
{
- assert(osdmap->get_epoch() == (lastmap->get_epoch() + 1));
assert(lastmap->get_epoch() == osdmap_ref->get_epoch());
assert(lastmap == osdmap_ref);
dout(10) << "handle_advance_map " << newup << "/" << newacting << dendl;
epoch_t last_epoch_clean; // lower bound on last epoch the PG was completely clean.
epoch_t last_epoch_split; // as parent
+ /**
+ * In the event of a map discontinuity, same_*_since may reflect the first
+ * map the osd has seen in the new map sequence rather than the actual start
+ * of the interval. This is ok since a discontinuity at epoch e means there
+ * must have been a clean interval between e and now and that we cannot be
+ * in the active set during the interval containing e.
+ */
epoch_t same_up_since; // same acting set since
epoch_t same_interval_since; // same acting AND up set since
epoch_t same_primary_since; // same primary at least back through this epoch.