From: Sage Weil Date: Mon, 10 Jun 2019 15:13:49 +0000 (-0500) Subject: osd: sync old purged_snaps on startup after upgrade or osd creation X-Git-Tag: v15.1.0~2308^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=81f7edc6bda47fce626abfc861b268c61c6a26bd;p=ceph.git osd: sync old purged_snaps on startup after upgrade or osd creation This path only triggers after an upgrade or osd creation, when purged_snaps_last < current_epoch. When that happens, we slurp down the old purged snaps so that we have a full history recorded locally. Signed-off-by: Sage Weil --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index e316c1fc2f4..ce7b39768bf 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -124,6 +124,9 @@ #include "messages/MOSDPGPushReply.h" #include "messages/MOSDPGPull.h" +#include "messages/MMonGetPurgedSnaps.h" +#include "messages/MMonGetPurgedSnapsReply.h" + #include "common/perf_counters.h" #include "common/Timer.h" #include "common/LogClient.h" @@ -5420,6 +5423,8 @@ void OSD::_preboot(epoch_t oldest, epoch_t newest) heartbeat(); } + const auto& monmap = monc->monmap; + // if our map within recent history, try to add ourselves to the osdmap. if (osdmap->get_epoch() == 0) { derr << "waiting for initial osdmap" << dendl; @@ -5441,6 +5446,11 @@ void OSD::_preboot(epoch_t oldest, epoch_t newest) } else if (service.need_fullness_update()) { derr << "osdmap fullness state needs update" << dendl; send_full_update(); + } else if (monmap.min_mon_release >= ceph_release_t::octopus && + superblock.purged_snaps_last < superblock.current_epoch) { + dout(10) << __func__ << " purged_snaps_last " << superblock.purged_snaps_last + << " < newest_map " << superblock.current_epoch << dendl; + _get_purged_snaps(); } else if (osdmap->get_epoch() >= oldest - 1 && osdmap->get_epoch() + cct->_conf->osd_map_message_max > newest) { @@ -5474,6 +5484,45 @@ void OSD::_preboot(epoch_t oldest, epoch_t newest) osdmap_subscribe(oldest - 1, true); } +void OSD::_get_purged_snaps() +{ + // NOTE: this is a naive, stateless implementaiton. it may send multiple + // overlapping requests to the mon, which will be somewhat inefficient, but + // it should be reliable. + dout(10) << __func__ << " purged_snaps_last " << superblock.purged_snaps_last + << ", newest_map " << superblock.current_epoch << dendl; + MMonGetPurgedSnaps *m = new MMonGetPurgedSnaps( + superblock.purged_snaps_last + 1, + superblock.current_epoch + 1); + monc->send_mon_message(m); +} + +void OSD::handle_get_purged_snaps_reply(MMonGetPurgedSnapsReply *m) +{ + dout(10) << __func__ << " " << *m << dendl; + ObjectStore::Transaction t; + if (!is_preboot() || + m->last < superblock.purged_snaps_last) { + goto out; + } + SnapMapper::record_purged_snaps(cct, store, service.meta_ch, + make_snapmapper_oid(), &t, + m->purged_snaps); + superblock.purged_snaps_last = m->last; + write_superblock(t); + store->queue_transaction( + service.meta_ch, + std::move(t)); + service.publish_superblock(superblock); + if (m->last < superblock.current_epoch) { + _get_purged_snaps(); + } else { + start_boot(); + } +out: + m->put(); +} + void OSD::send_full_update() { if (!service.need_fullness_update()) @@ -6894,6 +6943,9 @@ void OSD::_dispatch(Message *m) case CEPH_MSG_OSD_MAP: handle_osd_map(static_cast(m)); break; + case MSG_MON_GET_PURGED_SNAPS_REPLY: + handle_get_purged_snaps_reply(static_cast(m)); + break; // osd case MSG_OSD_SCRUB: diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 3045abea831..fdf5633ddbc 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -101,6 +101,7 @@ class MOSDPGNotify; class MOSDPGInfo; class MOSDPGRemove; class MOSDForceRecovery; +class MMonGetPurgedSnapsReply; class OSD; @@ -1815,6 +1816,8 @@ protected: void _preboot(epoch_t oldest, epoch_t newest); void _send_boot(); void _collect_metadata(map *pmeta); + void _get_purged_snaps(); + void handle_get_purged_snaps_reply(MMonGetPurgedSnapsReply *r); void start_waiting_for_healthy(); bool _is_healthy();