#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"
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;
} 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) {
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())
case CEPH_MSG_OSD_MAP:
handle_osd_map(static_cast<MOSDMap*>(m));
break;
+ case MSG_MON_GET_PURGED_SNAPS_REPLY:
+ handle_get_purged_snaps_reply(static_cast<MMonGetPurgedSnapsReply*>(m));
+ break;
// osd
case MSG_OSD_SCRUB: