--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "PaxosServiceMessage.h"
+#include "include/types.h"
+
+class MMonGetPurgedSnaps : public PaxosServiceMessage {
+public:
+ epoch_t start, last;
+
+ MMonGetPurgedSnaps(epoch_t s=0, epoch_t l=0)
+ : PaxosServiceMessage{MSG_MON_GET_PURGED_SNAPS, 0},
+ start(s),
+ last(l) {}
+private:
+ ~MMonGetPurgedSnaps() override {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "mon_get_purged_snaps";
+ }
+ void print(std::ostream& out) const override {
+ out << "mon_get_purged_snaps([" << start << "," << last << "])";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(start, payload);
+ encode(last, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(start, p);
+ decode(last, p);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "PaxosServiceMessage.h"
+#include "osd/osd_types.h"
+#include "include/types.h"
+
+class MMonGetPurgedSnapsReply : public PaxosServiceMessage {
+public:
+ epoch_t start, last;
+ map<epoch_t,mempool::osdmap::map<int64_t,snap_interval_set_t>> purged_snaps;
+
+ MMonGetPurgedSnapsReply(epoch_t s=0, epoch_t l=0)
+ : PaxosServiceMessage{MSG_MON_GET_PURGED_SNAPS_REPLY, 0},
+ start(s),
+ last(l) {}
+private:
+ ~MMonGetPurgedSnapsReply() override {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "mon_get_purged_snaps_reply";
+ }
+ void print(std::ostream& out) const override {
+ out << "mon_get_purged_snaps_reply([" << start << "," << last << "])";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(start, payload);
+ encode(last, payload);
+ encode(purged_snaps, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(start, p);
+ decode(last, p);
+ decode(purged_snaps, p);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
case MSG_OSD_PGTEMP:
case MSG_OSD_PG_CREATED:
case MSG_REMOVE_SNAPS:
+ case MSG_MON_GET_PURGED_SNAPS:
case MSG_OSD_PG_READY_TO_MERGE:
paxos_service[PAXOS_OSDMAP]->dispatch(op);
return;
#include "messages/MRemoveSnaps.h"
#include "messages/MOSDScrub.h"
#include "messages/MRoute.h"
+#include "messages/MMonGetPurgedSnaps.h"
+#include "messages/MMonGetPurgedSnapsReply.h"
#include "common/TextTable.h"
#include "common/Timer.h"
case MSG_REMOVE_SNAPS:
return preprocess_remove_snaps(op);
+ case MSG_MON_GET_PURGED_SNAPS:
+ return preprocess_get_purged_snaps(op);
+
default:
ceph_abort();
return true;
return true;
}
+bool OSDMonitor::preprocess_get_purged_snaps(MonOpRequestRef op)
+{
+ op->mark_osdmon_event(__func__);
+ const MMonGetPurgedSnaps *m = static_cast<MMonGetPurgedSnaps*>(op->get_req());
+ dout(7) << __func__ << " " << *m << dendl;
+
+ map<epoch_t,mempool::osdmap::map<int64_t,snap_interval_set_t>> r;
+
+ string k = make_purged_snap_epoch_key(m->start);
+ auto it = mon->store->get_iterator(OSD_SNAP_PREFIX);
+ it->upper_bound(k);
+ unsigned long epoch = m->last;
+ while (it->valid()) {
+ if (it->key().find("purged_epoch_") != 0) {
+ break;
+ }
+ string k = it->key();
+ int n = sscanf(k.c_str(), "purged_epoch_%lx", &epoch);
+ if (n != 1) {
+ derr << __func__ << " unable to parse key '" << it->key() << "'" << dendl;
+ } else if (epoch > m->last) {
+ break;
+ } else {
+ bufferlist bl = it->value();
+ auto p = bl.cbegin();
+ auto &v = r[epoch];
+ try {
+ ceph::decode(v, p);
+ } catch (buffer::error& e) {
+ derr << __func__ << " unable to parse value for key '" << it->key()
+ << "': \n";
+ bl.hexdump(*_dout);
+ *_dout << dendl;
+ }
+ n += 4 + v.size() * 16;
+ }
+ if (n > 1048576) {
+ // impose a semi-arbitrary limit to message size
+ break;
+ }
+ it->next();
+ }
+
+ auto reply = make_message<MMonGetPurgedSnapsReply>(m->start, epoch);
+ reply->purged_snaps.swap(r);
+ mon->send_reply(op, reply.detach());
+
+ return true;
+}
+
// osd beacon
bool OSDMonitor::preprocess_beacon(MonOpRequestRef op)
{
bool preprocess_remove_snaps(MonOpRequestRef op);
bool prepare_remove_snaps(MonOpRequestRef op);
+ bool preprocess_get_purged_snaps(MonOpRequestRef op);
+
int load_metadata(int osd, map<string, string>& m, ostream *err);
void count_metadata(const string& field, Formatter *f);
#include "messages/MOSDRepOpReply.h"
#include "messages/MOSDMap.h"
#include "messages/MMonGetOSDMap.h"
+#include "messages/MMonGetPurgedSnaps.h"
+#include "messages/MMonGetPurgedSnapsReply.h"
#include "messages/MOSDPGCreated.h"
#include "messages/MOSDPGNotify.h"
case CEPH_MSG_MON_GET_OSDMAP:
m = make_message<MMonGetOSDMap>();
break;
+ case MSG_MON_GET_PURGED_SNAPS:
+ m = make_message<MMonGetPurgedSnaps>();
+ break;
+ case MSG_MON_GET_PURGED_SNAPS_REPLY:
+ m = make_message<MMonGetPurgedSnapsReply>();
+ break;
case CEPH_MSG_MON_GET_VERSION:
m = make_message<MMonGetVersion>();
break;
#define MSG_CONFIG 62
#define MSG_GET_CONFIG 63
+#define MSG_MON_GET_PURGED_SNAPS 76
+#define MSG_MON_GET_PURGED_SNAPS_REPLY 77
// osd internal
#define MSG_OSD_PING 70