From: Sage Weil Date: Mon, 16 Oct 2017 03:03:11 +0000 (-0500) Subject: mon/OSDMonitor: convert removed_snaps on first mimic map X-Git-Tag: v13.0.2~844^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fd6a59ebf45a397e9530b9350ee46db99e70e5f8;p=ceph.git mon/OSDMonitor: convert removed_snaps on first mimic map On the first mimic map, consider previously removed_snaps to be removed in that epoch (since we don't easily know when it happened). Signed-off-by: Sage Weil --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 4c214ea29b3dc..c441a02f6123b 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -1127,6 +1127,70 @@ void OSDMonitor::encode_pending(MonitorDBStore::TransactionRef t) << "required " << ceph_release_name(mv); pending_inc.new_require_min_compat_client = mv; } + + // upgrade to mimic? + if (osdmap.require_osd_release < CEPH_RELEASE_MIMIC && + tmp.require_osd_release >= CEPH_RELEASE_MIMIC) { + dout(10) << __func__ << " first mimic epoch" << dendl; + // record this epoch as the deletion for all legacy removed_snaps + for (auto& p : tmp.get_pools()) { + // update every pool + if (pending_inc.new_pools.count(p.first) == 0) { + pending_inc.new_pools[p.first] = p.second; + } + auto& pi = pending_inc.new_pools[p.first]; + if (pi.snap_seq == 0) { + // no snaps on this pool + continue; + } + if ((pi.flags & (pg_pool_t::FLAG_SELFMANAGED_SNAPS | + pg_pool_t::FLAG_POOL_SNAPS)) == 0) { + if (!pi.removed_snaps.empty()) { + pi.flags |= pg_pool_t::FLAG_SELFMANAGED_SNAPS; + } else { + pi.flags |= pg_pool_t::FLAG_POOL_SNAPS; + } + } + + // Make all previously removed snaps appear to be removed in this + // epoch. this populates removed_snaps_queue. The OSD will subtract + // off its purged_snaps, as before, and this set will shrink over the + // following epochs as the purged snaps are reported back through the + // mgr. + OSDMap::snap_interval_set_t removed; + if (!p.second.removed_snaps.empty()) { + // different flavor of interval_set :( + for (auto q = p.second.removed_snaps.begin(); + q != p.second.removed_snaps.end(); + ++q) { + removed.insert(q.get_start(), q.get_len()); + } + } else { + for (snapid_t s = 1; s <= pi.get_snap_seq(); s = s + 1) { + if (pi.snaps.count(s) == 0) { + removed.insert(s); + } + } + } + pending_inc.new_removed_snaps[p.first].union_of(removed); + + dout(10) << __func__ << " converting pool " << p.first + << " with " << p.second.removed_snaps.size() + << " legacy removed_snaps" << dendl; + string k = make_snap_epoch_key(p.first, pending_inc.epoch); + bufferlist v; + ::encode(p.second.removed_snaps, v); + t->put(OSD_SNAP_PREFIX, k, v); + for (auto q = p.second.removed_snaps.begin(); + q != p.second.removed_snaps.end(); + ++q) { + bufferlist v; + string k = make_snap_key_value(p.first, q.get_start(), + q.get_len(), pending_inc.epoch, &v); + t->put(OSD_SNAP_PREFIX, k, v); + } + } + } } // tell me about it diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 5adcfcf4e27eb..a2cfc99cecdf8 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -354,7 +354,8 @@ PG::PG(OSDService *o, OSDMapRef curmap, peer_features(CEPH_FEATURES_SUPPORTED_DEFAULT), acting_features(CEPH_FEATURES_SUPPORTED_DEFAULT), upacting_features(CEPH_FEATURES_SUPPORTED_DEFAULT), - last_epoch(0) + last_epoch(0), + last_require_osd_release(curmap->require_osd_release) { #ifdef PG_DEBUG_REFS osd->add_pgid(p, this); @@ -5955,6 +5956,7 @@ void PG::handle_advance_map( on_pool_change(); update_store_with_options(); } + last_require_osd_release = osdmap->require_osd_release; } void PG::handle_activate_map(RecoveryCtx *rctx) @@ -7317,14 +7319,28 @@ boost::statechart::result PG::RecoveryState::Active::react(const AdvMap& advmap) decltype(pg->snap_trimq) added, overlap; added.insert(j.first, j.second); overlap.intersection_of(pg->snap_trimq, added); - lderr(pg->cct) << __func__ << " removed_snaps already contains " - << overlap << dendl; - bad = true; + if (pg->last_require_osd_release < CEPH_RELEASE_MIMIC) { + lderr(pg->cct) << __func__ << " removed_snaps already contains " + << overlap << ", but this is the first mimic+ osdmap," + << " so it's expected" << dendl; + } else { + lderr(pg->cct) << __func__ << " removed_snaps already contains " + << overlap << dendl; + bad = true; + } pg->snap_trimq.union_of(added); } else { pg->snap_trimq.insert(j.first, j.second); } } + if (pg->last_require_osd_release < CEPH_RELEASE_MIMIC) { + // at upgrade, we report *all* previously removed snaps as removed in + // the first mimic epoch. remove the ones we previously divined were + // removed (and subsequently purged) from the trimq. + lderr(pg->cct) << __func__ << " first mimic map, filtering purged_snaps" + << " from new removed_snaps" << dendl; + pg->snap_trimq.subtract(pg->info.purged_snaps); + } ldout(pg->cct,10) << __func__ << " new removed_snaps " << i->second << ", snap_trimq now " << pg->snap_trimq << dendl; assert(!bad || !pg->cct->_conf->osd_debug_verify_cached_snaps); diff --git a/src/osd/PG.h b/src/osd/PG.h index 73632fa9654b4..c260a9b444ebd 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -2630,6 +2630,9 @@ protected: epoch_t last_epoch; + /// most recently consumed osdmap's require_osd_version + unsigned last_require_osd_release = 0; + protected: void reset_min_peer_features() { peer_features = CEPH_FEATURES_SUPPORTED_DEFAULT;