summaryrefslogtreecommitdiffstats
path: root/src/messages
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages')
-rw-r--r--src/messages/MAuth.h62
-rw-r--r--src/messages/MAuthReply.h69
-rw-r--r--src/messages/MBackfillReserve.h180
-rw-r--r--src/messages/MCacheExpire.h113
-rw-r--r--src/messages/MClientCapRelease.h69
-rw-r--r--src/messages/MClientCaps.h336
-rw-r--r--src/messages/MClientLease.h93
-rw-r--r--src/messages/MClientQuota.h52
-rw-r--r--src/messages/MClientReclaim.h64
-rw-r--r--src/messages/MClientReclaimReply.h69
-rw-r--r--src/messages/MClientReconnect.h174
-rw-r--r--src/messages/MClientReply.h361
-rw-r--r--src/messages/MClientRequest.h289
-rw-r--r--src/messages/MClientRequestForward.h70
-rw-r--r--src/messages/MClientSession.h92
-rw-r--r--src/messages/MClientSnap.h70
-rw-r--r--src/messages/MCommand.h61
-rw-r--r--src/messages/MCommandReply.h60
-rw-r--r--src/messages/MConfig.h40
-rw-r--r--src/messages/MDataPing.h92
-rw-r--r--src/messages/MDentryLink.h75
-rw-r--r--src/messages/MDentryUnlink.h67
-rw-r--r--src/messages/MDirUpdate.h93
-rw-r--r--src/messages/MDiscover.h97
-rw-r--r--src/messages/MDiscoverReply.h212
-rw-r--r--src/messages/MExportCaps.h63
-rw-r--r--src/messages/MExportCapsAck.h54
-rw-r--r--src/messages/MExportDir.h65
-rw-r--r--src/messages/MExportDirAck.h57
-rw-r--r--src/messages/MExportDirCancel.h54
-rw-r--r--src/messages/MExportDirDiscover.h69
-rw-r--r--src/messages/MExportDirDiscoverAck.h64
-rw-r--r--src/messages/MExportDirFinish.h58
-rw-r--r--src/messages/MExportDirNotify.h84
-rw-r--r--src/messages/MExportDirNotifyAck.h59
-rw-r--r--src/messages/MExportDirPrep.h90
-rw-r--r--src/messages/MExportDirPrepAck.h59
-rw-r--r--src/messages/MFSMap.h64
-rw-r--r--src/messages/MFSMapUser.h62
-rw-r--r--src/messages/MForward.h156
-rw-r--r--src/messages/MGatherCaps.h37
-rw-r--r--src/messages/MGenericMessage.h42
-rw-r--r--src/messages/MGetConfig.h50
-rw-r--r--src/messages/MGetPoolStats.h59
-rw-r--r--src/messages/MGetPoolStatsReply.h72
-rw-r--r--src/messages/MHeartbeat.h65
-rw-r--r--src/messages/MInodeFileCaps.h61
-rw-r--r--src/messages/MLock.h103
-rw-r--r--src/messages/MLog.h61
-rw-r--r--src/messages/MLogAck.h53
-rw-r--r--src/messages/MMDSBeacon.h307
-rw-r--r--src/messages/MMDSCacheRejoin.h372
-rw-r--r--src/messages/MMDSFindIno.h51
-rw-r--r--src/messages/MMDSFindInoReply.h51
-rw-r--r--src/messages/MMDSFragmentNotify.h75
-rw-r--r--src/messages/MMDSFragmentNotifyAck.h60
-rw-r--r--src/messages/MMDSLoadTargets.h62
-rw-r--r--src/messages/MMDSMap.h79
-rw-r--r--src/messages/MMDSOpenIno.h55
-rw-r--r--src/messages/MMDSOpenInoReply.h60
-rw-r--r--src/messages/MMDSResolve.h129
-rw-r--r--src/messages/MMDSResolveAck.h63
-rw-r--r--src/messages/MMDSSlaveRequest.h220
-rw-r--r--src/messages/MMDSSnapUpdate.h63
-rw-r--r--src/messages/MMDSTableRequest.h68
-rw-r--r--src/messages/MMgrBeacon.h185
-rw-r--r--src/messages/MMgrClose.h48
-rw-r--r--src/messages/MMgrConfigure.h72
-rw-r--r--src/messages/MMgrDigest.h56
-rw-r--r--src/messages/MMgrMap.h58
-rw-r--r--src/messages/MMgrOpen.h95
-rw-r--r--src/messages/MMgrReport.h186
-rw-r--r--src/messages/MMonCommand.h81
-rw-r--r--src/messages/MMonCommandAck.h79
-rw-r--r--src/messages/MMonElection.h132
-rw-r--r--src/messages/MMonGetMap.h37
-rw-r--r--src/messages/MMonGetOSDMap.h93
-rw-r--r--src/messages/MMonGetVersion.h61
-rw-r--r--src/messages/MMonGetVersionReply.h67
-rw-r--r--src/messages/MMonGlobalID.h47
-rw-r--r--src/messages/MMonHealth.h65
-rw-r--r--src/messages/MMonHealthChecks.h50
-rw-r--r--src/messages/MMonJoin.h79
-rw-r--r--src/messages/MMonMap.h58
-rw-r--r--src/messages/MMonMetadata.h55
-rw-r--r--src/messages/MMonMgrReport.h87
-rw-r--r--src/messages/MMonPaxos.h133
-rw-r--r--src/messages/MMonProbe.h142
-rw-r--r--src/messages/MMonQuorumService.h70
-rw-r--r--src/messages/MMonScrub.h90
-rw-r--r--src/messages/MMonSubscribe.h105
-rw-r--r--src/messages/MMonSubscribeAck.h53
-rw-r--r--src/messages/MMonSync.h114
-rw-r--r--src/messages/MNop.h57
-rw-r--r--src/messages/MOSDAlive.h52
-rw-r--r--src/messages/MOSDBackoff.h84
-rw-r--r--src/messages/MOSDBeacon.h41
-rw-r--r--src/messages/MOSDBoot.h120
-rw-r--r--src/messages/MOSDECSubOpRead.h82
-rw-r--r--src/messages/MOSDECSubOpReadReply.h82
-rw-r--r--src/messages/MOSDECSubOpWrite.h91
-rw-r--r--src/messages/MOSDECSubOpWriteReply.h82
-rw-r--r--src/messages/MOSDFailure.h128
-rw-r--r--src/messages/MOSDFastDispatchOp.h23
-rw-r--r--src/messages/MOSDForceRecovery.h112
-rw-r--r--src/messages/MOSDFull.h53
-rw-r--r--src/messages/MOSDMap.h173
-rw-r--r--src/messages/MOSDMarkMeDown.h103
-rw-r--r--src/messages/MOSDOp.h598
-rw-r--r--src/messages/MOSDOpReply.h340
-rw-r--r--src/messages/MOSDPGBackfill.h114
-rw-r--r--src/messages/MOSDPGBackfillRemove.h78
-rw-r--r--src/messages/MOSDPGCreate.h72
-rw-r--r--src/messages/MOSDPGCreate2.h50
-rw-r--r--src/messages/MOSDPGCreated.h35
-rw-r--r--src/messages/MOSDPGInfo.h75
-rw-r--r--src/messages/MOSDPGLog.h124
-rw-r--r--src/messages/MOSDPGNotify.h87
-rw-r--r--src/messages/MOSDPGPull.h106
-rw-r--r--src/messages/MOSDPGPush.h112
-rw-r--r--src/messages/MOSDPGPushReply.h98
-rw-r--r--src/messages/MOSDPGQuery.h80
-rw-r--r--src/messages/MOSDPGReadyToMerge.h58
-rw-r--r--src/messages/MOSDPGRecoveryDelete.h93
-rw-r--r--src/messages/MOSDPGRecoveryDeleteReply.h64
-rw-r--r--src/messages/MOSDPGRemove.h71
-rw-r--r--src/messages/MOSDPGScan.h117
-rw-r--r--src/messages/MOSDPGTemp.h67
-rw-r--r--src/messages/MOSDPGTrim.h79
-rw-r--r--src/messages/MOSDPGUpdateLogMissing.h123
-rw-r--r--src/messages/MOSDPGUpdateLogMissingReply.h117
-rw-r--r--src/messages/MOSDPeeringOp.h28
-rw-r--r--src/messages/MOSDPing.h130
-rw-r--r--src/messages/MOSDRepOp.h180
-rw-r--r--src/messages/MOSDRepOpReply.h161
-rw-r--r--src/messages/MOSDRepScrub.h143
-rw-r--r--src/messages/MOSDRepScrubMap.h83
-rw-r--r--src/messages/MOSDScrub.h78
-rw-r--r--src/messages/MOSDScrub2.h59
-rw-r--r--src/messages/MOSDScrubReserve.h97
-rw-r--r--src/messages/MPGStats.h78
-rw-r--r--src/messages/MPGStatsAck.h47
-rw-r--r--src/messages/MPing.h35
-rw-r--r--src/messages/MPoolOp.h96
-rw-r--r--src/messages/MPoolOpReply.h83
-rw-r--r--src/messages/MRecoveryReserve.h130
-rw-r--r--src/messages/MRemoveSnaps.h55
-rw-r--r--src/messages/MRoute.h88
-rw-r--r--src/messages/MServiceMap.h37
-rw-r--r--src/messages/MStatfs.h69
-rw-r--r--src/messages/MStatfsReply.h47
-rw-r--r--src/messages/MTimeCheck.h90
-rw-r--r--src/messages/MTimeCheck2.h88
-rw-r--r--src/messages/MWatchNotify.h96
-rw-r--r--src/messages/PaxosServiceMessage.h56
155 files changed, 14829 insertions, 0 deletions
diff --git a/src/messages/MAuth.h b/src/messages/MAuth.h
new file mode 100644
index 00000000..0075e0b9
--- /dev/null
+++ b/src/messages/MAuth.h
@@ -0,0 +1,62 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MAUTH_H
+#define CEPH_MAUTH_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MAuth : public MessageInstance<MAuth, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ __u32 protocol;
+ bufferlist auth_payload;
+ epoch_t monmap_epoch;
+
+ /* if protocol == 0, then auth_payload is a set<__u32> listing protocols the client supports */
+
+ MAuth() : MessageInstance(CEPH_MSG_AUTH, 0), protocol(0), monmap_epoch(0) { }
+private:
+ ~MAuth() override {}
+
+public:
+ std::string_view get_type_name() const override { return "auth"; }
+ void print(ostream& out) const override {
+ out << "auth(proto " << protocol << " " << auth_payload.length() << " bytes"
+ << " epoch " << monmap_epoch << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::encode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(protocol, p);
+ decode(auth_payload, p);
+ if (!p.end())
+ decode(monmap_epoch, p);
+ else
+ monmap_epoch = 0;
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(protocol, payload);
+ encode(auth_payload, payload);
+ encode(monmap_epoch, payload);
+ }
+ bufferlist& get_auth_payload() { return auth_payload; }
+};
+
+#endif
diff --git a/src/messages/MAuthReply.h b/src/messages/MAuthReply.h
new file mode 100644
index 00000000..be3368e6
--- /dev/null
+++ b/src/messages/MAuthReply.h
@@ -0,0 +1,69 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MAUTHREPLY_H
+#define CEPH_MAUTHREPLY_H
+
+#include "msg/Message.h"
+#include "common/errno.h"
+
+class MAuthReply : public MessageInstance<MAuthReply> {
+public:
+ friend factory;
+
+ __u32 protocol;
+ errorcode32_t result;
+ uint64_t global_id; // if zero, meaningless
+ string result_msg;
+ bufferlist result_bl;
+
+ MAuthReply() : MessageInstance(CEPH_MSG_AUTH_REPLY), protocol(0), result(0), global_id(0) {}
+ MAuthReply(__u32 p, bufferlist *bl = NULL, int r = 0, uint64_t gid=0, const char *msg = "") :
+ MessageInstance(CEPH_MSG_AUTH_REPLY),
+ protocol(p), result(r), global_id(gid),
+ result_msg(msg) {
+ if (bl)
+ result_bl = *bl;
+ }
+private:
+ ~MAuthReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "auth_reply"; }
+ void print(ostream& o) const override {
+ o << "auth_reply(proto " << protocol << " " << result << " " << cpp_strerror(result);
+ if (result_msg.length())
+ o << ": " << result_msg;
+ o << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(protocol, p);
+ decode(result, p);
+ decode(global_id, p);
+ decode(result_bl, p);
+ decode(result_msg, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(protocol, payload);
+ encode(result, payload);
+ encode(global_id, payload);
+ encode(result_bl, payload);
+ encode(result_msg, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MBackfillReserve.h b/src/messages/MBackfillReserve.h
new file mode 100644
index 00000000..ac813293
--- /dev/null
+++ b/src/messages/MBackfillReserve.h
@@ -0,0 +1,180 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MBACKFILL_H
+#define CEPH_MBACKFILL_H
+
+#include "msg/Message.h"
+#include "messages/MOSDPeeringOp.h"
+
+class MBackfillReserve : public MessageInstance<MBackfillReserve, MOSDPeeringOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 5;
+ static constexpr int COMPAT_VERSION = 4;
+public:
+ spg_t pgid;
+ epoch_t query_epoch;
+ enum {
+ REQUEST = 0, // primary->replica: please reserve a slot
+ GRANT = 1, // replica->primary: ok, i reserved it
+ REJECT_TOOFULL = 2, // replica->primary: too full, sorry, try again later (*)
+ RELEASE = 3, // primary->replcia: release the slot i reserved before
+ REVOKE_TOOFULL = 4, // replica->primary: too full, stop backfilling
+ REVOKE = 5, // replica->primary: i'm taking back the slot i gave you
+ // (*) NOTE: prior to luminous, REJECT was overloaded to also mean release
+ };
+ uint32_t type;
+ uint32_t priority;
+ int64_t primary_num_bytes;
+ int64_t shard_num_bytes;
+
+ spg_t get_spg() const {
+ return pgid;
+ }
+ epoch_t get_map_epoch() const {
+ return query_epoch;
+ }
+ epoch_t get_min_epoch() const {
+ return query_epoch;
+ }
+
+ PGPeeringEvent *get_event() override {
+ switch (type) {
+ case REQUEST:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RequestBackfillPrio(priority, primary_num_bytes, shard_num_bytes));
+ case GRANT:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RemoteBackfillReserved());
+ case REJECT_TOOFULL:
+ // NOTE: this is replica -> primary "i reject your request"
+ // and also primary -> replica "cancel my previously-granted request"
+ // (for older peers)
+ // and also replica -> primary "i revoke your reservation"
+ // (for older peers)
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RemoteReservationRejectedTooFull());
+ case RELEASE:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RemoteReservationCanceled());
+ case REVOKE_TOOFULL:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RemoteReservationRevokedTooFull());
+ case REVOKE:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RemoteReservationRevoked());
+ default:
+ ceph_abort();
+ }
+ }
+
+ MBackfillReserve()
+ : MessageInstance(MSG_OSD_BACKFILL_RESERVE, HEAD_VERSION, COMPAT_VERSION),
+ query_epoch(0), type(-1), priority(-1), primary_num_bytes(0),
+ shard_num_bytes(0) {}
+ MBackfillReserve(int type,
+ spg_t pgid,
+ epoch_t query_epoch, unsigned prio = -1,
+ int64_t primary_num_bytes = 0,
+ int64_t shard_num_bytes = 0)
+ : MessageInstance(MSG_OSD_BACKFILL_RESERVE, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid), query_epoch(query_epoch),
+ type(type), priority(prio), primary_num_bytes(primary_num_bytes),
+ shard_num_bytes(shard_num_bytes) {}
+
+ std::string_view get_type_name() const override {
+ return "MBackfillReserve";
+ }
+
+ void inner_print(ostream& out) const override {
+ switch (type) {
+ case REQUEST:
+ out << "REQUEST";
+ break;
+ case GRANT:
+ out << "GRANT";
+ break;
+ case REJECT_TOOFULL:
+ out << "REJECT_TOOFULL";
+ break;
+ case RELEASE:
+ out << "RELEASE";
+ break;
+ case REVOKE_TOOFULL:
+ out << "REVOKE_TOOFULL";
+ break;
+ case REVOKE:
+ out << "REVOKE";
+ break;
+ }
+ if (type == REQUEST) out << " prio: " << priority;
+ return;
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(query_epoch, p);
+ decode(type, p);
+ decode(priority, p);
+ decode(pgid.shard, p);
+ if (header.version >= 5) {
+ decode(primary_num_bytes, p);
+ decode(shard_num_bytes, p);
+ } else {
+ primary_num_bytes = 0;
+ shard_num_bytes = 0;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if (!HAVE_FEATURE(features, RECOVERY_RESERVATION_2)) {
+ header.version = 3;
+ header.compat_version = 3;
+ encode(pgid.pgid, payload);
+ encode(query_epoch, payload);
+ encode((type == RELEASE || type == REVOKE_TOOFULL || type == REVOKE) ?
+ REJECT_TOOFULL : type, payload);
+ encode(priority, payload);
+ encode(pgid.shard, payload);
+ return;
+ }
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(pgid.pgid, payload);
+ encode(query_epoch, payload);
+ encode(type, payload);
+ encode(priority, payload);
+ encode(pgid.shard, payload);
+ encode(primary_num_bytes, payload);
+ encode(shard_num_bytes, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MCacheExpire.h b/src/messages/MCacheExpire.h
new file mode 100644
index 00000000..d54bcaf5
--- /dev/null
+++ b/src/messages/MCacheExpire.h
@@ -0,0 +1,113 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCACHEEXPIRE_H
+#define CEPH_MCACHEEXPIRE_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+
+#include "mds/mdstypes.h"
+
+class MCacheExpire : public MessageInstance<MCacheExpire> {
+public:
+ friend factory;
+private:
+ __s32 from;
+
+public:
+ /*
+ group things by realm (auth delgation root), since that's how auth is determined.
+ that makes it less work to process when exports are in progress.
+ */
+ struct realm {
+ map<vinodeno_t, uint32_t> inodes;
+ map<dirfrag_t, uint32_t> dirs;
+ map<dirfrag_t, map<pair<string,snapid_t>,uint32_t> > dentries;
+
+ void merge(const realm& o) {
+ inodes.insert(o.inodes.begin(), o.inodes.end());
+ dirs.insert(o.dirs.begin(), o.dirs.end());
+ for (const auto &p : o.dentries) {
+ auto em = dentries.emplace(std::piecewise_construct, std::forward_as_tuple(p.first), std::forward_as_tuple(p.second));
+ if (!em.second) {
+ em.first->second.insert(p.second.begin(), p.second.end());
+ }
+ }
+ }
+
+ void encode(bufferlist &bl) const {
+ using ceph::encode;
+ encode(inodes, bl);
+ encode(dirs, bl);
+ encode(dentries, bl);
+ }
+ void decode(bufferlist::const_iterator &bl) {
+ using ceph::decode;
+ decode(inodes, bl);
+ decode(dirs, bl);
+ decode(dentries, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(realm)
+
+ map<dirfrag_t, realm> realms;
+
+ int get_from() const { return from; }
+
+protected:
+ MCacheExpire() : MessageInstance(MSG_MDS_CACHEEXPIRE), from(-1) {}
+ MCacheExpire(int f) :
+ MessageInstance(MSG_MDS_CACHEEXPIRE),
+ from(f) { }
+ ~MCacheExpire() override {}
+
+public:
+ std::string_view get_type_name() const override { return "cache_expire";}
+
+ void add_inode(dirfrag_t r, vinodeno_t vino, unsigned nonce) {
+ realms[r].inodes[vino] = nonce;
+ }
+ void add_dir(dirfrag_t r, dirfrag_t df, unsigned nonce) {
+ realms[r].dirs[df] = nonce;
+ }
+ void add_dentry(dirfrag_t r, dirfrag_t df, std::string_view dn, snapid_t last, unsigned nonce) {
+ realms[r].dentries[df][pair<string,snapid_t>(dn,last)] = nonce;
+ }
+
+ void add_realm(dirfrag_t df, const realm& r) {
+ auto em = realms.emplace(std::piecewise_construct, std::forward_as_tuple(df), std::forward_as_tuple(r));
+ if (!em.second) {
+ em.first->second.merge(r);
+ }
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(from, p);
+ decode(realms, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(from, payload);
+ encode(realms, payload);
+ }
+};
+
+WRITE_CLASS_ENCODER(MCacheExpire::realm)
+
+#endif
diff --git a/src/messages/MClientCapRelease.h b/src/messages/MClientCapRelease.h
new file mode 100644
index 00000000..403169bd
--- /dev/null
+++ b/src/messages/MClientCapRelease.h
@@ -0,0 +1,69 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCLIENTCAPRELEASE_H
+#define CEPH_MCLIENTCAPRELEASE_H
+
+#include "msg/Message.h"
+
+
+class MClientCapRelease : public MessageInstance<MClientCapRelease> {
+public:
+ friend factory;
+
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+ public:
+
+ struct ceph_mds_cap_release head;
+ vector<ceph_mds_cap_item> caps;
+
+ // The message receiver must wait for this OSD epoch
+ // before actioning this cap release.
+ epoch_t osd_epoch_barrier;
+
+ MClientCapRelease() :
+ MessageInstance(CEPH_MSG_CLIENT_CAPRELEASE, HEAD_VERSION, COMPAT_VERSION),
+ osd_epoch_barrier(0)
+ {
+ memset(&head, 0, sizeof(head));
+ }
+private:
+ ~MClientCapRelease() override {}
+
+public:
+ std::string_view get_type_name() const override { return "client_cap_release";}
+ void print(ostream& out) const override {
+ out << "client_cap_release(" << caps.size() << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(head, p);
+ decode_nohead(head.num, caps, p);
+ if (header.version >= 2) {
+ decode(osd_epoch_barrier, p);
+ }
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ head.num = caps.size();
+ encode(head, payload);
+ encode_nohead(caps, payload);
+ encode(osd_epoch_barrier, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h
new file mode 100644
index 00000000..fa069f18
--- /dev/null
+++ b/src/messages/MClientCaps.h
@@ -0,0 +1,336 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCLIENTCAPS_H
+#define CEPH_MCLIENTCAPS_H
+
+#include "msg/Message.h"
+#include "mds/mdstypes.h"
+#include "include/ceph_features.h"
+
+class MClientCaps : public MessageInstance<MClientCaps> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 11;
+ static constexpr int COMPAT_VERSION = 1;
+
+ public:
+ static constexpr unsigned FLAG_SYNC = (1<<0);
+ static constexpr unsigned FLAG_NO_CAPSNAP = (1<<1); // unused
+ static constexpr unsigned FLAG_PENDING_CAPSNAP = (1<<2);
+
+ struct ceph_mds_caps_head head;
+
+ uint64_t size = 0;
+ uint64_t max_size = 0;
+ uint64_t truncate_size = 0;
+ uint64_t change_attr = 0;
+ uint32_t truncate_seq = 0;
+ utime_t mtime, atime, ctime, btime;
+ uint32_t time_warp_seq = 0;
+ int64_t nfiles = -1; // files in dir
+ int64_t nsubdirs = -1; // subdirs in dir
+
+ struct ceph_mds_cap_peer peer;
+
+ bufferlist snapbl;
+ bufferlist xattrbl;
+ bufferlist flockbl;
+ version_t inline_version = 0;
+ bufferlist inline_data;
+
+ // Receivers may not use their new caps until they have this OSD map
+ epoch_t osd_epoch_barrier = 0;
+ ceph_tid_t oldest_flush_tid = 0;
+ uint32_t caller_uid = 0;
+ uint32_t caller_gid = 0;
+
+ /* advisory CLIENT_CAPS_* flags to send to mds */
+ unsigned flags = 0;
+
+ int get_caps() const { return head.caps; }
+ int get_wanted() const { return head.wanted; }
+ int get_dirty() const { return head.dirty; }
+ ceph_seq_t get_seq() const { return head.seq; }
+ ceph_seq_t get_issue_seq() const { return head.issue_seq; }
+ ceph_seq_t get_mseq() const { return head.migrate_seq; }
+
+ inodeno_t get_ino() const { return inodeno_t(head.ino); }
+ inodeno_t get_realm() const { return inodeno_t(head.realm); }
+ uint64_t get_cap_id() const { return head.cap_id; }
+
+ uint64_t get_size() const { return size; }
+ uint64_t get_max_size() const { return max_size; }
+ __u32 get_truncate_seq() const { return truncate_seq; }
+ uint64_t get_truncate_size() const { return truncate_size; }
+ utime_t get_ctime() const { return ctime; }
+ utime_t get_btime() const { return btime; }
+ utime_t get_mtime() const { return mtime; }
+ utime_t get_atime() const { return atime; }
+ __u64 get_change_attr() const { return change_attr; }
+ __u32 get_time_warp_seq() const { return time_warp_seq; }
+ uint64_t get_nfiles() const { return nfiles; }
+ uint64_t get_nsubdirs() const { return nsubdirs; }
+ bool dirstat_is_valid() const { return nfiles != -1 || nsubdirs != -1; }
+
+ const file_layout_t& get_layout() const {
+ return layout;
+ }
+
+ void set_layout(const file_layout_t &l) {
+ layout = l;
+ }
+
+ int get_migrate_seq() const { return head.migrate_seq; }
+ int get_op() const { return head.op; }
+
+ uint64_t get_client_tid() const { return get_tid(); }
+ void set_client_tid(uint64_t s) { set_tid(s); }
+
+ snapid_t get_snap_follows() const { return snapid_t(head.snap_follows); }
+ void set_snap_follows(snapid_t s) { head.snap_follows = s; }
+
+ void set_caps(int c) { head.caps = c; }
+ void set_wanted(int w) { head.wanted = w; }
+
+ void set_max_size(uint64_t ms) { max_size = ms; }
+
+ void set_migrate_seq(unsigned m) { head.migrate_seq = m; }
+ void set_op(int o) { head.op = o; }
+
+ void set_size(loff_t s) { size = s; }
+ void set_mtime(const utime_t &t) { mtime = t; }
+ void set_ctime(const utime_t &t) { ctime = t; }
+ void set_atime(const utime_t &t) { atime = t; }
+
+ void set_cap_peer(uint64_t id, ceph_seq_t seq, ceph_seq_t mseq, int mds, int flags) {
+ peer.cap_id = id;
+ peer.seq = seq;
+ peer.mseq = mseq;
+ peer.mds = mds;
+ peer.flags = flags;
+ }
+
+ void set_oldest_flush_tid(ceph_tid_t tid) { oldest_flush_tid = tid; }
+ ceph_tid_t get_oldest_flush_tid() const { return oldest_flush_tid; }
+
+ void clear_dirty() { head.dirty = 0; }
+
+protected:
+ MClientCaps()
+ : MessageInstance(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION) {}
+ MClientCaps(int op,
+ inodeno_t ino,
+ inodeno_t realm,
+ uint64_t id,
+ long seq,
+ int caps,
+ int wanted,
+ int dirty,
+ int mseq,
+ epoch_t oeb)
+ : MessageInstance(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
+ osd_epoch_barrier(oeb) {
+ memset(&head, 0, sizeof(head));
+ head.op = op;
+ head.ino = ino;
+ head.realm = realm;
+ head.cap_id = id;
+ head.seq = seq;
+ head.caps = caps;
+ head.wanted = wanted;
+ head.dirty = dirty;
+ head.migrate_seq = mseq;
+ memset(&peer, 0, sizeof(peer));
+ }
+ MClientCaps(int op,
+ inodeno_t ino, inodeno_t realm,
+ uint64_t id, int mseq, epoch_t oeb)
+ : MessageInstance(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
+ osd_epoch_barrier(oeb) {
+ memset(&head, 0, sizeof(head));
+ head.op = op;
+ head.ino = ino;
+ head.realm = realm;
+ head.cap_id = id;
+ head.migrate_seq = mseq;
+ memset(&peer, 0, sizeof(peer));
+ }
+ ~MClientCaps() override {}
+
+private:
+ file_layout_t layout;
+
+public:
+ std::string_view get_type_name() const override { return "Cfcap";}
+ void print(ostream& out) const override {
+ out << "client_caps(" << ceph_cap_op_name(head.op)
+ << " ino " << inodeno_t(head.ino)
+ << " " << head.cap_id
+ << " seq " << head.seq;
+ if (get_tid())
+ out << " tid " << get_tid();
+ out << " caps=" << ccap_string(head.caps)
+ << " dirty=" << ccap_string(head.dirty)
+ << " wanted=" << ccap_string(head.wanted);
+ out << " follows " << snapid_t(head.snap_follows);
+ if (head.migrate_seq)
+ out << " mseq " << head.migrate_seq;
+
+ out << " size " << size << "/" << max_size;
+ if (truncate_seq)
+ out << " ts " << truncate_seq << "/" << truncate_size;
+ out << " mtime " << mtime;
+ if (time_warp_seq)
+ out << " tws " << time_warp_seq;
+
+ if (head.xattr_version)
+ out << " xattrs(v=" << head.xattr_version << " l=" << xattrbl.length() << ")";
+
+ out << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(head, p);
+ ceph_mds_caps_body_legacy body;
+ decode(body, p);
+ if (head.op == CEPH_CAP_OP_EXPORT) {
+ peer = body.peer;
+ } else {
+ size = body.size;
+ max_size = body.max_size;
+ truncate_size = body.truncate_size;
+ truncate_seq = body.truncate_seq;
+ mtime = utime_t(body.mtime);
+ atime = utime_t(body.atime);
+ ctime = utime_t(body.ctime);
+ layout.from_legacy(body.layout);
+ time_warp_seq = body.time_warp_seq;
+ }
+ decode_nohead(head.snap_trace_len, snapbl, p);
+
+ ceph_assert(middle.length() == head.xattr_len);
+ if (head.xattr_len)
+ xattrbl = middle;
+
+ // conditionally decode flock metadata
+ if (header.version >= 2)
+ decode(flockbl, p);
+
+ if (header.version >= 3) {
+ if (head.op == CEPH_CAP_OP_IMPORT)
+ decode(peer, p);
+ }
+
+ if (header.version >= 4) {
+ decode(inline_version, p);
+ decode(inline_data, p);
+ } else {
+ inline_version = CEPH_INLINE_NONE;
+ }
+
+ if (header.version >= 5) {
+ decode(osd_epoch_barrier, p);
+ }
+ if (header.version >= 6) {
+ decode(oldest_flush_tid, p);
+ }
+ if (header.version >= 7) {
+ decode(caller_uid, p);
+ decode(caller_gid, p);
+ }
+ if (header.version >= 8) {
+ decode(layout.pool_ns, p);
+ }
+ if (header.version >= 9) {
+ decode(btime, p);
+ decode(change_attr, p);
+ }
+ if (header.version >= 10) {
+ decode(flags, p);
+ }
+ if (header.version >= 11) {
+ decode(nfiles, p);
+ decode(nsubdirs, p);
+ }
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ header.version = HEAD_VERSION;
+ head.snap_trace_len = snapbl.length();
+ head.xattr_len = xattrbl.length();
+
+ encode(head, payload);
+ ceph_mds_caps_body_legacy body;
+ if (head.op == CEPH_CAP_OP_EXPORT) {
+ memset(&body, 0, sizeof(body));
+ body.peer = peer;
+ } else {
+ body.size = size;
+ body.max_size = max_size;
+ body.truncate_size = truncate_size;
+ body.truncate_seq = truncate_seq;
+ mtime.encode_timeval(&body.mtime);
+ atime.encode_timeval(&body.atime);
+ ctime.encode_timeval(&body.ctime);
+ layout.to_legacy(&body.layout);
+ body.time_warp_seq = time_warp_seq;
+ }
+ encode(body, payload);
+ encode_nohead(snapbl, payload);
+
+ middle = xattrbl;
+
+ // conditionally include flock metadata
+ if (features & CEPH_FEATURE_FLOCK) {
+ encode(flockbl, payload);
+ } else {
+ header.version = 1;
+ return;
+ }
+
+ if (features & CEPH_FEATURE_EXPORT_PEER) {
+ if (head.op == CEPH_CAP_OP_IMPORT)
+ encode(peer, payload);
+ } else {
+ header.version = 2;
+ return;
+ }
+
+ if (features & CEPH_FEATURE_MDS_INLINE_DATA) {
+ encode(inline_version, payload);
+ encode(inline_data, payload);
+ } else {
+ encode(inline_version, payload);
+ encode(bufferlist(), payload);
+ }
+
+ encode(osd_epoch_barrier, payload);
+ encode(oldest_flush_tid, payload);
+ encode(caller_uid, payload);
+ encode(caller_gid, payload);
+
+ encode(layout.pool_ns, payload);
+ encode(btime, payload);
+ encode(change_attr, payload);
+ encode(flags, payload);
+ encode(nfiles, payload);
+ encode(nsubdirs, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MClientLease.h b/src/messages/MClientLease.h
new file mode 100644
index 00000000..5c2bf84b
--- /dev/null
+++ b/src/messages/MClientLease.h
@@ -0,0 +1,93 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MCLIENTLEASE_H
+#define CEPH_MCLIENTLEASE_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+
+class MClientLease : public MessageInstance<MClientLease> {
+public:
+ friend factory;
+
+ struct ceph_mds_lease h;
+ std::string dname;
+
+ int get_action() const { return h.action; }
+ ceph_seq_t get_seq() const { return h.seq; }
+ int get_mask() const { return h.mask; }
+ inodeno_t get_ino() const { return inodeno_t(h.ino); }
+ snapid_t get_first() const { return snapid_t(h.first); }
+ snapid_t get_last() const { return snapid_t(h.last); }
+
+protected:
+ MClientLease() : MessageInstance(CEPH_MSG_CLIENT_LEASE) {}
+ MClientLease(const MClientLease& m) :
+ MessageInstance(CEPH_MSG_CLIENT_LEASE),
+ h(m.h),
+ dname(m.dname) {}
+ MClientLease(int ac, ceph_seq_t seq, int m, uint64_t i, uint64_t sf, uint64_t sl) :
+ MessageInstance(CEPH_MSG_CLIENT_LEASE) {
+ h.action = ac;
+ h.seq = seq;
+ h.mask = m;
+ h.ino = i;
+ h.first = sf;
+ h.last = sl;
+ h.duration_ms = 0;
+ }
+ MClientLease(int ac, ceph_seq_t seq, int m, uint64_t i, uint64_t sf, uint64_t sl, std::string_view d) :
+ MessageInstance(CEPH_MSG_CLIENT_LEASE),
+ dname(d) {
+ h.action = ac;
+ h.seq = seq;
+ h.mask = m;
+ h.ino = i;
+ h.first = sf;
+ h.last = sl;
+ h.duration_ms = 0;
+ }
+ ~MClientLease() override {}
+
+public:
+ std::string_view get_type_name() const override { return "client_lease"; }
+ void print(ostream& out) const override {
+ out << "client_lease(a=" << ceph_lease_op_name(get_action())
+ << " seq " << get_seq()
+ << " mask " << get_mask();
+ out << " " << get_ino();
+ if (h.last != CEPH_NOSNAP)
+ out << " [" << snapid_t(h.first) << "," << snapid_t(h.last) << "]";
+ if (dname.length())
+ out << "/" << dname;
+ out << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(h, p);
+ decode(dname, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(h, payload);
+ encode(dname, payload);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MClientQuota.h b/src/messages/MClientQuota.h
new file mode 100644
index 00000000..b1aed00b
--- /dev/null
+++ b/src/messages/MClientQuota.h
@@ -0,0 +1,52 @@
+#ifndef CEPH_MCLIENTQUOTA_H
+#define CEPH_MCLIENTQUOTA_H
+
+#include "msg/Message.h"
+
+class MClientQuota : public MessageInstance<MClientQuota> {
+public:
+ friend factory;
+
+ inodeno_t ino;
+ nest_info_t rstat;
+ quota_info_t quota;
+
+protected:
+ MClientQuota() :
+ MessageInstance(CEPH_MSG_CLIENT_QUOTA),
+ ino(0)
+ {}
+ ~MClientQuota() override {}
+
+public:
+ std::string_view get_type_name() const override { return "client_quota"; }
+ void print(ostream& out) const override {
+ out << "client_quota(";
+ out << " [" << ino << "] ";
+ out << rstat << " ";
+ out << quota;
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(rstat.rctime, payload);
+ encode(rstat.rbytes, payload);
+ encode(rstat.rfiles, payload);
+ encode(rstat.rsubdirs, payload);
+ encode(quota, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(rstat.rctime, p);
+ decode(rstat.rbytes, p);
+ decode(rstat.rfiles, p);
+ decode(rstat.rsubdirs, p);
+ decode(quota, p);
+ ceph_assert(p.end());
+ }
+};
+
+#endif
diff --git a/src/messages/MClientReclaim.h b/src/messages/MClientReclaim.h
new file mode 100644
index 00000000..ffb7609c
--- /dev/null
+++ b/src/messages/MClientReclaim.h
@@ -0,0 +1,64 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MCLIENTRECLAIM_H
+#define CEPH_MCLIENTRECLAIM_H
+
+#include "msg/Message.h"
+
+class MClientReclaim: public MessageInstance<MClientReclaim> {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+ static constexpr uint32_t FLAG_FINISH = 1U << 31;
+
+ uint32_t get_flags() const { return flags; }
+ std::string_view get_uuid() const { return uuid; }
+
+ std::string_view get_type_name() const override { return "client_reclaim"; }
+ void print(ostream& o) const override {
+ std::ios_base::fmtflags f(o.flags());
+ o << "client_reclaim(" << get_uuid() << " flags 0x" << std::hex << get_flags() << ")";
+ o.flags(f);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(uuid, payload);
+ encode(flags, payload);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(uuid, p);
+ decode(flags, p);
+ }
+
+protected:
+ friend factory;
+ MClientReclaim() :
+ MessageInstance(CEPH_MSG_CLIENT_RECLAIM, HEAD_VERSION, COMPAT_VERSION) {}
+ MClientReclaim(std::string_view _uuid, uint32_t _flags) :
+ MessageInstance(CEPH_MSG_CLIENT_RECLAIM, HEAD_VERSION, COMPAT_VERSION),
+ uuid(_uuid), flags(_flags) {}
+private:
+ ~MClientReclaim() override {}
+
+ std::string uuid;
+ uint32_t flags = 0;
+};
+
+#endif
diff --git a/src/messages/MClientReclaimReply.h b/src/messages/MClientReclaimReply.h
new file mode 100644
index 00000000..288b8868
--- /dev/null
+++ b/src/messages/MClientReclaimReply.h
@@ -0,0 +1,69 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MCLIENTRECLAIMREPLY_H
+#define CEPH_MCLIENTRECLAIMREPLY_H
+
+#include "msg/Message.h"
+
+class MClientReclaimReply: public MessageInstance<MClientReclaimReply> {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ int32_t get_result() const { return result; }
+ void set_result(int r) { result = r; }
+ epoch_t get_epoch() const { return epoch; }
+ void set_epoch(epoch_t e) { epoch = e; }
+ const entity_addrvec_t& get_addrs() const { return addrs; }
+ void set_addrs(const entity_addrvec_t& _addrs) { addrs = _addrs; }
+
+ std::string_view get_type_name() const override { return "client_reclaim_reply"; }
+ void print(ostream& o) const override {
+ o << "client_reclaim_reply(" << result << " e " << epoch << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(result, payload);
+ encode(epoch, payload);
+ encode(addrs, payload, features);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(result, p);
+ decode(epoch, p);
+ decode(addrs, p);
+ }
+
+protected:
+ friend factory;
+ MClientReclaimReply() :
+ MessageInstance(CEPH_MSG_CLIENT_RECLAIM_REPLY, HEAD_VERSION, COMPAT_VERSION) {}
+ MClientReclaimReply(int r, epoch_t e=0) :
+ MessageInstance(CEPH_MSG_CLIENT_RECLAIM_REPLY, HEAD_VERSION, COMPAT_VERSION),
+ result(r), epoch(e) {}
+
+private:
+ ~MClientReclaimReply() override {}
+
+ int32_t result;
+ epoch_t epoch;
+ entity_addrvec_t addrs;
+};
+
+#endif
diff --git a/src/messages/MClientReconnect.h b/src/messages/MClientReconnect.h
new file mode 100644
index 00000000..ba3b0fb2
--- /dev/null
+++ b/src/messages/MClientReconnect.h
@@ -0,0 +1,174 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCLIENTRECONNECT_H
+#define CEPH_MCLIENTRECONNECT_H
+
+#include "msg/Message.h"
+#include "mds/mdstypes.h"
+#include "include/ceph_features.h"
+
+
+class MClientReconnect : public MessageInstance<MClientReconnect> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 5;
+ static constexpr int COMPAT_VERSION = 4;
+
+public:
+ map<inodeno_t, cap_reconnect_t> caps; // only head inodes
+ vector<snaprealm_reconnect_t> realms;
+ bool more = false;
+
+ MClientReconnect() :
+ MessageInstance(CEPH_MSG_CLIENT_RECONNECT, HEAD_VERSION, COMPAT_VERSION) {}
+private:
+ ~MClientReconnect() override {}
+
+ size_t cap_size = 0;
+ size_t realm_size = 0;
+ size_t approx_size = sizeof(__u32) + sizeof(__u32) + 1;
+
+ void calc_item_size() {
+ using ceph::encode;
+ {
+ bufferlist bl;
+ inodeno_t ino;
+ cap_reconnect_t cr;
+ encode(ino, bl);
+ encode(cr, bl);
+ cap_size = bl.length();
+ }
+ {
+ bufferlist bl;
+ snaprealm_reconnect_t sr;
+ encode(sr, bl);
+ realm_size = bl.length();
+ }
+ }
+
+public:
+ std::string_view get_type_name() const override { return "client_reconnect"; }
+ void print(ostream& out) const override {
+ out << "client_reconnect("
+ << caps.size() << " caps " << realms.size() << " realms )";
+ }
+
+ // Force to use old encoding.
+ // Use connection's features to choose encoding if version is set to 0.
+ void set_encoding_version(int v) {
+ header.version = v;
+ if (v <= 3)
+ header.compat_version = 0;
+ }
+ size_t get_approx_size() {
+ return approx_size;
+ }
+ void mark_more() { more = true; }
+ bool has_more() const { return more; }
+
+ void add_cap(inodeno_t ino, uint64_t cap_id, inodeno_t pathbase, const string& path,
+ int wanted, int issued, inodeno_t sr, snapid_t sf, bufferlist& lb)
+ {
+ caps[ino] = cap_reconnect_t(cap_id, pathbase, path, wanted, issued, sr, sf, lb);
+ if (!cap_size)
+ calc_item_size();
+ approx_size += cap_size + path.length() + lb.length();
+ }
+ void add_snaprealm(inodeno_t ino, snapid_t seq, inodeno_t parent) {
+ snaprealm_reconnect_t r;
+ r.realm.ino = ino;
+ r.realm.seq = seq;
+ r.realm.parent = parent;
+ realms.push_back(r);
+ if (!realm_size)
+ calc_item_size();
+ approx_size += realm_size;
+ }
+
+ void encode_payload(uint64_t features) override {
+ if (header.version == 0) {
+ if (features & CEPH_FEATURE_MDSENC)
+ header.version = 3;
+ else if (features & CEPH_FEATURE_FLOCK)
+ header.version = 2;
+ else
+ header.version = 1;
+ }
+
+ using ceph::encode;
+ data.clear();
+
+ if (header.version >= 4) {
+ encode(caps, data);
+ encode(realms, data);
+ encode(more, data);
+ } else {
+ // compat crap
+ if (header.version == 3) {
+ encode(caps, data);
+ } else if (header.version == 2) {
+ __u32 n = caps.size();
+ encode(n, data);
+ for (auto& p : caps) {
+ encode(p.first, data);
+ p.second.encode_old(data);
+ }
+ } else {
+ map<inodeno_t, old_cap_reconnect_t> ocaps;
+ for (auto& p : caps) {
+ ocaps[p.first] = p.second;
+ encode(ocaps, data);
+ }
+ for (auto& r : realms)
+ r.encode_old(data);
+ }
+ }
+ }
+ void decode_payload() override {
+ auto p = data.cbegin();
+ if (header.version >= 4) {
+ decode(caps, p);
+ decode(realms, p);
+ if (header.version >= 5)
+ decode(more, p);
+ } else {
+ // compat crap
+ if (header.version == 3) {
+ decode(caps, p);
+ } else if (header.version == 2) {
+ __u32 n;
+ decode(n, p);
+ inodeno_t ino;
+ while (n--) {
+ decode(ino, p);
+ caps[ino].decode_old(p);
+ }
+ } else {
+ map<inodeno_t, old_cap_reconnect_t> ocaps;
+ decode(ocaps, p);
+ for (auto &q : ocaps)
+ caps[q.first] = q.second;
+ }
+ while (!p.end()) {
+ realms.push_back(snaprealm_reconnect_t());
+ realms.back().decode_old(p);
+ }
+ }
+ }
+};
+
+
+#endif
diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h
new file mode 100644
index 00000000..fb1ebfe8
--- /dev/null
+++ b/src/messages/MClientReply.h
@@ -0,0 +1,361 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MCLIENTREPLY_H
+#define CEPH_MCLIENTREPLY_H
+
+#include "include/types.h"
+#include "include/fs_types.h"
+#include "MClientRequest.h"
+
+#include "msg/Message.h"
+#include "include/ceph_features.h"
+#include "common/errno.h"
+
+/***
+ *
+ * MClientReply - container message for MDS reply to a client's MClientRequest
+ *
+ * key fields:
+ * long tid - transaction id, so the client can match up with pending request
+ * int result - error code, or fh if it was open
+ *
+ * for most requests:
+ * trace is a vector of InodeStat's tracing from root to the file/dir/whatever
+ * the operation referred to, so that the client can update it's info about what
+ * metadata lives on what MDS.
+ *
+ * for readdir replies:
+ * dir_contents is a vector of InodeStat*'s.
+ *
+ * that's mostly it, i think!
+ *
+ */
+
+
+struct LeaseStat {
+ // this matches ceph_mds_reply_lease
+ __u16 mask;
+ __u32 duration_ms;
+ __u32 seq;
+
+ LeaseStat() : mask(0), duration_ms(0), seq(0) {}
+ LeaseStat(__u16 msk, __u32 dur, __u32 sq) : mask{msk}, duration_ms{dur}, seq{sq} {}
+
+ void decode(bufferlist::const_iterator &bl, const uint64_t features) {
+ using ceph::decode;
+ if (features == (uint64_t)-1) {
+ DECODE_START(1, bl);
+ decode(mask, bl);
+ decode(duration_ms, bl);
+ decode(seq, bl);
+ DECODE_FINISH(bl);
+ }
+ else {
+ decode(mask, bl);
+ decode(duration_ms, bl);
+ decode(seq, bl);
+ }
+ }
+};
+
+inline ostream& operator<<(ostream& out, const LeaseStat& l) {
+ return out << "lease(mask " << l.mask << " dur " << l.duration_ms << ")";
+}
+
+struct DirStat {
+ // mds distribution hints
+ frag_t frag;
+ __s32 auth;
+ set<__s32> dist;
+
+ DirStat() : auth(CDIR_AUTH_PARENT) {}
+ DirStat(bufferlist::const_iterator& p, const uint64_t features) {
+ decode(p, features);
+ }
+
+ void decode(bufferlist::const_iterator& p, const uint64_t features) {
+ using ceph::decode;
+ if (features == (uint64_t)-1) {
+ DECODE_START(1, p);
+ decode(frag, p);
+ decode(auth, p);
+ decode(dist, p);
+ DECODE_FINISH(p);
+ }
+ else {
+ decode(frag, p);
+ decode(auth, p);
+ decode(dist, p);
+ }
+ }
+
+ // see CDir::encode_dirstat for encoder.
+};
+
+struct InodeStat {
+ vinodeno_t vino;
+ uint32_t rdev = 0;
+ version_t version = 0;
+ version_t xattr_version = 0;
+ ceph_mds_reply_cap cap;
+ file_layout_t layout;
+ utime_t ctime, btime, mtime, atime, snap_btime;
+ uint32_t time_warp_seq = 0;
+ uint64_t size = 0, max_size = 0;
+ uint64_t change_attr = 0;
+ uint64_t truncate_size = 0;
+ uint32_t truncate_seq = 0;
+ uint32_t mode = 0, uid = 0, gid = 0, nlink = 0;
+ frag_info_t dirstat;
+ nest_info_t rstat;
+
+ fragtree_t dirfragtree;
+ string symlink; // symlink content (if symlink)
+
+ ceph_dir_layout dir_layout;
+
+ bufferlist xattrbl;
+
+ bufferlist inline_data;
+ version_t inline_version;
+
+ quota_info_t quota;
+
+ mds_rank_t dir_pin;
+
+ public:
+ InodeStat() {}
+ InodeStat(bufferlist::const_iterator& p, const uint64_t features) {
+ decode(p, features);
+ }
+
+ void decode(bufferlist::const_iterator &p, const uint64_t features) {
+ using ceph::decode;
+ if (features == (uint64_t)-1) {
+ DECODE_START(2, p);
+ decode(vino.ino, p);
+ decode(vino.snapid, p);
+ decode(rdev, p);
+ decode(version, p);
+ decode(xattr_version, p);
+ decode(cap, p);
+ {
+ ceph_file_layout legacy_layout;
+ decode(legacy_layout, p);
+ layout.from_legacy(legacy_layout);
+ }
+ decode(ctime, p);
+ decode(mtime, p);
+ decode(atime, p);
+ decode(time_warp_seq, p);
+ decode(size, p);
+ decode(max_size, p);
+ decode(truncate_size, p);
+ decode(truncate_seq, p);
+ decode(mode, p);
+ decode(uid, p);
+ decode(gid, p);
+ decode(nlink, p);
+ decode(dirstat.nfiles, p);
+ decode(dirstat.nsubdirs, p);
+ decode(rstat.rbytes, p);
+ decode(rstat.rfiles, p);
+ decode(rstat.rsubdirs, p);
+ decode(rstat.rctime, p);
+ decode(dirfragtree, p);
+ decode(symlink, p);
+ decode(dir_layout, p);
+ decode(xattrbl, p);
+ decode(inline_version, p);
+ decode(inline_data, p);
+ decode(quota, p);
+ decode(layout.pool_ns, p);
+ decode(btime, p);
+ decode(change_attr, p);
+ if (struct_v > 1) {
+ decode(dir_pin, p);
+ } else {
+ dir_pin = -ENODATA;
+ }
+ if (struct_v >= 3) {
+ decode(snap_btime, p);
+ } // else remains zero
+ DECODE_FINISH(p);
+ }
+ else {
+ decode(vino.ino, p);
+ decode(vino.snapid, p);
+ decode(rdev, p);
+ decode(version, p);
+ decode(xattr_version, p);
+ decode(cap, p);
+ {
+ ceph_file_layout legacy_layout;
+ decode(legacy_layout, p);
+ layout.from_legacy(legacy_layout);
+ }
+ decode(ctime, p);
+ decode(mtime, p);
+ decode(atime, p);
+ decode(time_warp_seq, p);
+ decode(size, p);
+ decode(max_size, p);
+ decode(truncate_size, p);
+ decode(truncate_seq, p);
+ decode(mode, p);
+ decode(uid, p);
+ decode(gid, p);
+ decode(nlink, p);
+ decode(dirstat.nfiles, p);
+ decode(dirstat.nsubdirs, p);
+ decode(rstat.rbytes, p);
+ decode(rstat.rfiles, p);
+ decode(rstat.rsubdirs, p);
+ decode(rstat.rctime, p);
+ decode(dirfragtree, p);
+ decode(symlink, p);
+ if (features & CEPH_FEATURE_DIRLAYOUTHASH)
+ decode(dir_layout, p);
+ else
+ memset(&dir_layout, 0, sizeof(dir_layout));
+
+ decode(xattrbl, p);
+
+ if (features & CEPH_FEATURE_MDS_INLINE_DATA) {
+ decode(inline_version, p);
+ decode(inline_data, p);
+ } else {
+ inline_version = CEPH_INLINE_NONE;
+ }
+
+ if (features & CEPH_FEATURE_MDS_QUOTA)
+ decode(quota, p);
+ else
+ quota = quota_info_t{};
+
+ if ((features & CEPH_FEATURE_FS_FILE_LAYOUT_V2))
+ decode(layout.pool_ns, p);
+
+ if ((features & CEPH_FEATURE_FS_BTIME)) {
+ decode(btime, p);
+ decode(change_attr, p);
+ } else {
+ btime = utime_t();
+ change_attr = 0;
+ }
+ }
+ }
+
+ // see CInode::encode_inodestat for encoder.
+};
+
+
+class MClientReply : public MessageInstance<MClientReply> {
+public:
+ friend factory;
+
+ // reply data
+ struct ceph_mds_reply_head head {};
+ bufferlist trace_bl;
+ bufferlist extra_bl;
+ bufferlist snapbl;
+
+ int get_op() const { return head.op; }
+
+ void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; }
+ epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; }
+
+ int get_result() const {
+ return ceph_to_hostos_errno((__s32)(__u32)head.result);
+ }
+
+ void set_result(int r) { head.result = r; }
+
+ void set_unsafe() { head.safe = 0; }
+
+ bool is_safe() const { return head.safe; }
+
+protected:
+ MClientReply() : MessageInstance(CEPH_MSG_CLIENT_REPLY) {}
+ MClientReply(const MClientRequest &req, int result = 0) :
+ MessageInstance(CEPH_MSG_CLIENT_REPLY) {
+ memset(&head, 0, sizeof(head));
+ header.tid = req.get_tid();
+ head.op = req.get_op();
+ head.result = result;
+ head.safe = 1;
+ }
+ ~MClientReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "creply"; }
+ void print(ostream& o) const override {
+ o << "client_reply(???:" << get_tid();
+ o << " = " << get_result();
+ if (get_result() <= 0) {
+ o << " " << cpp_strerror(get_result());
+ }
+ if (head.op & CEPH_MDS_OP_WRITE) {
+ if (head.safe)
+ o << " safe";
+ else
+ o << " unsafe";
+ }
+ o << ")";
+ }
+
+ // serialization
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(head, p);
+ decode(trace_bl, p);
+ decode(extra_bl, p);
+ decode(snapbl, p);
+ ceph_assert(p.end());
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(head, payload);
+ encode(trace_bl, payload);
+ encode(extra_bl, payload);
+ encode(snapbl, payload);
+ }
+
+
+ // dir contents
+ void set_extra_bl(bufferlist& bl) {
+ extra_bl.claim(bl);
+ }
+ bufferlist& get_extra_bl() {
+ return extra_bl;
+ }
+ const bufferlist& get_extra_bl() const {
+ return extra_bl;
+ }
+
+ // trace
+ void set_trace(bufferlist& bl) {
+ trace_bl.claim(bl);
+ }
+ bufferlist& get_trace_bl() {
+ return trace_bl;
+ }
+ const bufferlist& get_trace_bl() const {
+ return trace_bl;
+ }
+};
+
+#endif
diff --git a/src/messages/MClientRequest.h b/src/messages/MClientRequest.h
new file mode 100644
index 00000000..602eff1d
--- /dev/null
+++ b/src/messages/MClientRequest.h
@@ -0,0 +1,289 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MCLIENTREQUEST_H
+#define CEPH_MCLIENTREQUEST_H
+
+/**
+ *
+ * MClientRequest - container for a client METADATA request. created/sent by clients.
+ * can be forwarded around between MDS's.
+ *
+ * int client - the originating client
+ * long tid - transaction id, unique among requests for that client. probably just a counter!
+ * -> the MDS passes the Request to the Reply constructor, so this always matches.
+ *
+ * int op - the metadata op code. MDS_OP_RENAME, etc.
+ * int caller_uid, _gid - guess
+ *
+ * fixed size arguments are in a union.
+ * there's also a string argument, for e.g. symlink().
+ *
+ */
+
+#include <string_view>
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+#include "mds/mdstypes.h"
+#include "include/ceph_features.h"
+
+#include <sys/types.h>
+#include <utime.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+// metadata ops.
+
+class MClientRequest : public MessageInstance<MClientRequest> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ mutable struct ceph_mds_request_head head; /* XXX HACK! */
+ utime_t stamp;
+
+ struct Release {
+ mutable ceph_mds_request_release item;
+ string dname;
+
+ Release() : item(), dname() {}
+ Release(const ceph_mds_request_release& rel, string name) :
+ item(rel), dname(name) {}
+
+ void encode(bufferlist& bl) const {
+ using ceph::encode;
+ item.dname_len = dname.length();
+ encode(item, bl);
+ encode_nohead(dname, bl);
+ }
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(item, bl);
+ decode_nohead(item.dname_len, dname, bl);
+ }
+ };
+ mutable vector<Release> releases; /* XXX HACK! */
+
+ // path arguments
+ filepath path, path2;
+ vector<uint64_t> gid_list;
+
+ /* XXX HACK */
+ mutable bool queued_for_replay = false;
+
+protected:
+ // cons
+ MClientRequest()
+ : MessageInstance(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {}
+ MClientRequest(int op)
+ : MessageInstance(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {
+ memset(&head, 0, sizeof(head));
+ head.op = op;
+ }
+ ~MClientRequest() override {}
+
+public:
+ void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; }
+ epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; }
+ epoch_t get_osdmap_epoch() const {
+ ceph_assert(head.op == CEPH_MDS_OP_SETXATTR);
+ if (header.version >= 3)
+ return head.args.setxattr.osdmap_epoch;
+ else
+ return 0;
+ }
+ void set_osdmap_epoch(epoch_t e) {
+ ceph_assert(head.op == CEPH_MDS_OP_SETXATTR);
+ head.args.setxattr.osdmap_epoch = e;
+ }
+
+ metareqid_t get_reqid() const {
+ // FIXME: for now, assume clients always have 1 incarnation
+ return metareqid_t(get_orig_source(), header.tid);
+ }
+
+ /*bool open_file_mode_is_readonly() {
+ return file_mode_is_readonly(ceph_flags_to_mode(head.args.open.flags));
+ }*/
+ bool may_write() const {
+ return
+ (head.op & CEPH_MDS_OP_WRITE) ||
+ (head.op == CEPH_MDS_OP_OPEN && (head.args.open.flags & (O_CREAT|O_TRUNC)));
+ }
+
+ int get_flags() const {
+ return head.flags;
+ }
+ bool is_replay() const {
+ return get_flags() & CEPH_MDS_FLAG_REPLAY;
+ }
+
+ // normal fields
+ void set_stamp(utime_t t) { stamp = t; }
+ void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; }
+ void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
+ void set_retry_attempt(int a) { head.num_retry = a; }
+ void set_filepath(const filepath& fp) { path = fp; }
+ void set_filepath2(const filepath& fp) { path2 = fp; }
+ void set_string2(const char *s) { path2.set_path(std::string_view(s), 0); }
+ void set_caller_uid(unsigned u) { head.caller_uid = u; }
+ void set_caller_gid(unsigned g) { head.caller_gid = g; }
+ void set_gid_list(int count, const gid_t *gids) {
+ gid_list.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ gid_list.push_back(gids[i]);
+ }
+ }
+ void set_dentry_wanted() {
+ head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY;
+ }
+ void set_replayed_op() {
+ head.flags = head.flags | CEPH_MDS_FLAG_REPLAY;
+ }
+
+ utime_t get_stamp() const { return stamp; }
+ ceph_tid_t get_oldest_client_tid() const { return head.oldest_client_tid; }
+ int get_num_fwd() const { return head.num_fwd; }
+ int get_retry_attempt() const { return head.num_retry; }
+ int get_op() const { return head.op; }
+ unsigned get_caller_uid() const { return head.caller_uid; }
+ unsigned get_caller_gid() const { return head.caller_gid; }
+ const vector<uint64_t>& get_caller_gid_list() const { return gid_list; }
+
+ const string& get_path() const { return path.get_path(); }
+ const filepath& get_filepath() const { return path; }
+ const string& get_path2() const { return path2.get_path(); }
+ const filepath& get_filepath2() const { return path2; }
+
+ int get_dentry_wanted() const { return get_flags() & CEPH_MDS_FLAG_WANT_DENTRY; }
+
+ void mark_queued_for_replay() const { queued_for_replay = true; }
+ bool is_queued_for_replay() const { return queued_for_replay; }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+
+ if (header.version >= 4) {
+ decode(head, p);
+ } else {
+ struct ceph_mds_request_head_legacy old_mds_head;
+
+ decode(old_mds_head, p);
+ copy_from_legacy_head(&head, &old_mds_head);
+ head.version = 0;
+
+ /* Can't set the btime from legacy struct */
+ if (head.op == CEPH_MDS_OP_SETATTR) {
+ int localmask = head.args.setattr.mask;
+
+ localmask &= ~CEPH_SETATTR_BTIME;
+
+ head.args.setattr.btime = { 0 };
+ head.args.setattr.mask = localmask;
+ }
+ }
+
+ decode(path, p);
+ decode(path2, p);
+ decode_nohead(head.num_releases, releases, p);
+ if (header.version >= 2)
+ decode(stamp, p);
+ if (header.version >= 4) // epoch 3 was for a ceph_mds_request_args change
+ decode(gid_list, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ head.num_releases = releases.size();
+ head.version = CEPH_MDS_REQUEST_HEAD_VERSION;
+
+ if (features & CEPH_FEATURE_FS_BTIME) {
+ encode(head, payload);
+ } else {
+ struct ceph_mds_request_head_legacy old_mds_head;
+
+ copy_to_legacy_head(&old_mds_head, &head);
+ encode(old_mds_head, payload);
+ }
+
+ encode(path, payload);
+ encode(path2, payload);
+ encode_nohead(releases, payload);
+ encode(stamp, payload);
+ encode(gid_list, payload);
+ }
+
+ std::string_view get_type_name() const override { return "creq"; }
+ void print(ostream& out) const override {
+ out << "client_request(" << get_orig_source()
+ << ":" << get_tid()
+ << " " << ceph_mds_op_name(get_op());
+ if (head.op == CEPH_MDS_OP_GETATTR)
+ out << " " << ccap_string(head.args.getattr.mask);
+ if (head.op == CEPH_MDS_OP_SETATTR) {
+ if (head.args.setattr.mask & CEPH_SETATTR_MODE)
+ out << " mode=0" << std::oct << head.args.setattr.mode << std::dec;
+ if (head.args.setattr.mask & CEPH_SETATTR_UID)
+ out << " uid=" << head.args.setattr.uid;
+ if (head.args.setattr.mask & CEPH_SETATTR_GID)
+ out << " gid=" << head.args.setattr.gid;
+ if (head.args.setattr.mask & CEPH_SETATTR_SIZE)
+ out << " size=" << head.args.setattr.size;
+ if (head.args.setattr.mask & CEPH_SETATTR_MTIME)
+ out << " mtime=" << utime_t(head.args.setattr.mtime);
+ if (head.args.setattr.mask & CEPH_SETATTR_ATIME)
+ out << " atime=" << utime_t(head.args.setattr.atime);
+ }
+ if (head.op == CEPH_MDS_OP_SETFILELOCK ||
+ head.op == CEPH_MDS_OP_GETFILELOCK) {
+ out << " rule " << (int)head.args.filelock_change.rule
+ << ", type " << (int)head.args.filelock_change.type
+ << ", owner " << head.args.filelock_change.owner
+ << ", pid " << head.args.filelock_change.pid
+ << ", start " << head.args.filelock_change.start
+ << ", length " << head.args.filelock_change.length
+ << ", wait " << (int)head.args.filelock_change.wait;
+ }
+ //if (!get_filepath().empty())
+ out << " " << get_filepath();
+ if (!get_filepath2().empty())
+ out << " " << get_filepath2();
+ if (stamp != utime_t())
+ out << " " << stamp;
+ if (head.num_retry)
+ out << " RETRY=" << (int)head.num_retry;
+ if (get_flags() & CEPH_MDS_FLAG_REPLAY)
+ out << " REPLAY";
+ if (queued_for_replay)
+ out << " QUEUED_FOR_REPLAY";
+ out << " caller_uid=" << head.caller_uid
+ << ", caller_gid=" << head.caller_gid
+ << '{';
+ for (auto i = gid_list.begin(); i != gid_list.end(); ++i)
+ out << *i << ',';
+ out << '}'
+ << ")";
+ }
+
+};
+
+WRITE_CLASS_ENCODER(MClientRequest::Release)
+
+#endif
diff --git a/src/messages/MClientRequestForward.h b/src/messages/MClientRequestForward.h
new file mode 100644
index 00000000..e3dc8071
--- /dev/null
+++ b/src/messages/MClientRequestForward.h
@@ -0,0 +1,70 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MCLIENTREQUESTFORWARD_H
+#define CEPH_MCLIENTREQUESTFORWARD_H
+
+#include "msg/Message.h"
+
+class MClientRequestForward : public MessageInstance<MClientRequestForward> {
+public:
+ friend factory;
+private:
+ int32_t dest_mds;
+ int32_t num_fwd;
+ bool client_must_resend;
+
+protected:
+ MClientRequestForward()
+ : MessageInstance(CEPH_MSG_CLIENT_REQUEST_FORWARD),
+ dest_mds(-1), num_fwd(-1), client_must_resend(false) {}
+ MClientRequestForward(ceph_tid_t t, int dm, int nf, bool cmr) :
+ MessageInstance(CEPH_MSG_CLIENT_REQUEST_FORWARD),
+ dest_mds(dm), num_fwd(nf), client_must_resend(cmr) {
+ ceph_assert(client_must_resend);
+ header.tid = t;
+ }
+ ~MClientRequestForward() override {}
+
+public:
+ int get_dest_mds() const { return dest_mds; }
+ int get_num_fwd() const { return num_fwd; }
+ bool must_resend() const { return client_must_resend; }
+
+ std::string_view get_type_name() const override { return "client_request_forward"; }
+ void print(ostream& o) const override {
+ o << "client_request_forward(" << get_tid()
+ << " to mds." << dest_mds
+ << " num_fwd=" << num_fwd
+ << (client_must_resend ? " client_must_resend":"")
+ << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dest_mds, payload);
+ encode(num_fwd, payload);
+ encode(client_must_resend, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dest_mds, p);
+ decode(num_fwd, p);
+ decode(client_must_resend, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MClientSession.h b/src/messages/MClientSession.h
new file mode 100644
index 00000000..c7a2a3b5
--- /dev/null
+++ b/src/messages/MClientSession.h
@@ -0,0 +1,92 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCLIENTSESSION_H
+#define CEPH_MCLIENTSESSION_H
+
+#include "msg/Message.h"
+#include "mds/mdstypes.h"
+
+class MClientSession : public MessageInstance<MClientSession> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ ceph_mds_session_head head;
+
+ std::map<std::string, std::string> metadata;
+ feature_bitset_t supported_features;
+
+ int get_op() const { return head.op; }
+ version_t get_seq() const { return head.seq; }
+ utime_t get_stamp() const { return utime_t(head.stamp); }
+ int get_max_caps() const { return head.max_caps; }
+ int get_max_leases() const { return head.max_leases; }
+
+protected:
+ MClientSession() : MessageInstance(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) { }
+ MClientSession(int o, version_t s=0) :
+ MessageInstance(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ head.seq = s;
+ }
+ MClientSession(int o, utime_t st) :
+ MessageInstance(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ head.seq = 0;
+ st.encode_timeval(&head.stamp);
+ }
+ ~MClientSession() override {}
+
+public:
+ std::string_view get_type_name() const override { return "client_session"; }
+ void print(ostream& out) const override {
+ out << "client_session(" << ceph_session_op_name(get_op());
+ if (get_seq())
+ out << " seq " << get_seq();
+ if (get_op() == CEPH_SESSION_RECALL_STATE)
+ out << " max_caps " << head.max_caps << " max_leases " << head.max_leases;
+ out << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(head, p);
+ if (header.version >= 2)
+ decode(metadata, p);
+ if (header.version >= 3)
+ decode(supported_features, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(head, payload);
+ if (metadata.empty() && supported_features.empty()) {
+ // If we're not trying to send any metadata (always the case if
+ // we are a server) then send older-format message to avoid upsetting
+ // old kernel clients.
+ header.version = 1;
+ } else {
+ header.version = HEAD_VERSION;
+ encode(metadata, payload);
+ encode(supported_features, payload);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MClientSnap.h b/src/messages/MClientSnap.h
new file mode 100644
index 00000000..f0f96e4e
--- /dev/null
+++ b/src/messages/MClientSnap.h
@@ -0,0 +1,70 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCLIENTSNAP_H
+#define CEPH_MCLIENTSNAP_H
+
+#include "msg/Message.h"
+
+class MClientSnap : public MessageInstance<MClientSnap> {
+public:
+ friend factory;
+
+ ceph_mds_snap_head head;
+ bufferlist bl;
+
+ // (for split only)
+ vector<inodeno_t> split_inos;
+ vector<inodeno_t> split_realms;
+
+protected:
+ MClientSnap(int o=0) :
+ MessageInstance(CEPH_MSG_CLIENT_SNAP) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ }
+ ~MClientSnap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "client_snap"; }
+ void print(ostream& out) const override {
+ out << "client_snap(" << ceph_snap_op_name(head.op);
+ if (head.split)
+ out << " split=" << inodeno_t(head.split);
+ out << " tracelen=" << bl.length();
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ head.num_split_inos = split_inos.size();
+ head.num_split_realms = split_realms.size();
+ head.trace_len = bl.length();
+ encode(head, payload);
+ encode_nohead(split_inos, payload);
+ encode_nohead(split_realms, payload);
+ encode_nohead(bl, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(head, p);
+ decode_nohead(head.num_split_inos, split_inos, p);
+ decode_nohead(head.num_split_realms, split_realms, p);
+ decode_nohead(head.trace_len, bl, p);
+ ceph_assert(p.end());
+ }
+
+};
+
+#endif
diff --git a/src/messages/MCommand.h b/src/messages/MCommand.h
new file mode 100644
index 00000000..421d04c2
--- /dev/null
+++ b/src/messages/MCommand.h
@@ -0,0 +1,61 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCOMMAND_H
+#define CEPH_MCOMMAND_H
+
+#include <vector>
+
+#include "msg/Message.h"
+
+class MCommand : public MessageInstance<MCommand> {
+public:
+ friend factory;
+
+ uuid_d fsid;
+ std::vector<string> cmd;
+
+ MCommand()
+ : MessageInstance(MSG_COMMAND) {}
+ MCommand(const uuid_d &f)
+ : MessageInstance(MSG_COMMAND),
+ fsid(f) { }
+
+private:
+ ~MCommand() override {}
+
+public:
+ std::string_view get_type_name() const override { return "command"; }
+ void print(ostream& o) const override {
+ o << "command(tid " << get_tid() << ": ";
+ for (unsigned i=0; i<cmd.size(); i++) {
+ if (i) o << ' ';
+ o << cmd[i];
+ }
+ o << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(fsid, payload);
+ encode(cmd, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(cmd, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MCommandReply.h b/src/messages/MCommandReply.h
new file mode 100644
index 00000000..d740565b
--- /dev/null
+++ b/src/messages/MCommandReply.h
@@ -0,0 +1,60 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MCOMMANDREPLY_H
+#define CEPH_MCOMMANDREPLY_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+#include "MCommand.h"
+
+class MCommandReply : public MessageInstance<MCommandReply> {
+public:
+ friend factory;
+
+ errorcode32_t r;
+ string rs;
+
+ MCommandReply()
+ : MessageInstance(MSG_COMMAND_REPLY) {}
+ MCommandReply(MCommand *m, int _r)
+ : MessageInstance(MSG_COMMAND_REPLY), r(_r) {
+ header.tid = m->get_tid();
+ }
+ MCommandReply(int _r, std::string_view s)
+ : MessageInstance(MSG_COMMAND_REPLY),
+ r(_r), rs(s) { }
+private:
+ ~MCommandReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "command_reply"; }
+ void print(ostream& o) const override {
+ o << "command_reply(tid " << get_tid() << ": " << r << " " << rs << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(r, payload);
+ encode(rs, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(r, p);
+ decode(rs, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MConfig.h b/src/messages/MConfig.h
new file mode 100644
index 00000000..1e433e52
--- /dev/null
+++ b/src/messages/MConfig.h
@@ -0,0 +1,40 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+
+class MConfig : public MessageInstance<MConfig> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ map<string,string> config;
+
+ MConfig() : MessageInstance(MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION) { }
+ MConfig(const map<string,string>& c)
+ : MessageInstance(MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION),
+ config(c) {}
+
+ std::string_view get_type_name() const override {
+ return "config";
+ }
+ void print(ostream& o) const override {
+ o << "config(" << config.size() << " keys" << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(config, p);
+ }
+
+ void encode_payload(uint64_t) override {
+ using ceph::encode;
+ encode(config, payload);
+ }
+
+};
diff --git a/src/messages/MDataPing.h b/src/messages/MDataPing.h
new file mode 100644
index 00000000..615bdc05
--- /dev/null
+++ b/src/messages/MDataPing.h
@@ -0,0 +1,92 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MDATAPING_H
+#define CEPH_MDATAPING_H
+
+#include "msg/Message.h"
+#include "messages/MPing.h"
+#include "include/encoding.h"
+#if defined(HAVE_XIO)
+extern "C" {
+#include "libxio.h"
+}
+#else
+struct xio_reg_mem {};
+#endif /* HAVE_XIO */
+
+typedef void (*mdata_hook_func)(struct xio_reg_mem *mp);
+
+class MDataPing : public MessageInstance<MDataPing> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ std::string tag;
+ uint32_t counter = 0;
+ mdata_hook_func mdata_hook;
+ struct xio_reg_mem mp;
+ bool free_data;
+
+ MDataPing()
+ : MessageInstance(MSG_DATA_PING, HEAD_VERSION, COMPAT_VERSION),
+ mdata_hook(NULL),
+ free_data(false)
+ {}
+
+ struct xio_reg_mem *get_mp()
+ {
+ return &mp;
+ }
+
+ void set_rdma_hook(mdata_hook_func hook)
+ {
+ mdata_hook = hook;
+ }
+
+private:
+ ~MDataPing() override
+ {
+ if (mdata_hook)
+ mdata_hook(&mp);
+
+ if (free_data) {
+ for (const auto& node : data.buffers()) {
+ free(const_cast<void*>(static_cast<const void*>(node.c_str())));
+ }
+ }
+ }
+
+public:
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(tag, p);
+ decode(counter, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(tag, payload);
+ encode(counter, payload);
+ }
+
+ std::string_view get_type_name() const override { return "data_ping"; }
+
+ void print(ostream& out) const override {
+ out << get_type_name() << " " << tag << " " << counter;
+ }
+};
+
+#endif /* CEPH_MDATAPING_H */
diff --git a/src/messages/MDentryLink.h b/src/messages/MDentryLink.h
new file mode 100644
index 00000000..75dea9ba
--- /dev/null
+++ b/src/messages/MDentryLink.h
@@ -0,0 +1,75 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MDENTRYLINK_H
+#define CEPH_MDENTRYLINK_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+
+class MDentryLink : public MessageInstance<MDentryLink> {
+public:
+ friend factory;
+private:
+ dirfrag_t subtree;
+ dirfrag_t dirfrag;
+ string dn;
+ bool is_primary = false;
+
+ public:
+ dirfrag_t get_subtree() const { return subtree; }
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const string& get_dn() const { return dn; }
+ bool get_is_primary() const { return is_primary; }
+
+ bufferlist bl;
+
+protected:
+ MDentryLink() :
+ MessageInstance(MSG_MDS_DENTRYLINK) { }
+ MDentryLink(dirfrag_t r, dirfrag_t df, std::string_view n, bool p) :
+ MessageInstance(MSG_MDS_DENTRYLINK),
+ subtree(r),
+ dirfrag(df),
+ dn(n),
+ is_primary(p) {}
+ ~MDentryLink() override {}
+
+public:
+ std::string_view get_type_name() const override { return "dentry_link";}
+ void print(ostream& o) const override {
+ o << "dentry_link(" << dirfrag << " " << dn << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(subtree, p);
+ decode(dirfrag, p);
+ decode(dn, p);
+ decode(is_primary, p);
+ decode(bl, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(subtree, payload);
+ encode(dirfrag, payload);
+ encode(dn, payload);
+ encode(is_primary, payload);
+ encode(bl, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MDentryUnlink.h b/src/messages/MDentryUnlink.h
new file mode 100644
index 00000000..1d3d9715
--- /dev/null
+++ b/src/messages/MDentryUnlink.h
@@ -0,0 +1,67 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MDENTRYUNLINK_H
+#define CEPH_MDENTRYUNLINK_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+
+class MDentryUnlink : public MessageInstance<MDentryUnlink> {
+public:
+ friend factory;
+private:
+
+ dirfrag_t dirfrag;
+ string dn;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const string& get_dn() const { return dn; }
+
+ bufferlist straybl;
+ bufferlist snapbl;
+
+protected:
+ MDentryUnlink() :
+ MessageInstance(MSG_MDS_DENTRYUNLINK) { }
+ MDentryUnlink(dirfrag_t df, std::string_view n) :
+ MessageInstance(MSG_MDS_DENTRYUNLINK),
+ dirfrag(df),
+ dn(n) {}
+ ~MDentryUnlink() override {}
+
+public:
+ std::string_view get_type_name() const override { return "dentry_unlink";}
+ void print(ostream& o) const override {
+ o << "dentry_unlink(" << dirfrag << " " << dn << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(dn, p);
+ decode(straybl, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(dn, payload);
+ encode(straybl, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MDirUpdate.h b/src/messages/MDirUpdate.h
new file mode 100644
index 00000000..c1154ac7
--- /dev/null
+++ b/src/messages/MDirUpdate.h
@@ -0,0 +1,93 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MDIRUPDATE_H
+#define CEPH_MDIRUPDATE_H
+
+#include "msg/Message.h"
+
+class MDirUpdate : public MessageInstance<MDirUpdate> {
+public:
+ friend factory;
+
+ mds_rank_t get_source_mds() const { return from_mds; }
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ int get_dir_rep() const { return dir_rep; }
+ const std::set<int32_t>& get_dir_rep_by() const { return dir_rep_by; }
+ bool should_discover() const { return discover > tried_discover; }
+ const filepath& get_path() const { return path; }
+
+ bool has_tried_discover() const { return tried_discover > 0; }
+ void inc_tried_discover() const { ++tried_discover; }
+
+ std::string_view get_type_name() const override { return "dir_update"; }
+ void print(ostream& out) const override {
+ out << "dir_update(" << get_dirfrag() << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(from_mds, p);
+ decode(dirfrag, p);
+ decode(dir_rep, p);
+ decode(discover, p);
+ decode(dir_rep_by, p);
+ decode(path, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(from_mds, payload);
+ encode(dirfrag, payload);
+ encode(dir_rep, payload);
+ encode(discover, payload);
+ encode(dir_rep_by, payload);
+ encode(path, payload);
+ }
+
+protected:
+ ~MDirUpdate() {}
+ MDirUpdate() : MessageInstance(MSG_MDS_DIRUPDATE) {}
+ MDirUpdate(mds_rank_t f,
+ dirfrag_t dirfrag,
+ int dir_rep,
+ const std::set<int32_t>& dir_rep_by,
+ filepath& path,
+ bool discover = false) :
+ MessageInstance(MSG_MDS_DIRUPDATE), from_mds(f), dirfrag(dirfrag),
+ dir_rep(dir_rep), dir_rep_by(dir_rep_by), path(path) {
+ this->discover = discover ? 5 : 0;
+ }
+ MDirUpdate(const MDirUpdate& m)
+ : MessageInstance(MSG_MDS_DIRUPDATE),
+ from_mds(m.from_mds),
+ dirfrag(m.dirfrag),
+ dir_rep(m.dir_rep),
+ discover(m.discover),
+ dir_rep_by(m.dir_rep_by),
+ path(m.path),
+ tried_discover(m.tried_discover)
+ {}
+
+ mds_rank_t from_mds = -1;
+ dirfrag_t dirfrag;
+ int32_t dir_rep = 5;
+ int32_t discover = 5;
+ std::set<int32_t> dir_rep_by;
+ filepath path;
+ mutable int tried_discover = 0; // XXX HACK
+};
+
+#endif
diff --git a/src/messages/MDiscover.h b/src/messages/MDiscover.h
new file mode 100644
index 00000000..f4418e61
--- /dev/null
+++ b/src/messages/MDiscover.h
@@ -0,0 +1,97 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MDISCOVER_H
+#define CEPH_MDISCOVER_H
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+
+#include <string>
+
+
+class MDiscover : public MessageInstance<MDiscover> {
+public:
+ friend factory;
+private:
+
+ inodeno_t base_ino; // 1 -> root
+ frag_t base_dir_frag;
+
+ snapid_t snapid;
+ filepath want; // ... [/]need/this/stuff
+
+ bool want_base_dir = true;
+ bool want_xlocked = false;
+
+ public:
+ inodeno_t get_base_ino() const { return base_ino; }
+ frag_t get_base_dir_frag() const { return base_dir_frag; }
+ snapid_t get_snapid() const { return snapid; }
+
+ const filepath& get_want() const { return want; }
+ const std::string& get_dentry(int n) const { return want[n]; }
+
+ bool wants_base_dir() const { return want_base_dir; }
+ bool wants_xlocked() const { return want_xlocked; }
+
+ void set_base_dir_frag(frag_t f) { base_dir_frag = f; }
+
+protected:
+ MDiscover() : MessageInstance(MSG_MDS_DISCOVER) { }
+ MDiscover(inodeno_t base_ino_,
+ frag_t base_frag_,
+ snapid_t s,
+ filepath& want_path_,
+ bool want_base_dir_ = true,
+ bool discover_xlocks_ = false) :
+ MessageInstance(MSG_MDS_DISCOVER),
+ base_ino(base_ino_),
+ base_dir_frag(base_frag_),
+ snapid(s),
+ want(want_path_),
+ want_base_dir(want_base_dir_),
+ want_xlocked(discover_xlocks_) { }
+ ~MDiscover() override {}
+
+public:
+ std::string_view get_type_name() const override { return "Dis"; }
+ void print(ostream &out) const override {
+ out << "discover(" << header.tid << " " << base_ino << "." << base_dir_frag
+ << " " << want << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(base_ino, p);
+ decode(base_dir_frag, p);
+ decode(snapid, p);
+ decode(want, p);
+ decode(want_base_dir, p);
+ decode(want_xlocked, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(base_ino, payload);
+ encode(base_dir_frag, payload);
+ encode(snapid, payload);
+ encode(want, payload);
+ encode(want_base_dir, payload);
+ encode(want_xlocked, payload);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MDiscoverReply.h b/src/messages/MDiscoverReply.h
new file mode 100644
index 00000000..bd4f3475
--- /dev/null
+++ b/src/messages/MDiscoverReply.h
@@ -0,0 +1,212 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MDISCOVERREPLY_H
+#define CEPH_MDISCOVERREPLY_H
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+
+#include <string>
+
+
+
+/**
+ * MDiscoverReply - return new replicas (of inodes, dirs, dentries)
+ *
+ * we group returned items by (dir, dentry, inode). each
+ * item in each set shares an index (it's "depth").
+ *
+ * we can start and end with any type.
+ * no_base_dir = true if the first group has an inode but no dir
+ * no_base_dentry = true if the first group has an inode but no dentry
+ * they are false if there is no returned data, ie the first group is empty.
+ *
+ * we also return errors:
+ * error_flag_dn(std::string) - the specified dentry dne
+ * error_flag_dir - the last item wasn't a dir, so we couldn't continue.
+ *
+ * and sometimes,
+ * dir_auth_hint - where we think the dir auth is
+ *
+ * depth() gives us the number of depth units/indices for which we have
+ * information. this INCLUDES those for which we have errors but no data.
+ *
+ * see MDCache::handle_discover, handle_discover_reply.
+ *
+ *
+ * so basically, we get
+ *
+ * dir den ino i
+ * x 0
+ * x x x 1
+ * or
+ * x x 0
+ * x x x 1
+ * or
+ * x x x 0
+ * x x x 1
+ * ...and trail off however we want.
+ *
+ *
+ */
+
+class MDiscoverReply : public MessageInstance<MDiscoverReply> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+
+ // info about original request
+ inodeno_t base_ino;
+ frag_t base_dir_frag;
+ bool wanted_base_dir = false;
+ bool wanted_xlocked = false;
+ snapid_t wanted_snapid;
+
+ // and the response
+ bool flag_error_dn = false;
+ bool flag_error_dir = false;
+ std::string error_dentry; // dentry that was not found (to trigger waiters on asker)
+ bool unsolicited = false;
+
+ mds_rank_t dir_auth_hint = 0;
+
+ public:
+ __u8 starts_with = 0;
+ bufferlist trace;
+
+ enum { DIR, DENTRY, INODE };
+
+ // accessors
+ inodeno_t get_base_ino() const { return base_ino; }
+ frag_t get_base_dir_frag() const { return base_dir_frag; }
+ bool get_wanted_base_dir() const { return wanted_base_dir; }
+ bool get_wanted_xlocked() const { return wanted_xlocked; }
+ snapid_t get_wanted_snapid() const { return wanted_snapid; }
+
+ bool is_flag_error_dn() const { return flag_error_dn; }
+ bool is_flag_error_dir() const { return flag_error_dir; }
+ const std::string& get_error_dentry() const { return error_dentry; }
+
+ int get_starts_with() const { return starts_with; }
+
+ mds_rank_t get_dir_auth_hint() const { return dir_auth_hint; }
+
+ bool is_unsolicited() const { return unsolicited; }
+ void mark_unsolicited() { unsolicited = true; }
+
+ void set_base_dir_frag(frag_t df) { base_dir_frag = df; }
+
+protected:
+ MDiscoverReply() : MessageInstance(MSG_MDS_DISCOVERREPLY, HEAD_VERSION) { }
+ MDiscoverReply(const MDiscover &dis) :
+ MessageInstance(MSG_MDS_DISCOVERREPLY, HEAD_VERSION),
+ base_ino(dis.get_base_ino()),
+ base_dir_frag(dis.get_base_dir_frag()),
+ wanted_base_dir(dis.wants_base_dir()),
+ wanted_xlocked(dis.wants_xlocked()),
+ wanted_snapid(dis.get_snapid()),
+ flag_error_dn(false),
+ flag_error_dir(false),
+ unsolicited(false),
+ dir_auth_hint(CDIR_AUTH_UNKNOWN),
+ starts_with(DIR)
+ {
+ header.tid = dis.get_tid();
+ }
+ MDiscoverReply(dirfrag_t df) :
+ MessageInstance(MSG_MDS_DISCOVERREPLY, HEAD_VERSION),
+ base_ino(df.ino),
+ base_dir_frag(df.frag),
+ wanted_base_dir(false),
+ wanted_xlocked(false),
+ wanted_snapid(CEPH_NOSNAP),
+ flag_error_dn(false),
+ flag_error_dir(false),
+ unsolicited(false),
+ dir_auth_hint(CDIR_AUTH_UNKNOWN),
+ starts_with(DIR)
+ {
+ header.tid = 0;
+ }
+ ~MDiscoverReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "discover_reply"; }
+ void print(ostream& out) const override {
+ out << "discover_reply(" << header.tid << " " << base_ino << ")";
+ }
+
+ // builders
+ bool is_empty() const {
+ return trace.length() == 0 &&
+ !flag_error_dn &&
+ !flag_error_dir &&
+ dir_auth_hint == CDIR_AUTH_UNKNOWN;
+ }
+
+ // void set_flag_forward() { flag_forward = true; }
+ void set_flag_error_dn(std::string_view dn) {
+ flag_error_dn = true;
+ error_dentry = dn;
+ }
+ void set_flag_error_dir() {
+ flag_error_dir = true;
+ }
+ void set_dir_auth_hint(int a) {
+ dir_auth_hint = a;
+ }
+ void set_error_dentry(std::string_view dn) {
+ error_dentry = dn;
+ }
+
+
+ // ...
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(base_ino, p);
+ decode(base_dir_frag, p);
+ decode(wanted_base_dir, p);
+ decode(wanted_xlocked, p);
+ decode(wanted_snapid, p);
+ decode(flag_error_dn, p);
+ decode(flag_error_dir, p);
+ decode(error_dentry, p);
+ decode(dir_auth_hint, p);
+ decode(unsolicited, p);
+
+ decode(starts_with, p);
+ decode(trace, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(base_ino, payload);
+ encode(base_dir_frag, payload);
+ encode(wanted_base_dir, payload);
+ encode(wanted_xlocked, payload);
+ encode(wanted_snapid, payload);
+ encode(flag_error_dn, payload);
+ encode(flag_error_dir, payload);
+ encode(error_dentry, payload);
+ encode(dir_auth_hint, payload);
+ encode(unsolicited, payload);
+
+ encode(starts_with, payload);
+ encode(trace, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportCaps.h b/src/messages/MExportCaps.h
new file mode 100644
index 00000000..93e53b0f
--- /dev/null
+++ b/src/messages/MExportCaps.h
@@ -0,0 +1,63 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MEXPORTCAPS_H
+#define CEPH_MEXPORTCAPS_H
+
+#include "msg/Message.h"
+
+
+class MExportCaps : public MessageInstance<MExportCaps> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ inodeno_t ino;
+ bufferlist cap_bl;
+ map<client_t,entity_inst_t> client_map;
+ map<client_t,client_metadata_t> client_metadata_map;
+
+protected:
+ MExportCaps() :
+ MessageInstance(MSG_MDS_EXPORTCAPS, HEAD_VERSION, COMPAT_VERSION) {}
+ ~MExportCaps() override {}
+
+public:
+ std::string_view get_type_name() const override { return "export_caps"; }
+ void print(ostream& o) const override {
+ o << "export_caps(" << ino << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(cap_bl, payload);
+ encode(client_map, payload, features);
+ encode(client_metadata_map, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(cap_bl, p);
+ decode(client_map, p);
+ if (header.version >= 2)
+ decode(client_metadata_map, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MExportCapsAck.h b/src/messages/MExportCapsAck.h
new file mode 100644
index 00000000..d159161e
--- /dev/null
+++ b/src/messages/MExportCapsAck.h
@@ -0,0 +1,54 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MEXPORTCAPSACK_H
+#define CEPH_MEXPORTCAPSACK_H
+
+#include "msg/Message.h"
+
+
+class MExportCapsAck : public MessageInstance<MExportCapsAck> {
+public:
+ friend factory;
+
+ inodeno_t ino;
+ bufferlist cap_bl;
+
+protected:
+ MExportCapsAck() :
+ MessageInstance(MSG_MDS_EXPORTCAPSACK) {}
+ MExportCapsAck(inodeno_t i) :
+ MessageInstance(MSG_MDS_EXPORTCAPSACK), ino(i) {}
+ ~MExportCapsAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "export_caps_ack"; }
+ void print(ostream& o) const override {
+ o << "export_caps_ack(" << ino << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(cap_bl, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(cap_bl, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportDir.h b/src/messages/MExportDir.h
new file mode 100644
index 00000000..8f509e03
--- /dev/null
+++ b/src/messages/MExportDir.h
@@ -0,0 +1,65 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MEXPORTDIR_H
+#define CEPH_MEXPORTDIR_H
+
+#include "msg/Message.h"
+
+
+class MExportDir : public MessageInstance<MExportDir> {
+public:
+ friend factory;
+ dirfrag_t dirfrag;
+ bufferlist export_data;
+ vector<dirfrag_t> bounds;
+ bufferlist client_map;
+
+protected:
+ MExportDir() : MessageInstance(MSG_MDS_EXPORTDIR) {}
+ MExportDir(dirfrag_t df, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIR), dirfrag(df) {
+ set_tid(tid);
+ }
+ ~MExportDir() override {}
+
+public:
+ std::string_view get_type_name() const override { return "Ex"; }
+ void print(ostream& o) const override {
+ o << "export(" << dirfrag << ")";
+ }
+
+ void add_export(dirfrag_t df) {
+ bounds.push_back(df);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(bounds, payload);
+ encode(export_data, payload);
+ encode(client_map, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(bounds, p);
+ decode(export_data, p);
+ decode(client_map, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MExportDirAck.h b/src/messages/MExportDirAck.h
new file mode 100644
index 00000000..ff8be816
--- /dev/null
+++ b/src/messages/MExportDirAck.h
@@ -0,0 +1,57 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRACK_H
+#define CEPH_MEXPORTDIRACK_H
+
+#include "MExportDir.h"
+#include "msg/Message.h"
+
+class MExportDirAck : public MessageInstance<MExportDirAck> {
+public:
+ friend factory;
+
+ dirfrag_t dirfrag;
+ bufferlist imported_caps;
+
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+
+protected:
+ MExportDirAck() : MessageInstance(MSG_MDS_EXPORTDIRACK) {}
+ MExportDirAck(dirfrag_t df, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIRACK), dirfrag(df) {
+ set_tid(tid);
+ }
+ ~MExportDirAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExAck"; }
+ void print(ostream& o) const override {
+ o << "export_ack(" << dirfrag << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(imported_caps, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(imported_caps, payload);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MExportDirCancel.h b/src/messages/MExportDirCancel.h
new file mode 100644
index 00000000..56f2c4d1
--- /dev/null
+++ b/src/messages/MExportDirCancel.h
@@ -0,0 +1,54 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRCANCEL_H
+#define CEPH_MEXPORTDIRCANCEL_H
+
+#include "msg/Message.h"
+#include "include/types.h"
+
+class MExportDirCancel : public MessageInstance<MExportDirCancel> {
+public:
+ friend factory;
+private:
+ dirfrag_t dirfrag;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+
+protected:
+ MExportDirCancel() : MessageInstance(MSG_MDS_EXPORTDIRCANCEL) {}
+ MExportDirCancel(dirfrag_t df, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIRCANCEL), dirfrag(df) {
+ set_tid(tid);
+ }
+ ~MExportDirCancel() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExCancel"; }
+ void print(ostream& o) const override {
+ o << "export_cancel(" << dirfrag << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportDirDiscover.h b/src/messages/MExportDirDiscover.h
new file mode 100644
index 00000000..74f298bc
--- /dev/null
+++ b/src/messages/MExportDirDiscover.h
@@ -0,0 +1,69 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRDISCOVER_H
+#define CEPH_MEXPORTDIRDISCOVER_H
+
+#include "msg/Message.h"
+#include "include/types.h"
+
+class MExportDirDiscover : public MessageInstance<MExportDirDiscover> {
+public:
+ friend factory;
+private:
+ mds_rank_t from = -1;
+ dirfrag_t dirfrag;
+ filepath path;
+
+ public:
+ mds_rank_t get_source_mds() const { return from; }
+ inodeno_t get_ino() const { return dirfrag.ino; }
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const filepath& get_path() const { return path; }
+
+ bool started;
+
+protected:
+ MExportDirDiscover() :
+ MessageInstance(MSG_MDS_EXPORTDIRDISCOVER),
+ started(false) { }
+ MExportDirDiscover(dirfrag_t df, filepath& p, mds_rank_t f, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIRDISCOVER),
+ from(f), dirfrag(df), path(p), started(false) {
+ set_tid(tid);
+ }
+ ~MExportDirDiscover() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExDis"; }
+ void print(ostream& o) const override {
+ o << "export_discover(" << dirfrag << " " << path << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(from, p);
+ decode(dirfrag, p);
+ decode(path, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(from, payload);
+ encode(dirfrag, payload);
+ encode(path, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportDirDiscoverAck.h b/src/messages/MExportDirDiscoverAck.h
new file mode 100644
index 00000000..ba8fda56
--- /dev/null
+++ b/src/messages/MExportDirDiscoverAck.h
@@ -0,0 +1,64 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRDISCOVERACK_H
+#define CEPH_MEXPORTDIRDISCOVERACK_H
+
+#include "msg/Message.h"
+#include "include/types.h"
+
+class MExportDirDiscoverAck : public MessageInstance<MExportDirDiscoverAck> {
+public:
+ friend factory;
+private:
+ dirfrag_t dirfrag;
+ bool success;
+
+ public:
+ inodeno_t get_ino() const { return dirfrag.ino; }
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ bool is_success() const { return success; }
+
+protected:
+ MExportDirDiscoverAck() : MessageInstance(MSG_MDS_EXPORTDIRDISCOVERACK) {}
+ MExportDirDiscoverAck(dirfrag_t df, uint64_t tid, bool s=true) :
+ MessageInstance(MSG_MDS_EXPORTDIRDISCOVERACK),
+ dirfrag(df), success(s) {
+ set_tid(tid);
+ }
+ ~MExportDirDiscoverAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExDisA"; }
+ void print(ostream& o) const override {
+ o << "export_discover_ack(" << dirfrag;
+ if (success)
+ o << " success)";
+ else
+ o << " failure)";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(success, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(success, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportDirFinish.h b/src/messages/MExportDirFinish.h
new file mode 100644
index 00000000..6cc35d09
--- /dev/null
+++ b/src/messages/MExportDirFinish.h
@@ -0,0 +1,58 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRFINISH_H
+#define CEPH_MEXPORTDIRFINISH_H
+
+#include "msg/Message.h"
+
+class MExportDirFinish : public MessageInstance<MExportDirFinish> {
+public:
+ friend factory;
+private:
+ dirfrag_t dirfrag;
+ bool last;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ bool is_last() const { return last; }
+
+protected:
+ MExportDirFinish() : last(false) {}
+ MExportDirFinish(dirfrag_t df, bool l, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIRFINISH), dirfrag(df), last(l) {
+ set_tid(tid);
+ }
+ ~MExportDirFinish() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExFin"; }
+ void print(ostream& o) const override {
+ o << "export_finish(" << dirfrag << (last ? " last" : "") << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(last, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(last, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MExportDirNotify.h b/src/messages/MExportDirNotify.h
new file mode 100644
index 00000000..fbb7a30b
--- /dev/null
+++ b/src/messages/MExportDirNotify.h
@@ -0,0 +1,84 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRNOTIFY_H
+#define CEPH_MEXPORTDIRNOTIFY_H
+
+#include "msg/Message.h"
+
+class MExportDirNotify : public MessageInstance<MExportDirNotify> {
+public:
+ friend factory;
+private:
+ dirfrag_t base;
+ bool ack;
+ pair<__s32,__s32> old_auth, new_auth;
+ list<dirfrag_t> bounds; // bounds; these dirs are _not_ included (tho the dirfragdes are)
+
+ public:
+ dirfrag_t get_dirfrag() const { return base; }
+ pair<__s32,__s32> get_old_auth() const { return old_auth; }
+ pair<__s32,__s32> get_new_auth() const { return new_auth; }
+ bool wants_ack() const { return ack; }
+ const list<dirfrag_t>& get_bounds() const { return bounds; }
+ list<dirfrag_t>& get_bounds() { return bounds; }
+
+protected:
+ MExportDirNotify() {}
+ MExportDirNotify(dirfrag_t i, uint64_t tid, bool a, pair<__s32,__s32> oa, pair<__s32,__s32> na) :
+ MessageInstance(MSG_MDS_EXPORTDIRNOTIFY),
+ base(i), ack(a), old_auth(oa), new_auth(na) {
+ set_tid(tid);
+ }
+ ~MExportDirNotify() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExNot"; }
+ void print(ostream& o) const override {
+ o << "export_notify(" << base;
+ o << " " << old_auth << " -> " << new_auth;
+ if (ack)
+ o << " ack)";
+ else
+ o << " no ack)";
+ }
+
+ void copy_bounds(list<dirfrag_t>& ex) {
+ this->bounds = ex;
+ }
+ void copy_bounds(set<dirfrag_t>& ex) {
+ for (set<dirfrag_t>::iterator i = ex.begin();
+ i != ex.end(); ++i)
+ bounds.push_back(*i);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(base, payload);
+ encode(ack, payload);
+ encode(old_auth, payload);
+ encode(new_auth, payload);
+ encode(bounds, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(base, p);
+ decode(ack, p);
+ decode(old_auth, p);
+ decode(new_auth, p);
+ decode(bounds, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportDirNotifyAck.h b/src/messages/MExportDirNotifyAck.h
new file mode 100644
index 00000000..05f77167
--- /dev/null
+++ b/src/messages/MExportDirNotifyAck.h
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRNOTIFYACK_H
+#define CEPH_MEXPORTDIRNOTIFYACK_H
+
+#include "msg/Message.h"
+
+class MExportDirNotifyAck : public MessageInstance<MExportDirNotifyAck> {
+public:
+ friend factory;
+private:
+ dirfrag_t dirfrag;
+ pair<__s32,__s32> new_auth;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ pair<__s32,__s32> get_new_auth() const { return new_auth; }
+
+protected:
+ MExportDirNotifyAck() {}
+ MExportDirNotifyAck(dirfrag_t df, uint64_t tid, pair<__s32,__s32> na) :
+ MessageInstance(MSG_MDS_EXPORTDIRNOTIFYACK), dirfrag(df), new_auth(na) {
+ set_tid(tid);
+ }
+ ~MExportDirNotifyAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExNotA"; }
+ void print(ostream& o) const override {
+ o << "export_notify_ack(" << dirfrag << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(new_auth, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(new_auth, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MExportDirPrep.h b/src/messages/MExportDirPrep.h
new file mode 100644
index 00000000..e10d4f24
--- /dev/null
+++ b/src/messages/MExportDirPrep.h
@@ -0,0 +1,90 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MEXPORTDIRPREP_H
+#define CEPH_MEXPORTDIRPREP_H
+
+#include "msg/Message.h"
+#include "include/types.h"
+
+class MExportDirPrep : public MessageInstance<MExportDirPrep> {
+public:
+ friend factory;
+private:
+ dirfrag_t dirfrag;
+ public:
+ bufferlist basedir;
+ list<dirfrag_t> bounds;
+ list<bufferlist> traces;
+private:
+ set<mds_rank_t> bystanders;
+ bool b_did_assim;
+
+public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const list<dirfrag_t>& get_bounds() const { return bounds; }
+ const set<mds_rank_t> &get_bystanders() const { return bystanders; }
+
+ bool did_assim() const { return b_did_assim; }
+ void mark_assim() { b_did_assim = true; }
+
+protected:
+ MExportDirPrep() {
+ b_did_assim = false;
+ }
+ MExportDirPrep(dirfrag_t df, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIRPREP),
+ dirfrag(df), b_did_assim(false) {
+ set_tid(tid);
+ }
+ ~MExportDirPrep() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ExP"; }
+ void print(ostream& o) const override {
+ o << "export_prep(" << dirfrag << ")";
+ }
+
+ void add_bound(dirfrag_t df) {
+ bounds.push_back( df );
+ }
+ void add_trace(bufferlist& bl) {
+ traces.push_back(bl);
+ }
+ void add_bystander(mds_rank_t who) {
+ bystanders.insert(who);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(basedir, p);
+ decode(bounds, p);
+ decode(traces, p);
+ decode(bystanders, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(basedir, payload);
+ encode(bounds, payload);
+ encode(traces, payload);
+ encode(bystanders, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MExportDirPrepAck.h b/src/messages/MExportDirPrepAck.h
new file mode 100644
index 00000000..11e59a8d
--- /dev/null
+++ b/src/messages/MExportDirPrepAck.h
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MEXPORTDIRPREPACK_H
+#define CEPH_MEXPORTDIRPREPACK_H
+
+#include "msg/Message.h"
+#include "include/types.h"
+
+class MExportDirPrepAck : public MessageInstance<MExportDirPrepAck> {
+public:
+ friend factory;
+private:
+ dirfrag_t dirfrag;
+ bool success = false;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+
+protected:
+ MExportDirPrepAck() {}
+ MExportDirPrepAck(dirfrag_t df, bool s, uint64_t tid) :
+ MessageInstance(MSG_MDS_EXPORTDIRPREPACK), dirfrag(df), success(s) {
+ set_tid(tid);
+ }
+ ~MExportDirPrepAck() override {}
+
+public:
+ bool is_success() const { return success; }
+ std::string_view get_type_name() const override { return "ExPAck"; }
+ void print(ostream& o) const override {
+ o << "export_prep_ack(" << dirfrag << (success ? " success)" : " fail)");
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(success, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(success, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MFSMap.h b/src/messages/MFSMap.h
new file mode 100644
index 00000000..99f241d5
--- /dev/null
+++ b/src/messages/MFSMap.h
@@ -0,0 +1,64 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MFSMAP_H
+#define CEPH_MFSMAP_H
+
+#include "msg/Message.h"
+#include "mds/FSMap.h"
+#include "include/ceph_features.h"
+
+class MFSMap : public MessageInstance<MFSMap> {
+public:
+ friend factory;
+
+ epoch_t epoch;
+ bufferlist encoded;
+
+ version_t get_epoch() const { return epoch; }
+ const FSMap& get_fsmap() const {return fsmap;}
+
+ MFSMap() :
+ MessageInstance(CEPH_MSG_FS_MAP), epoch(0) {}
+ MFSMap(const uuid_d &f, const FSMap &fsmap_) :
+ MessageInstance(CEPH_MSG_FS_MAP), epoch(fsmap_.get_epoch())
+ {
+ fsmap = fsmap_;
+ }
+private:
+ FSMap fsmap;
+
+ ~MFSMap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "fsmap"; }
+ void print(ostream& out) const override {
+ out << "fsmap(e " << epoch << ")";
+ }
+
+ // marshalling
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(fsmap, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(fsmap, payload, features);
+ }
+};
+
+#endif
diff --git a/src/messages/MFSMapUser.h b/src/messages/MFSMapUser.h
new file mode 100644
index 00000000..215b1211
--- /dev/null
+++ b/src/messages/MFSMapUser.h
@@ -0,0 +1,62 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ */
+
+
+#ifndef CEPH_MFSMAPCOMPACT_H
+#define CEPH_MFSMAPCOMPACT_H
+
+#include "msg/Message.h"
+#include "mds/FSMapUser.h"
+#include "include/ceph_features.h"
+
+class MFSMapUser : public MessageInstance<MFSMapUser> {
+public:
+ friend factory;
+
+ epoch_t epoch;
+
+ version_t get_epoch() const { return epoch; }
+ const FSMapUser& get_fsmap() const { return fsmap; }
+
+ MFSMapUser() :
+ MessageInstance(CEPH_MSG_FS_MAP_USER), epoch(0) {}
+ MFSMapUser(const uuid_d &f, const FSMapUser &fsmap_) :
+ MessageInstance(CEPH_MSG_FS_MAP_USER), epoch(fsmap_.epoch)
+ {
+ fsmap = fsmap_;
+ }
+private:
+ FSMapUser fsmap;
+
+ ~MFSMapUser() override {}
+
+public:
+ std::string_view get_type_name() const override { return "fsmap.user"; }
+ void print(ostream& out) const override {
+ out << "fsmap.user(e " << epoch << ")";
+ }
+
+ // marshalling
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(fsmap, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(fsmap, payload, features);
+ }
+};
+
+#endif
diff --git a/src/messages/MForward.h b/src/messages/MForward.h
new file mode 100644
index 00000000..7f552ca1
--- /dev/null
+++ b/src/messages/MForward.h
@@ -0,0 +1,156 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ * Client requests often need to get forwarded from some monitor
+ * to the leader. This class encapsulates the original message
+ * along with the client's caps so the leader can do proper permissions
+ * checking.
+ */
+
+#ifndef CEPH_MFORWARD_H
+#define CEPH_MFORWARD_H
+
+#include "msg/Message.h"
+#include "mon/MonCap.h"
+#include "include/encoding.h"
+#include "include/stringify.h"
+
+class MForward : public MessageInstance<MForward> {
+public:
+ friend factory;
+
+ uint64_t tid;
+ uint8_t client_type;
+ entity_addrvec_t client_addrs;
+ entity_addr_t client_socket_addr;
+ MonCap client_caps;
+ uint64_t con_features;
+ EntityName entity_name;
+ PaxosServiceMessage *msg; // incoming or outgoing message
+
+ string msg_desc; // for operator<< only
+
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 4;
+
+ MForward() : MessageInstance(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
+ tid(0), con_features(0), msg(NULL) {}
+ MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat,
+ const MonCap& caps) :
+ MessageInstance(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
+ tid(t), client_caps(caps), msg(NULL) {
+ client_type = m->get_source().type();
+ client_addrs = m->get_source_addrs();
+ if (auto con = m->get_connection()) {
+ client_socket_addr = con->get_peer_socket_addr();
+ }
+ con_features = feat;
+ msg = (PaxosServiceMessage*)m->get();
+ }
+private:
+ ~MForward() override {
+ if (msg) {
+ // message was unclaimed
+ msg->put();
+ msg = NULL;
+ }
+ }
+
+public:
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ header.version = 3;
+ header.compat_version = 3;
+ encode(tid, payload);
+ entity_inst_t client;
+ client.name = entity_name_t(client_type, -1);
+ client.addr = client_addrs.legacy_addr();
+ encode(client, payload, features);
+ encode(client_caps, payload, features);
+ // Encode client message with intersection of target and source
+ // features. This could matter if the semantics of the encoded
+ // message are changed when reencoding with more features than the
+ // client had originally. That should never happen, but we may as
+ // well be defensive here.
+ if (con_features != features) {
+ msg->clear_payload();
+ }
+ encode_message(msg, features & con_features, payload);
+ encode(con_features, payload);
+ encode(entity_name, payload);
+ return;
+ }
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(tid, payload);
+ encode(client_type, payload, features);
+ encode(client_addrs, payload, features);
+ encode(client_socket_addr, payload, features);
+ encode(client_caps, payload, features);
+ // Encode client message with intersection of target and source
+ // features. This could matter if the semantics of the encoded
+ // message are changed when reencoding with more features than the
+ // client had originally. That should never happen, but we may as
+ // well be defensive here.
+ if (con_features != features) {
+ msg->clear_payload();
+ }
+ encode_message(msg, features & con_features, payload);
+ encode(con_features, payload);
+ encode(entity_name, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(tid, p);
+ if (header.version < 4) {
+ entity_inst_t client;
+ decode(client, p);
+ client_type = client.name.type();
+ client_addrs = entity_addrvec_t(client.addr);
+ client_socket_addr = client.addr;
+ } else {
+ decode(client_type, p);
+ decode(client_addrs, p);
+ decode(client_socket_addr, p);
+ }
+ decode(client_caps, p);
+ msg = (PaxosServiceMessage *)decode_message(NULL, 0, p);
+ decode(con_features, p);
+ decode(entity_name, p);
+ }
+
+ PaxosServiceMessage *claim_message() {
+ // let whoever is claiming the message deal with putting it.
+ ceph_assert(msg);
+ msg_desc = stringify(*msg);
+ PaxosServiceMessage *m = msg;
+ msg = NULL;
+ return m;
+ }
+
+ std::string_view get_type_name() const override { return "forward"; }
+ void print(ostream& o) const override {
+ o << "forward(";
+ if (msg) {
+ o << *msg;
+ } else {
+ o << msg_desc;
+ }
+ o << " caps " << client_caps
+ << " tid " << tid
+ << " con_features " << con_features << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MGatherCaps.h b/src/messages/MGatherCaps.h
new file mode 100644
index 00000000..fe8b4187
--- /dev/null
+++ b/src/messages/MGatherCaps.h
@@ -0,0 +1,37 @@
+#ifndef CEPH_MGATHERCAPS_H
+#define CEPH_MGATHERCAPS_H
+
+#include "msg/Message.h"
+
+
+class MGatherCaps : public MessageInstance<MGatherCaps> {
+public:
+ friend factory;
+
+
+ inodeno_t ino;
+
+protected:
+ MGatherCaps() :
+ MessageInstance(MSG_MDS_GATHERCAPS) {}
+ ~MGatherCaps() override {}
+
+public:
+ std::string_view get_type_name() const override { return "gather_caps"; }
+ void print(ostream& o) const override {
+ o << "gather_caps(" << ino << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MGenericMessage.h b/src/messages/MGenericMessage.h
new file mode 100644
index 00000000..49e906d6
--- /dev/null
+++ b/src/messages/MGenericMessage.h
@@ -0,0 +1,42 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MGENERICMESSAGE_H
+#define CEPH_MGENERICMESSAGE_H
+
+#include "msg/Message.h"
+
+class MGenericMessage : public MessageInstance<MGenericMessage> {
+public:
+ friend factory;
+private:
+ char tname[20];
+ //long pcid;
+
+ public:
+ MGenericMessage(int t=0) : MessageInstance(t) {
+ snprintf(tname, sizeof(tname), "generic%d", get_type());
+ }
+
+ //void set_pcid(long pcid) { this->pcid = pcid; }
+ //long get_pcid() { return pcid; }
+
+ std::string_view get_type_name() const override { return tname; }
+
+ void decode_payload() override { }
+ void encode_payload(uint64_t features) override { }
+};
+
+#endif
diff --git a/src/messages/MGetConfig.h b/src/messages/MGetConfig.h
new file mode 100644
index 00000000..0e548576
--- /dev/null
+++ b/src/messages/MGetConfig.h
@@ -0,0 +1,50 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+
+class MGetConfig : public MessageInstance<MGetConfig> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ EntityName name; ///< e.g., mon.a, client.foo
+ string host; ///< our hostname
+ string device_class;
+
+ MGetConfig() : MessageInstance(MSG_GET_CONFIG, HEAD_VERSION, COMPAT_VERSION) { }
+ MGetConfig(const EntityName& n, const string& h)
+ : MessageInstance(MSG_GET_CONFIG, HEAD_VERSION, COMPAT_VERSION),
+ name(n),
+ host(h) {}
+
+ std::string_view get_type_name() const override {
+ return "get_config";
+ }
+ void print(ostream& o) const override {
+ o << "get_config(" << name << "@" << host;
+ if (device_class.size()) {
+ o << " device_class " << device_class;
+ }
+ o << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(name, p);
+ decode(host, p);
+ decode(device_class, p);
+ }
+
+ void encode_payload(uint64_t) override {
+ using ceph::encode;
+ encode(name, payload);
+ encode(host, payload);
+ encode(device_class, payload);
+ }
+};
diff --git a/src/messages/MGetPoolStats.h b/src/messages/MGetPoolStats.h
new file mode 100644
index 00000000..54ee08f6
--- /dev/null
+++ b/src/messages/MGetPoolStats.h
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MGETPOOLSTATS_H
+#define CEPH_MGETPOOLSTATS_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MGetPoolStats : public MessageInstance<MGetPoolStats, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ uuid_d fsid;
+ list<string> pools;
+
+ MGetPoolStats() : MessageInstance(MSG_GETPOOLSTATS, 0) {}
+ MGetPoolStats(const uuid_d& f, ceph_tid_t t, list<string>& ls, version_t l) :
+ MessageInstance(MSG_GETPOOLSTATS, l),
+ fsid(f), pools(ls) {
+ set_tid(t);
+ }
+
+private:
+ ~MGetPoolStats() override {}
+
+public:
+ std::string_view get_type_name() const override { return "getpoolstats"; }
+ void print(ostream& out) const override {
+ out << "getpoolstats(" << get_tid() << " " << pools << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(pools, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(pools, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MGetPoolStatsReply.h b/src/messages/MGetPoolStatsReply.h
new file mode 100644
index 00000000..8af58584
--- /dev/null
+++ b/src/messages/MGetPoolStatsReply.h
@@ -0,0 +1,72 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MGETPOOLSTATSREPLY_H
+#define CEPH_MGETPOOLSTATSREPLY_H
+
+class MGetPoolStatsReply : public MessageInstance<MGetPoolStatsReply, PaxosServiceMessage> {
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ friend factory;
+
+ uuid_d fsid;
+ map<string,pool_stat_t> pool_stats;
+ bool per_pool = false;
+
+ MGetPoolStatsReply() : MessageInstance(MSG_GETPOOLSTATSREPLY, 0,
+ HEAD_VERSION, COMPAT_VERSION) {}
+ MGetPoolStatsReply(uuid_d& f, ceph_tid_t t, version_t v) :
+ MessageInstance(MSG_GETPOOLSTATSREPLY, v,
+ HEAD_VERSION, COMPAT_VERSION),
+ fsid(f) {
+ set_tid(t);
+ }
+
+private:
+ ~MGetPoolStatsReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "getpoolstats"; }
+ void print(ostream& out) const override {
+ out << "getpoolstatsreply(" << get_tid();
+ if (per_pool)
+ out << " per_pool";
+ out << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(pool_stats, payload, features);
+ encode(per_pool, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(pool_stats, p);
+ if (header.version >= 2) {
+ decode(per_pool, p);
+ } else {
+ per_pool = false;
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MHeartbeat.h b/src/messages/MHeartbeat.h
new file mode 100644
index 00000000..50259619
--- /dev/null
+++ b/src/messages/MHeartbeat.h
@@ -0,0 +1,65 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MHEARTBEAT_H
+#define CEPH_MHEARTBEAT_H
+
+#include "include/types.h"
+#include "msg/Message.h"
+#include "common/DecayCounter.h"
+
+class MHeartbeat : public MessageInstance<MHeartbeat> {
+public:
+ friend factory;
+private:
+ mds_load_t load;
+ __s32 beat = 0;
+ map<mds_rank_t, float> import_map;
+
+ public:
+ const mds_load_t& get_load() const { return load; }
+ int get_beat() const { return beat; }
+
+ const map<mds_rank_t, float>& get_import_map() const { return import_map; }
+ map<mds_rank_t, float>& get_import_map() { return import_map; }
+
+protected:
+ MHeartbeat() : MessageInstance(MSG_MDS_HEARTBEAT), load(DecayRate()) {}
+ MHeartbeat(mds_load_t& load, int beat)
+ : MessageInstance(MSG_MDS_HEARTBEAT),
+ load(load) {
+ this->beat = beat;
+ }
+ ~MHeartbeat() override {}
+
+public:
+ std::string_view get_type_name() const override { return "HB"; }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(load, payload);
+ encode(beat, payload);
+ encode(import_map, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(load, p);
+ decode(beat, p);
+ decode(import_map, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MInodeFileCaps.h b/src/messages/MInodeFileCaps.h
new file mode 100644
index 00000000..0d32dcd7
--- /dev/null
+++ b/src/messages/MInodeFileCaps.h
@@ -0,0 +1,61 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MINODEFILECAPS_H
+#define CEPH_MINODEFILECAPS_H
+
+#include "msg/Message.h"
+
+class MInodeFileCaps : public MessageInstance<MInodeFileCaps> {
+public:
+ friend factory;
+private:
+ inodeno_t ino;
+ __u32 caps = 0;
+
+ public:
+
+ inodeno_t get_ino() const { return ino; }
+ int get_caps() const { return caps; }
+
+protected:
+ MInodeFileCaps() : MessageInstance(MSG_MDS_INODEFILECAPS) {}
+ MInodeFileCaps(inodeno_t ino, int caps) :
+ MessageInstance(MSG_MDS_INODEFILECAPS) {
+ this->ino = ino;
+ this->caps = caps;
+ }
+ ~MInodeFileCaps() override {}
+
+public:
+ std::string_view get_type_name() const override { return "inode_file_caps";}
+ void print(ostream& out) const override {
+ out << "inode_file_caps(" << ino << " " << ccap_string(caps) << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(caps, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(caps, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MLock.h b/src/messages/MLock.h
new file mode 100644
index 00000000..decaabae
--- /dev/null
+++ b/src/messages/MLock.h
@@ -0,0 +1,103 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MLOCK_H
+#define CEPH_MLOCK_H
+
+#include "msg/Message.h"
+#include "mds/locks.h"
+#include "mds/SimpleLock.h"
+
+class MLock : public MessageInstance<MLock> {
+public:
+ friend factory;
+private:
+ int32_t action = 0; // action type
+ mds_rank_t asker = 0; // who is initiating this request
+ metareqid_t reqid; // for remote lock requests
+
+ __u16 lock_type = 0; // lock object type
+ MDSCacheObjectInfo object_info;
+
+ bufferlist lockdata; // and possibly some data
+
+public:
+ bufferlist& get_data() { return lockdata; }
+ const bufferlist& get_data() const { return lockdata; }
+ int get_asker() const { return asker; }
+ int get_action() const { return action; }
+ metareqid_t get_reqid() const { return reqid; }
+
+ int get_lock_type() const { return lock_type; }
+ const MDSCacheObjectInfo &get_object_info() const { return object_info; }
+ MDSCacheObjectInfo &get_object_info() { return object_info; }
+
+protected:
+ MLock() : MessageInstance(MSG_MDS_LOCK) {}
+ MLock(int ac, mds_rank_t as) :
+ MessageInstance(MSG_MDS_LOCK),
+ action(ac), asker(as),
+ lock_type(0) { }
+ MLock(SimpleLock *lock, int ac, mds_rank_t as) :
+ MessageInstance(MSG_MDS_LOCK),
+ action(ac), asker(as),
+ lock_type(lock->get_type()) {
+ lock->get_parent()->set_object_info(object_info);
+ }
+ MLock(SimpleLock *lock, int ac, mds_rank_t as, bufferlist& bl) :
+ MessageInstance(MSG_MDS_LOCK),
+ action(ac), asker(as), lock_type(lock->get_type()) {
+ lock->get_parent()->set_object_info(object_info);
+ lockdata.claim(bl);
+ }
+ ~MLock() override {}
+
+public:
+ std::string_view get_type_name() const override { return "ILock"; }
+ void print(ostream& out) const override {
+ out << "lock(a=" << SimpleLock::get_lock_action_name(action)
+ << " " << SimpleLock::get_lock_type_name(lock_type)
+ << " " << object_info
+ << ")";
+ }
+
+ void set_reqid(metareqid_t ri) { reqid = ri; }
+ void set_data(const bufferlist& lockdata) {
+ this->lockdata = lockdata;
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(asker, p);
+ decode(action, p);
+ decode(reqid, p);
+ decode(lock_type, p);
+ decode(object_info, p);
+ decode(lockdata, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(asker, payload);
+ encode(action, payload);
+ encode(reqid, payload);
+ encode(lock_type, payload);
+ encode(object_info, payload);
+ encode(lockdata, payload);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MLog.h b/src/messages/MLog.h
new file mode 100644
index 00000000..d2c6e9e9
--- /dev/null
+++ b/src/messages/MLog.h
@@ -0,0 +1,61 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MLOG_H
+#define CEPH_MLOG_H
+
+#include "common/LogEntry.h"
+#include "messages/PaxosServiceMessage.h"
+
+#include <deque>
+
+class MLog : public MessageInstance<MLog, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ uuid_d fsid;
+ std::deque<LogEntry> entries;
+
+ MLog() : MessageInstance(MSG_LOG, 0) {}
+ MLog(const uuid_d& f, const std::deque<LogEntry>& e)
+ : MessageInstance(MSG_LOG, 0), fsid(f), entries(e) { }
+ MLog(const uuid_d& f) : MessageInstance(MSG_LOG, 0), fsid(f) { }
+private:
+ ~MLog() override {}
+
+public:
+ std::string_view get_type_name() const override { return "log"; }
+ void print(ostream& out) const override {
+ out << "log(";
+ if (entries.size())
+ out << entries.size() << " entries from seq " << entries.front().seq
+ << " at " << entries.front().stamp;
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(entries, payload, features);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(entries, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MLogAck.h b/src/messages/MLogAck.h
new file mode 100644
index 00000000..012c758d
--- /dev/null
+++ b/src/messages/MLogAck.h
@@ -0,0 +1,53 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MLOGACK_H
+#define CEPH_MLOGACK_H
+
+class MLogAck : public MessageInstance<MLogAck> {
+public:
+ friend factory;
+
+ uuid_d fsid;
+ version_t last = 0;
+ std::string channel;
+
+ MLogAck() : MessageInstance(MSG_LOGACK) {}
+ MLogAck(uuid_d& f, version_t l) : MessageInstance(MSG_LOGACK), fsid(f), last(l) {}
+private:
+ ~MLogAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "log_ack"; }
+ void print(ostream& out) const override {
+ out << "log(last " << last << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(fsid, payload);
+ encode(last, payload);
+ encode(channel, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(last, p);
+ if (!p.end())
+ decode(channel, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSBeacon.h b/src/messages/MMDSBeacon.h
new file mode 100644
index 00000000..10b5ae46
--- /dev/null
+++ b/src/messages/MMDSBeacon.h
@@ -0,0 +1,307 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSBEACON_H
+#define CEPH_MMDSBEACON_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+#include "messages/PaxosServiceMessage.h"
+
+#include "include/types.h"
+
+#include "mds/MDSMap.h"
+
+
+
+/**
+ * Unique ID for each type of metric we can send to the mon, so that if the mon
+ * knows about the IDs then it can implement special behaviour for certain
+ * messages.
+ */
+enum mds_metric_t {
+ MDS_HEALTH_NULL = 0,
+ MDS_HEALTH_TRIM,
+ MDS_HEALTH_CLIENT_RECALL,
+ MDS_HEALTH_CLIENT_LATE_RELEASE,
+ MDS_HEALTH_CLIENT_RECALL_MANY,
+ MDS_HEALTH_CLIENT_LATE_RELEASE_MANY,
+ MDS_HEALTH_CLIENT_OLDEST_TID,
+ MDS_HEALTH_CLIENT_OLDEST_TID_MANY,
+ MDS_HEALTH_DAMAGE,
+ MDS_HEALTH_READ_ONLY,
+ MDS_HEALTH_SLOW_REQUEST,
+ MDS_HEALTH_CACHE_OVERSIZED,
+ MDS_HEALTH_SLOW_METADATA_IO,
+};
+
+inline const char *mds_metric_name(mds_metric_t m)
+{
+ switch (m) {
+ case MDS_HEALTH_TRIM: return "MDS_TRIM";
+ case MDS_HEALTH_CLIENT_RECALL: return "MDS_CLIENT_RECALL";
+ case MDS_HEALTH_CLIENT_LATE_RELEASE: return "MDS_CLIENT_LATE_RELEASE";
+ case MDS_HEALTH_CLIENT_RECALL_MANY: return "MDS_CLIENT_RECALL_MANY";
+ case MDS_HEALTH_CLIENT_LATE_RELEASE_MANY: return "MDS_CLIENT_LATE_RELEASE_MANY";
+ case MDS_HEALTH_CLIENT_OLDEST_TID: return "MDS_CLIENT_OLDEST_TID";
+ case MDS_HEALTH_CLIENT_OLDEST_TID_MANY: return "MDS_CLIENT_OLDEST_TID_MANY";
+ case MDS_HEALTH_DAMAGE: return "MDS_DAMAGE";
+ case MDS_HEALTH_READ_ONLY: return "MDS_READ_ONLY";
+ case MDS_HEALTH_SLOW_REQUEST: return "MDS_SLOW_REQUEST";
+ case MDS_HEALTH_CACHE_OVERSIZED: return "MDS_CACHE_OVERSIZED";
+ case MDS_HEALTH_SLOW_METADATA_IO: return "MDS_SLOW_METADATA_IO";
+ default:
+ return "???";
+ }
+}
+
+inline const char *mds_metric_summary(mds_metric_t m)
+{
+ switch (m) {
+ case MDS_HEALTH_TRIM:
+ return "%num% MDSs behind on trimming";
+ case MDS_HEALTH_CLIENT_RECALL:
+ return "%num% clients failing to respond to cache pressure";
+ case MDS_HEALTH_CLIENT_LATE_RELEASE:
+ return "%num% clients failing to respond to capability release";
+ case MDS_HEALTH_CLIENT_RECALL_MANY:
+ return "%num% MDSs have many clients failing to respond to cache pressure";
+ case MDS_HEALTH_CLIENT_LATE_RELEASE_MANY:
+ return "%num% MDSs have many clients failing to respond to capability "
+ "release";
+ case MDS_HEALTH_CLIENT_OLDEST_TID:
+ return "%num% clients failing to advance oldest client/flush tid";
+ case MDS_HEALTH_CLIENT_OLDEST_TID_MANY:
+ return "%num% MDSs have clients failing to advance oldest client/flush tid";
+ case MDS_HEALTH_DAMAGE:
+ return "%num% MDSs report damaged metadata";
+ case MDS_HEALTH_READ_ONLY:
+ return "%num% MDSs are read only";
+ case MDS_HEALTH_SLOW_REQUEST:
+ return "%num% MDSs report slow requests";
+ case MDS_HEALTH_CACHE_OVERSIZED:
+ return "%num% MDSs report oversized cache";
+ case MDS_HEALTH_SLOW_METADATA_IO:
+ return "%num% MDSs report slow metadata IOs";
+ default:
+ return "???";
+ }
+}
+
+/**
+ * This structure is designed to allow some flexibility in how we emit health
+ * complaints, such that:
+ * - The mon doesn't have to have foreknowledge of all possible metrics: we can
+ * implement new messages in the MDS and have the mon pass them through to the user
+ * (enables us to do complex checks inside the MDS, and allows mon to be older version
+ * than MDS)
+ * - The mon has enough information to perform reductions on some types of metric, for
+ * example complaints about the same client from multiple MDSs where we might want
+ * to reduce three "client X is stale on MDS y" metrics into one "client X is stale
+ * on 3 MDSs" message.
+ */
+struct MDSHealthMetric
+{
+ mds_metric_t type;
+ health_status_t sev;
+ std::string message;
+ std::map<std::string, std::string> metadata;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ ceph_assert(type != MDS_HEALTH_NULL);
+ encode((uint16_t)type, bl);
+ encode((uint8_t)sev, bl);
+ encode(message, bl);
+ encode(metadata, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ uint16_t raw_type;
+ decode(raw_type, bl);
+ type = (mds_metric_t)raw_type;
+ ceph_assert(type != MDS_HEALTH_NULL);
+ uint8_t raw_sev;
+ decode(raw_sev, bl);
+ sev = (health_status_t)raw_sev;
+ decode(message, bl);
+ decode(metadata, bl);
+ DECODE_FINISH(bl);
+ }
+
+ bool operator==(MDSHealthMetric const &other) const
+ {
+ return (type == other.type && sev == other.sev && message == other.message);
+ }
+
+ MDSHealthMetric() : type(MDS_HEALTH_NULL), sev(HEALTH_OK) {}
+ MDSHealthMetric(mds_metric_t type_, health_status_t sev_, std::string_view message_)
+ : type(type_), sev(sev_), message(message_) {}
+};
+WRITE_CLASS_ENCODER(MDSHealthMetric)
+
+
+/**
+ * Health metrics send by the MDS to the mon, so that the mon can generate
+ * user friendly warnings about undesirable states.
+ */
+struct MDSHealth
+{
+ std::list<MDSHealthMetric> metrics;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(metrics, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(metrics, bl);
+ DECODE_FINISH(bl);
+ }
+
+ bool operator==(MDSHealth const &other) const
+ {
+ return metrics == other.metrics;
+ }
+};
+WRITE_CLASS_ENCODER(MDSHealth)
+
+
+class MMDSBeacon : public MessageInstance<MMDSBeacon, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 7;
+ static constexpr int COMPAT_VERSION = 6;
+
+ uuid_d fsid;
+ mds_gid_t global_id = MDS_GID_NONE;
+ string name;
+
+ MDSMap::DaemonState state = MDSMap::STATE_NULL;
+ version_t seq = 0;
+
+ CompatSet compat;
+
+ MDSHealth health;
+
+ map<string, string> sys_info;
+
+ uint64_t mds_features = 0;
+
+protected:
+ MMDSBeacon() : MessageInstance(MSG_MDS_BEACON, 0, HEAD_VERSION, COMPAT_VERSION)
+ {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MMDSBeacon(const uuid_d &f, mds_gid_t g, const string& n, epoch_t les, MDSMap::DaemonState st, version_t se, uint64_t feat) :
+ MessageInstance(MSG_MDS_BEACON, les, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), global_id(g), name(n), state(st), seq(se),
+ mds_features(feat) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ ~MMDSBeacon() override {}
+
+public:
+ const uuid_d& get_fsid() const { return fsid; }
+ mds_gid_t get_global_id() const { return global_id; }
+ const string& get_name() const { return name; }
+ epoch_t get_last_epoch_seen() const { return version; }
+ MDSMap::DaemonState get_state() const { return state; }
+ version_t get_seq() const { return seq; }
+ std::string_view get_type_name() const override { return "mdsbeacon"; }
+ uint64_t get_mds_features() const { return mds_features; }
+
+ CompatSet const& get_compat() const { return compat; }
+ void set_compat(const CompatSet& c) { compat = c; }
+
+ MDSHealth const& get_health() const { return health; }
+ void set_health(const MDSHealth &h) { health = h; }
+
+ const map<string, string>& get_sys_info() const { return sys_info; }
+ void set_sys_info(const map<string, string>& i) { sys_info = i; }
+
+ void print(ostream& out) const override {
+ out << "mdsbeacon(" << global_id << "/" << name << " " << ceph_mds_state_name(state)
+ << " seq " << seq << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(global_id, payload);
+ encode((__u32)state, payload);
+ encode(seq, payload);
+ encode(name, payload);
+ encode(MDS_RANK_NONE, payload);
+ encode(std::string(), payload);
+ encode(compat, payload);
+ encode(health, payload);
+ if (state == MDSMap::STATE_BOOT) {
+ encode(sys_info, payload);
+ }
+ encode(mds_features, payload);
+ encode(FS_CLUSTER_ID_NONE, payload);
+ encode(false, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(global_id, p);
+ __u32 raw_state;
+ decode(raw_state, p);
+ state = (MDSMap::DaemonState)raw_state;
+ decode(seq, p);
+ decode(name, p);
+ {
+ mds_rank_t standby_for_rank;
+ decode(standby_for_rank, p);
+ }
+ {
+ std::string standby_for_name;
+ decode(standby_for_name, p);
+ }
+ decode(compat, p);
+ decode(health, p);
+ if (state == MDSMap::STATE_BOOT) {
+ decode(sys_info, p);
+ }
+ decode(mds_features, p);
+ {
+ fs_cluster_id_t standby_for_fscid;
+ decode(standby_for_fscid, p);
+ }
+ if (header.version >= 7) {
+ bool standby_replay;
+ decode(standby_replay, p);
+ }
+
+ if (header.version < 7 && state == MDSMap::STATE_STANDBY_REPLAY) {
+ // Old MDS daemons request the state, instead of explicitly
+ // advertising that they are configured as a replay daemon.
+ state = MDSMap::STATE_STANDBY;
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSCacheRejoin.h b/src/messages/MMDSCacheRejoin.h
new file mode 100644
index 00000000..985adb52
--- /dev/null
+++ b/src/messages/MMDSCacheRejoin.h
@@ -0,0 +1,372 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSCACHEREJOIN_H
+#define CEPH_MMDSCACHEREJOIN_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+#include "mds/CInode.h"
+#include "mds/CDir.h"
+#include "mds/mdstypes.h"
+
+// sent from replica to auth
+
+class MMDSCacheRejoin : public MessageInstance<MMDSCacheRejoin> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ public:
+ static constexpr int OP_WEAK = 1; // replica -> auth, i exist, + maybe open files.
+ static constexpr int OP_STRONG = 2; // replica -> auth, i exist, + open files and lock state.
+ static constexpr int OP_ACK = 3; // auth -> replica, here is your lock state.
+ static const char *get_opname(int op) {
+ switch (op) {
+ case OP_WEAK: return "weak";
+ case OP_STRONG: return "strong";
+ case OP_ACK: return "ack";
+ default: ceph_abort(); return 0;
+ }
+ }
+
+ // -- types --
+ struct inode_strong {
+ uint32_t nonce = 0;
+ int32_t caps_wanted = 0;
+ int32_t filelock = 0, nestlock = 0, dftlock = 0;
+ inode_strong() {}
+ inode_strong(int n, int cw, int dl, int nl, int dftl) :
+ nonce(n), caps_wanted(cw),
+ filelock(dl), nestlock(nl), dftlock(dftl) { }
+ void encode(bufferlist &bl) const {
+ using ceph::encode;
+ encode(nonce, bl);
+ encode(caps_wanted, bl);
+ encode(filelock, bl);
+ encode(nestlock, bl);
+ encode(dftlock, bl);
+ }
+ void decode(bufferlist::const_iterator &bl) {
+ using ceph::decode;
+ decode(nonce, bl);
+ decode(caps_wanted, bl);
+ decode(filelock, bl);
+ decode(nestlock, bl);
+ decode(dftlock, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(inode_strong)
+
+ struct dirfrag_strong {
+ uint32_t nonce = 0;
+ int8_t dir_rep = 0;
+ dirfrag_strong() {}
+ dirfrag_strong(int n, int dr) : nonce(n), dir_rep(dr) {}
+ void encode(bufferlist &bl) const {
+ using ceph::encode;
+ encode(nonce, bl);
+ encode(dir_rep, bl);
+ }
+ void decode(bufferlist::const_iterator &bl) {
+ using ceph::decode;
+ decode(nonce, bl);
+ decode(dir_rep, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(dirfrag_strong)
+
+ struct dn_strong {
+ snapid_t first;
+ inodeno_t ino;
+ inodeno_t remote_ino;
+ unsigned char remote_d_type;
+ uint32_t nonce;
+ int32_t lock;
+ dn_strong() :
+ ino(0), remote_ino(0), remote_d_type(0), nonce(0), lock(0) {}
+ dn_strong(snapid_t f, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int l) :
+ first(f), ino(pi), remote_ino(ri), remote_d_type(rdt), nonce(n), lock(l) {}
+ bool is_primary() const { return ino > 0; }
+ bool is_remote() const { return remote_ino > 0; }
+ bool is_null() const { return ino == 0 && remote_ino == 0; }
+ void encode(bufferlist &bl) const {
+ using ceph::encode;
+ encode(first, bl);
+ encode(ino, bl);
+ encode(remote_ino, bl);
+ encode(remote_d_type, bl);
+ encode(nonce, bl);
+ encode(lock, bl);
+ }
+ void decode(bufferlist::const_iterator &bl) {
+ using ceph::decode;
+ decode(first, bl);
+ decode(ino, bl);
+ decode(remote_ino, bl);
+ decode(remote_d_type, bl);
+ decode(nonce, bl);
+ decode(lock, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(dn_strong)
+
+ struct dn_weak {
+ snapid_t first;
+ inodeno_t ino;
+ dn_weak() : ino(0) {}
+ dn_weak(snapid_t f, inodeno_t pi) : first(f), ino(pi) {}
+ void encode(bufferlist &bl) const {
+ using ceph::encode;
+ encode(first, bl);
+ encode(ino, bl);
+ }
+ void decode(bufferlist::const_iterator &bl) {
+ using ceph::decode;
+ decode(first, bl);
+ decode(ino, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(dn_weak)
+
+ // -- data --
+ int32_t op;
+
+ struct lock_bls {
+ bufferlist file, nest, dft;
+ void encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(file, bl);
+ encode(nest, bl);
+ encode(dft, bl);
+ }
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(file, bl);
+ decode(nest, bl);
+ decode(dft, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(lock_bls)
+
+ // weak
+ map<inodeno_t, map<string_snap_t, dn_weak> > weak;
+ set<dirfrag_t> weak_dirfrags;
+ set<vinodeno_t> weak_inodes;
+ map<inodeno_t, lock_bls> inode_scatterlocks;
+
+ // strong
+ map<dirfrag_t, dirfrag_strong> strong_dirfrags;
+ map<dirfrag_t, map<string_snap_t, dn_strong> > strong_dentries;
+ map<vinodeno_t, inode_strong> strong_inodes;
+
+ // open
+ map<inodeno_t,map<client_t, cap_reconnect_t> > cap_exports;
+ map<client_t, entity_inst_t> client_map;
+ map<client_t,client_metadata_t> client_metadata_map;
+ bufferlist imported_caps;
+
+ // full
+ bufferlist inode_base;
+ bufferlist inode_locks;
+ map<dirfrag_t, bufferlist> dirfrag_bases;
+
+ // authpins, xlocks
+ struct slave_reqid {
+ metareqid_t reqid;
+ __u32 attempt;
+ slave_reqid() : attempt(0) {}
+ slave_reqid(const metareqid_t& r, __u32 a)
+ : reqid(r), attempt(a) {}
+ void encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(reqid, bl);
+ encode(attempt, bl);
+ }
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(reqid, bl);
+ decode(attempt, bl);
+ }
+ };
+ map<vinodeno_t, list<slave_reqid> > authpinned_inodes;
+ map<vinodeno_t, slave_reqid> frozen_authpin_inodes;
+ map<vinodeno_t, map<__s32, slave_reqid> > xlocked_inodes;
+ map<vinodeno_t, map<__s32, list<slave_reqid> > > wrlocked_inodes;
+ map<dirfrag_t, map<string_snap_t, list<slave_reqid> > > authpinned_dentries;
+ map<dirfrag_t, map<string_snap_t, slave_reqid> > xlocked_dentries;
+
+protected:
+ MMDSCacheRejoin() :
+ MessageInstance(MSG_MDS_CACHEREJOIN, HEAD_VERSION, COMPAT_VERSION),
+ op(0) {}
+ MMDSCacheRejoin(int o) :
+ MessageInstance(MSG_MDS_CACHEREJOIN, HEAD_VERSION, COMPAT_VERSION),
+ op(o) {}
+ ~MMDSCacheRejoin() override {}
+
+public:
+ std::string_view get_type_name() const override { return "cache_rejoin"; }
+ void print(ostream& out) const override {
+ out << "cache_rejoin " << get_opname(op);
+ }
+
+ // -- builders --
+ // inodes
+ void add_weak_inode(vinodeno_t i) {
+ weak_inodes.insert(i);
+ }
+ void add_strong_inode(vinodeno_t i, int n, int cw, int dl, int nl, int dftl) {
+ strong_inodes[i] = inode_strong(n, cw, dl, nl, dftl);
+ }
+ void add_inode_locks(CInode *in, __u32 nonce, bufferlist& bl) {
+ using ceph::encode;
+ encode(in->inode.ino, inode_locks);
+ encode(in->last, inode_locks);
+ encode(nonce, inode_locks);
+ encode(bl, inode_locks);
+ }
+ void add_inode_base(CInode *in, uint64_t features) {
+ using ceph::encode;
+ encode(in->inode.ino, inode_base);
+ encode(in->last, inode_base);
+ bufferlist bl;
+ in->_encode_base(bl, features);
+ encode(bl, inode_base);
+ }
+ void add_inode_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) {
+ authpinned_inodes[ino].push_back(slave_reqid(ri, attempt));
+ }
+ void add_inode_frozen_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) {
+ frozen_authpin_inodes[ino] = slave_reqid(ri, attempt);
+ }
+ void add_inode_xlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) {
+ xlocked_inodes[ino][lt] = slave_reqid(ri, attempt);
+ }
+ void add_inode_wrlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) {
+ wrlocked_inodes[ino][lt].push_back(slave_reqid(ri, attempt));
+ }
+
+ void add_scatterlock_state(CInode *in) {
+ if (inode_scatterlocks.count(in->ino()))
+ return; // already added this one
+ in->encode_lock_state(CEPH_LOCK_IFILE, inode_scatterlocks[in->ino()].file);
+ in->encode_lock_state(CEPH_LOCK_INEST, inode_scatterlocks[in->ino()].nest);
+ in->encode_lock_state(CEPH_LOCK_IDFT, inode_scatterlocks[in->ino()].dft);
+ }
+
+ // dirfrags
+ void add_strong_dirfrag(dirfrag_t df, int n, int dr) {
+ strong_dirfrags[df] = dirfrag_strong(n, dr);
+ }
+ void add_dirfrag_base(CDir *dir) {
+ bufferlist& bl = dirfrag_bases[dir->dirfrag()];
+ dir->_encode_base(bl);
+ }
+
+ // dentries
+ void add_weak_dirfrag(dirfrag_t df) {
+ weak_dirfrags.insert(df);
+ }
+ void add_weak_dentry(inodeno_t dirino, std::string_view dname, snapid_t last, dn_weak& dnw) {
+ weak[dirino][string_snap_t(dname, last)] = dnw;
+ }
+ void add_weak_primary_dentry(inodeno_t dirino, std::string_view dname, snapid_t first, snapid_t last, inodeno_t ino) {
+ weak[dirino][string_snap_t(dname, last)] = dn_weak(first, ino);
+ }
+ void add_strong_dentry(dirfrag_t df, std::string_view dname, snapid_t first, snapid_t last, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int ls) {
+ strong_dentries[df][string_snap_t(dname, last)] = dn_strong(first, pi, ri, rdt, n, ls);
+ }
+ void add_dentry_authpin(dirfrag_t df, std::string_view dname, snapid_t last,
+ const metareqid_t& ri, __u32 attempt) {
+ authpinned_dentries[df][string_snap_t(dname, last)].push_back(slave_reqid(ri, attempt));
+ }
+ void add_dentry_xlock(dirfrag_t df, std::string_view dname, snapid_t last,
+ const metareqid_t& ri, __u32 attempt) {
+ xlocked_dentries[df][string_snap_t(dname, last)] = slave_reqid(ri, attempt);
+ }
+
+ // -- encoding --
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(strong_inodes, payload);
+ encode(inode_base, payload);
+ encode(inode_locks, payload);
+ encode(inode_scatterlocks, payload);
+ encode(authpinned_inodes, payload);
+ encode(frozen_authpin_inodes, payload);
+ encode(xlocked_inodes, payload);
+ encode(wrlocked_inodes, payload);
+ encode(cap_exports, payload);
+ encode(client_map, payload, features);
+ encode(imported_caps, payload);
+ encode(strong_dirfrags, payload);
+ encode(dirfrag_bases, payload);
+ encode(weak, payload);
+ encode(weak_dirfrags, payload);
+ encode(weak_inodes, payload);
+ encode(strong_dentries, payload);
+ encode(authpinned_dentries, payload);
+ encode(xlocked_dentries, payload);
+ encode(client_metadata_map, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ using ceph::decode;
+ decode(op, p);
+ decode(strong_inodes, p);
+ decode(inode_base, p);
+ decode(inode_locks, p);
+ decode(inode_scatterlocks, p);
+ decode(authpinned_inodes, p);
+ decode(frozen_authpin_inodes, p);
+ decode(xlocked_inodes, p);
+ decode(wrlocked_inodes, p);
+ decode(cap_exports, p);
+ decode(client_map, p);
+ decode(imported_caps, p);
+ decode(strong_dirfrags, p);
+ decode(dirfrag_bases, p);
+ decode(weak, p);
+ decode(weak_dirfrags, p);
+ decode(weak_inodes, p);
+ decode(strong_dentries, p);
+ decode(authpinned_dentries, p);
+ decode(xlocked_dentries, p);
+ if (header.version >= 2)
+ decode(client_metadata_map, p);
+ }
+
+};
+
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::inode_strong)
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::dirfrag_strong)
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_strong)
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_weak)
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::lock_bls)
+WRITE_CLASS_ENCODER(MMDSCacheRejoin::slave_reqid)
+
+inline ostream& operator<<(ostream& out, const MMDSCacheRejoin::slave_reqid& r) {
+ return out << r.reqid << '.' << r.attempt;
+}
+
+#endif
diff --git a/src/messages/MMDSFindIno.h b/src/messages/MMDSFindIno.h
new file mode 100644
index 00000000..a6d661b9
--- /dev/null
+++ b/src/messages/MMDSFindIno.h
@@ -0,0 +1,51 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MDSFINDINO_H
+#define CEPH_MDSFINDINO_H
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+
+class MMDSFindIno : public MessageInstance<MMDSFindIno> {
+public:
+ friend factory;
+
+ ceph_tid_t tid {0};
+ inodeno_t ino;
+
+protected:
+ MMDSFindIno() : MessageInstance(MSG_MDS_FINDINO) {}
+ MMDSFindIno(ceph_tid_t t, inodeno_t i) : MessageInstance(MSG_MDS_FINDINO), tid(t), ino(i) {}
+ ~MMDSFindIno() override {}
+
+public:
+ std::string_view get_type_name() const override { return "findino"; }
+ void print(ostream &out) const override {
+ out << "findino(" << tid << " " << ino << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(tid, payload);
+ encode(ino, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(tid, p);
+ decode(ino, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSFindInoReply.h b/src/messages/MMDSFindInoReply.h
new file mode 100644
index 00000000..10e003b3
--- /dev/null
+++ b/src/messages/MMDSFindInoReply.h
@@ -0,0 +1,51 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MDSFINDINOREPLY_H
+#define CEPH_MDSFINDINOREPLY_H
+
+#include "msg/Message.h"
+#include "include/filepath.h"
+
+class MMDSFindInoReply : public MessageInstance<MMDSFindInoReply> {
+public:
+ friend factory;
+
+ ceph_tid_t tid = 0;
+ filepath path;
+
+protected:
+ MMDSFindInoReply() : MessageInstance(MSG_MDS_FINDINOREPLY) {}
+ MMDSFindInoReply(ceph_tid_t t) : MessageInstance(MSG_MDS_FINDINOREPLY), tid(t) {}
+ ~MMDSFindInoReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "findinoreply"; }
+ void print(ostream &out) const override {
+ out << "findinoreply(" << tid << " " << path << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(tid, payload);
+ encode(path, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(tid, p);
+ decode(path, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSFragmentNotify.h b/src/messages/MMDSFragmentNotify.h
new file mode 100644
index 00000000..0baa874f
--- /dev/null
+++ b/src/messages/MMDSFragmentNotify.h
@@ -0,0 +1,75 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSFRAGMENTNOTIFY_H
+#define CEPH_MMDSFRAGMENTNOTIFY_H
+
+#include "msg/Message.h"
+
+class MMDSFragmentNotify : public MessageInstance<MMDSFragmentNotify> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t base_dirfrag;
+ int8_t bits = 0;
+ bool ack_wanted = false;
+
+ public:
+ inodeno_t get_ino() const { return base_dirfrag.ino; }
+ frag_t get_basefrag() const { return base_dirfrag.frag; }
+ dirfrag_t get_base_dirfrag() const { return base_dirfrag; }
+ int get_bits() const { return bits; }
+ bool is_ack_wanted() const { return ack_wanted; }
+ void mark_ack_wanted() { ack_wanted = true; }
+
+ bufferlist basebl;
+
+protected:
+ MMDSFragmentNotify() :
+ MessageInstance(MSG_MDS_FRAGMENTNOTIFY, HEAD_VERSION, COMPAT_VERSION) {}
+ MMDSFragmentNotify(dirfrag_t df, int b, uint64_t tid) :
+ MessageInstance(MSG_MDS_FRAGMENTNOTIFY, HEAD_VERSION, COMPAT_VERSION),
+ base_dirfrag(df), bits(b) {
+ set_tid(tid);
+ }
+ ~MMDSFragmentNotify() override {}
+
+public:
+ std::string_view get_type_name() const override { return "fragment_notify"; }
+ void print(ostream& o) const override {
+ o << "fragment_notify(" << base_dirfrag << " " << (int)bits << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(base_dirfrag, payload);
+ encode(bits, payload);
+ encode(basebl, payload);
+ encode(ack_wanted, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(base_dirfrag, p);
+ decode(bits, p);
+ decode(basebl, p);
+ if (header.version >= 2)
+ decode(ack_wanted, p);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MMDSFragmentNotifyAck.h b/src/messages/MMDSFragmentNotifyAck.h
new file mode 100644
index 00000000..e20a3089
--- /dev/null
+++ b/src/messages/MMDSFragmentNotifyAck.h
@@ -0,0 +1,60 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSFRAGMENTNOTIFYAck_H
+#define CEPH_MMDSFRAGMENTNOTIFYAck_H
+
+#include "msg/Message.h"
+
+class MMDSFragmentNotifyAck : public MessageInstance<MMDSFragmentNotifyAck> {
+public:
+ friend factory;
+private:
+ dirfrag_t base_dirfrag;
+ int8_t bits = 0;
+
+ public:
+ dirfrag_t get_base_dirfrag() const { return base_dirfrag; }
+ int get_bits() const { return bits; }
+
+ bufferlist basebl;
+
+protected:
+ MMDSFragmentNotifyAck() : MessageInstance(MSG_MDS_FRAGMENTNOTIFYACK) {}
+ MMDSFragmentNotifyAck(dirfrag_t df, int b, uint64_t tid) :
+ MessageInstance(MSG_MDS_FRAGMENTNOTIFYACK),
+ base_dirfrag(df), bits(b) {
+ set_tid(tid);
+ }
+ ~MMDSFragmentNotifyAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "fragment_notify_ack"; }
+ void print(ostream& o) const override {
+ o << "fragment_notify_ack(" << base_dirfrag << " " << (int)bits << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(base_dirfrag, payload);
+ encode(bits, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(base_dirfrag, p);
+ decode(bits, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSLoadTargets.h b/src/messages/MMDSLoadTargets.h
new file mode 100644
index 00000000..98d845de
--- /dev/null
+++ b/src/messages/MMDSLoadTargets.h
@@ -0,0 +1,62 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2009 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSLoadTargets_H
+#define CEPH_MMDSLoadTargets_H
+
+#include "msg/Message.h"
+#include "mds/mdstypes.h"
+#include "messages/PaxosServiceMessage.h"
+#include "include/types.h"
+
+#include <map>
+using std::map;
+
+class MMDSLoadTargets : public MessageInstance<MMDSLoadTargets, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ mds_gid_t global_id;
+ set<mds_rank_t> targets;
+
+protected:
+ MMDSLoadTargets() : MessageInstance(MSG_MDS_OFFLOAD_TARGETS, 0) {}
+ MMDSLoadTargets(mds_gid_t g, set<mds_rank_t>& mds_targets) :
+ MessageInstance(MSG_MDS_OFFLOAD_TARGETS, 0),
+ global_id(g), targets(mds_targets) {}
+ ~MMDSLoadTargets() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mds_load_targets"; }
+ void print(ostream& o) const override {
+ o << "mds_load_targets(" << global_id << " " << targets << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(global_id, p);
+ decode(targets, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(global_id, payload);
+ encode(targets, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSMap.h b/src/messages/MMDSMap.h
new file mode 100644
index 00000000..726cfac5
--- /dev/null
+++ b/src/messages/MMDSMap.h
@@ -0,0 +1,79 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMDSMAP_H
+#define CEPH_MMDSMAP_H
+
+#include "msg/Message.h"
+#include "mds/MDSMap.h"
+#include "include/ceph_features.h"
+
+class MMDSMap : public MessageInstance<MMDSMap> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ uuid_d fsid;
+ epoch_t epoch = 0;
+ bufferlist encoded;
+
+ version_t get_epoch() const { return epoch; }
+ const bufferlist& get_encoded() const { return encoded; }
+
+protected:
+ MMDSMap() :
+ MessageInstance(CEPH_MSG_MDS_MAP, HEAD_VERSION, COMPAT_VERSION) {}
+ MMDSMap(const uuid_d &f, const MDSMap &mm) :
+ MessageInstance(CEPH_MSG_MDS_MAP, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f) {
+ epoch = mm.get_epoch();
+ mm.encode(encoded, -1); // we will reencode with fewer features as necessary
+ }
+ ~MMDSMap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mdsmap"; }
+ void print(ostream& out) const override {
+ out << "mdsmap(e " << epoch << ")";
+ }
+
+ // marshalling
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(epoch, p);
+ decode(encoded, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(fsid, payload);
+ encode(epoch, payload);
+ if ((features & CEPH_FEATURE_PGID64) == 0 ||
+ (features & CEPH_FEATURE_MDSENC) == 0 ||
+ (features & CEPH_FEATURE_MSG_ADDR2) == 0 ||
+ !HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ // reencode for old clients.
+ MDSMap m;
+ m.decode(encoded);
+ encoded.clear();
+ m.encode(encoded, features);
+ }
+ encode(encoded, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSOpenIno.h b/src/messages/MMDSOpenIno.h
new file mode 100644
index 00000000..b9a068be
--- /dev/null
+++ b/src/messages/MMDSOpenIno.h
@@ -0,0 +1,55 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MDSOPENINO_H
+#define CEPH_MDSOPENINO_H
+
+#include "msg/Message.h"
+
+class MMDSOpenIno : public MessageInstance<MMDSOpenIno> {
+public:
+ friend factory;
+
+ inodeno_t ino;
+ vector<inode_backpointer_t> ancestors;
+
+protected:
+ MMDSOpenIno() : MessageInstance(MSG_MDS_OPENINO) {}
+ MMDSOpenIno(ceph_tid_t t, inodeno_t i, vector<inode_backpointer_t>* pa) :
+ MessageInstance(MSG_MDS_OPENINO), ino(i) {
+ header.tid = t;
+ if (pa)
+ ancestors = *pa;
+ }
+ ~MMDSOpenIno() override {}
+
+public:
+ std::string_view get_type_name() const override { return "openino"; }
+ void print(ostream &out) const override {
+ out << "openino(" << header.tid << " " << ino << " " << ancestors << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(ancestors, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(ancestors, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSOpenInoReply.h b/src/messages/MMDSOpenInoReply.h
new file mode 100644
index 00000000..6f87e6a9
--- /dev/null
+++ b/src/messages/MMDSOpenInoReply.h
@@ -0,0 +1,60 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MDSOPENINOREPLY_H
+#define CEPH_MDSOPENINOREPLY_H
+
+#include "msg/Message.h"
+
+class MMDSOpenInoReply : public MessageInstance<MMDSOpenInoReply> {
+public:
+ friend factory;
+
+ inodeno_t ino;
+ vector<inode_backpointer_t> ancestors;
+ mds_rank_t hint;
+ int32_t error;
+
+protected:
+ MMDSOpenInoReply() : MessageInstance(MSG_MDS_OPENINOREPLY), error(0) {}
+ MMDSOpenInoReply(ceph_tid_t t, inodeno_t i, mds_rank_t h=MDS_RANK_NONE, int e=0) :
+ MessageInstance(MSG_MDS_OPENINOREPLY), ino(i), hint(h), error(e) {
+ header.tid = t;
+ }
+
+
+public:
+ std::string_view get_type_name() const override { return "openinoreply"; }
+ void print(ostream &out) const override {
+ out << "openinoreply(" << header.tid << " "
+ << ino << " " << hint << " " << ancestors << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(ancestors, payload);
+ encode(hint, payload);
+ encode(error, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(ancestors, p);
+ decode(hint, p);
+ decode(error, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSResolve.h b/src/messages/MMDSResolve.h
new file mode 100644
index 00000000..52fad12e
--- /dev/null
+++ b/src/messages/MMDSResolve.h
@@ -0,0 +1,129 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSRESOLVE_H
+#define CEPH_MMDSRESOLVE_H
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+class MMDSResolve : public MessageInstance<MMDSResolve> {
+public:
+ friend factory;
+
+ map<dirfrag_t, vector<dirfrag_t> > subtrees;
+ map<dirfrag_t, vector<dirfrag_t> > ambiguous_imports;
+
+ struct slave_request {
+ bufferlist inode_caps;
+ bool committing;
+ slave_request() : committing(false) {}
+ void encode(bufferlist &bl) const {
+ using ceph::encode;
+ encode(inode_caps, bl);
+ encode(committing, bl);
+ }
+ void decode(bufferlist::const_iterator &bl) {
+ using ceph::decode;
+ decode(inode_caps, bl);
+ decode(committing, bl);
+ }
+ };
+
+ map<metareqid_t, slave_request> slave_requests;
+
+ // table client information
+ struct table_client {
+ __u8 type;
+ set<version_t> pending_commits;
+
+ table_client() : type(0) {}
+ table_client(int _type, const set<version_t>& commits)
+ : type(_type), pending_commits(commits) {}
+
+ void encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(type, bl);
+ encode(pending_commits, bl);
+ }
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(type, bl);
+ decode(pending_commits, bl);
+ }
+ };
+
+ list<table_client> table_clients;
+
+protected:
+ MMDSResolve() : MessageInstance(MSG_MDS_RESOLVE) {}
+ ~MMDSResolve() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mds_resolve"; }
+
+ void print(ostream& out) const override {
+ out << "mds_resolve(" << subtrees.size()
+ << "+" << ambiguous_imports.size()
+ << " subtrees +" << slave_requests.size() << " slave requests)";
+ }
+
+ void add_subtree(dirfrag_t im) {
+ subtrees[im].clear();
+ }
+ void add_subtree_bound(dirfrag_t im, dirfrag_t ex) {
+ subtrees[im].push_back(ex);
+ }
+
+ void add_ambiguous_import(dirfrag_t im, const vector<dirfrag_t>& m) {
+ ambiguous_imports[im] = m;
+ }
+
+ void add_slave_request(metareqid_t reqid, bool committing) {
+ slave_requests[reqid].committing = committing;
+ }
+
+ void add_slave_request(metareqid_t reqid, bufferlist& bl) {
+ slave_requests[reqid].inode_caps.claim(bl);
+ }
+
+ void add_table_commits(int table, const set<version_t>& pending_commits) {
+ table_clients.push_back(table_client(table, pending_commits));
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(subtrees, payload);
+ encode(ambiguous_imports, payload);
+ encode(slave_requests, payload);
+ encode(table_clients, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(subtrees, p);
+ decode(ambiguous_imports, p);
+ decode(slave_requests, p);
+ decode(table_clients, p);
+ }
+};
+
+inline ostream& operator<<(ostream& out, const MMDSResolve::slave_request&) {
+ return out;
+}
+
+WRITE_CLASS_ENCODER(MMDSResolve::slave_request)
+WRITE_CLASS_ENCODER(MMDSResolve::table_client)
+#endif
diff --git a/src/messages/MMDSResolveAck.h b/src/messages/MMDSResolveAck.h
new file mode 100644
index 00000000..42698834
--- /dev/null
+++ b/src/messages/MMDSResolveAck.h
@@ -0,0 +1,63 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSRESOLVEACK_H
+#define CEPH_MMDSRESOLVEACK_H
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+
+class MMDSResolveAck : public MessageInstance<MMDSResolveAck> {
+public:
+ friend factory;
+
+ map<metareqid_t, bufferlist> commit;
+ vector<metareqid_t> abort;
+
+protected:
+ MMDSResolveAck() : MessageInstance(MSG_MDS_RESOLVEACK) {}
+ ~MMDSResolveAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "resolve_ack"; }
+ /*void print(ostream& out) const {
+ out << "resolve_ack.size()
+ << "+" << ambiguous_imap.size()
+ << " imports +" << slave_requests.size() << " slave requests)";
+ }
+ */
+
+ void add_commit(metareqid_t r) {
+ commit[r].clear();
+ }
+ void add_abort(metareqid_t r) {
+ abort.push_back(r);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(commit, payload);
+ encode(abort, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(commit, p);
+ decode(abort, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSSlaveRequest.h b/src/messages/MMDSSlaveRequest.h
new file mode 100644
index 00000000..f9be3af8
--- /dev/null
+++ b/src/messages/MMDSSlaveRequest.h
@@ -0,0 +1,220 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMDSSLAVEREQUEST_H
+#define CEPH_MMDSSLAVEREQUEST_H
+
+#include "msg/Message.h"
+#include "mds/mdstypes.h"
+
+class MMDSSlaveRequest : public MessageInstance<MMDSSlaveRequest> {
+public:
+ friend factory;
+
+ static constexpr int OP_XLOCK = 1;
+ static constexpr int OP_XLOCKACK = -1;
+ static constexpr int OP_UNXLOCK = 2;
+ static constexpr int OP_AUTHPIN = 3;
+ static constexpr int OP_AUTHPINACK = -3;
+
+ static constexpr int OP_LINKPREP = 4;
+ static constexpr int OP_UNLINKPREP = 5;
+ static constexpr int OP_LINKPREPACK = -4;
+
+ static constexpr int OP_RENAMEPREP = 7;
+ static constexpr int OP_RENAMEPREPACK = -7;
+
+ static constexpr int OP_WRLOCK = 8;
+ static constexpr int OP_WRLOCKACK = -8;
+ static constexpr int OP_UNWRLOCK = 9;
+
+ static constexpr int OP_RMDIRPREP = 10;
+ static constexpr int OP_RMDIRPREPACK = -10;
+
+ static constexpr int OP_DROPLOCKS = 11;
+
+ static constexpr int OP_RENAMENOTIFY = 12;
+ static constexpr int OP_RENAMENOTIFYACK = -12;
+
+ static constexpr int OP_FINISH = 17;
+ static constexpr int OP_COMMITTED = -18;
+
+ static constexpr int OP_ABORT = 20; // used for recovery only
+ //static constexpr int OP_COMMIT = 21; // used for recovery only
+
+
+ static const char *get_opname(int o) {
+ switch (o) {
+ case OP_XLOCK: return "xlock";
+ case OP_XLOCKACK: return "xlock_ack";
+ case OP_UNXLOCK: return "unxlock";
+ case OP_AUTHPIN: return "authpin";
+ case OP_AUTHPINACK: return "authpin_ack";
+
+ case OP_LINKPREP: return "link_prep";
+ case OP_LINKPREPACK: return "link_prep_ack";
+ case OP_UNLINKPREP: return "unlink_prep";
+
+ case OP_RENAMEPREP: return "rename_prep";
+ case OP_RENAMEPREPACK: return "rename_prep_ack";
+
+ case OP_FINISH: return "finish"; // commit
+ case OP_COMMITTED: return "committed";
+
+ case OP_WRLOCK: return "wrlock";
+ case OP_WRLOCKACK: return "wrlock_ack";
+ case OP_UNWRLOCK: return "unwrlock";
+
+ case OP_RMDIRPREP: return "rmdir_prep";
+ case OP_RMDIRPREPACK: return "rmdir_prep_ack";
+
+ case OP_DROPLOCKS: return "drop_locks";
+
+ case OP_RENAMENOTIFY: return "rename_notify";
+ case OP_RENAMENOTIFYACK: return "rename_notify_ack";
+
+ case OP_ABORT: return "abort";
+ //case OP_COMMIT: return "commit";
+
+ default: ceph_abort(); return 0;
+ }
+ }
+
+ private:
+ metareqid_t reqid;
+ __u32 attempt;
+ __s16 op;
+ mutable __u16 flags; /* XXX HACK for mark_interrupted */
+
+ static constexpr unsigned FLAG_NONBLOCK = 1<<0;
+ static constexpr unsigned FLAG_WOULDBLOCK = 1<<1;
+ static constexpr unsigned FLAG_NOTJOURNALED = 1<<2;
+ static constexpr unsigned FLAG_EROFS = 1<<3;
+ static constexpr unsigned FLAG_ABORT = 1<<4;
+ static constexpr unsigned FLAG_INTERRUPTED = 1<<5;
+
+ // for locking
+ __u16 lock_type; // lock object type
+ MDSCacheObjectInfo object_info;
+
+ // for authpins
+ vector<MDSCacheObjectInfo> authpins;
+
+ public:
+ // for rename prep
+ filepath srcdnpath;
+ filepath destdnpath;
+ set<mds_rank_t> witnesses;
+ bufferlist inode_export;
+ version_t inode_export_v;
+ mds_rank_t srcdn_auth;
+ utime_t op_stamp;
+
+ mutable bufferlist straybl; // stray dir + dentry
+ bufferlist srci_snapbl;
+ bufferlist desti_snapbl;
+
+public:
+ metareqid_t get_reqid() const { return reqid; }
+ __u32 get_attempt() const { return attempt; }
+ int get_op() const { return op; }
+ bool is_reply() const { return op < 0; }
+
+ int get_lock_type() const { return lock_type; }
+ const MDSCacheObjectInfo &get_object_info() const { return object_info; }
+ MDSCacheObjectInfo &get_object_info() { return object_info; }
+ const MDSCacheObjectInfo &get_authpin_freeze() const { return object_info; }
+ MDSCacheObjectInfo &get_authpin_freeze() { return object_info; }
+
+ const vector<MDSCacheObjectInfo>& get_authpins() const { return authpins; }
+ vector<MDSCacheObjectInfo>& get_authpins() { return authpins; }
+ void mark_nonblock() { flags |= FLAG_NONBLOCK; }
+ bool is_nonblock() const { return (flags & FLAG_NONBLOCK); }
+ void mark_error_wouldblock() { flags |= FLAG_WOULDBLOCK; }
+ bool is_error_wouldblock() const { return (flags & FLAG_WOULDBLOCK); }
+ void mark_not_journaled() { flags |= FLAG_NOTJOURNALED; }
+ bool is_not_journaled() const { return (flags & FLAG_NOTJOURNALED); }
+ void mark_error_rofs() { flags |= FLAG_EROFS; }
+ bool is_error_rofs() const { return (flags & FLAG_EROFS); }
+ bool is_abort() const { return (flags & FLAG_ABORT); }
+ void mark_abort() { flags |= FLAG_ABORT; }
+ bool is_interrupted() const { return (flags & FLAG_INTERRUPTED); }
+ void mark_interrupted() const { flags |= FLAG_INTERRUPTED; }
+
+ void set_lock_type(int t) { lock_type = t; }
+ const bufferlist& get_lock_data() const { return inode_export; }
+ bufferlist& get_lock_data() { return inode_export; }
+
+protected:
+ MMDSSlaveRequest() : MessageInstance(MSG_MDS_SLAVE_REQUEST) { }
+ MMDSSlaveRequest(metareqid_t ri, __u32 att, int o) :
+ MessageInstance(MSG_MDS_SLAVE_REQUEST),
+ reqid(ri), attempt(att), op(o), flags(0), lock_type(0),
+ inode_export_v(0), srcdn_auth(MDS_RANK_NONE) { }
+ ~MMDSSlaveRequest() override {}
+
+public:
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(reqid, payload);
+ encode(attempt, payload);
+ encode(op, payload);
+ encode(flags, payload);
+ encode(lock_type, payload);
+ encode(object_info, payload);
+ encode(authpins, payload);
+ encode(srcdnpath, payload);
+ encode(destdnpath, payload);
+ encode(witnesses, payload);
+ encode(op_stamp, payload);
+ encode(inode_export, payload);
+ encode(inode_export_v, payload);
+ encode(srcdn_auth, payload);
+ encode(straybl, payload);
+ encode(srci_snapbl, payload);
+ encode(desti_snapbl, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(reqid, p);
+ decode(attempt, p);
+ decode(op, p);
+ decode(flags, p);
+ decode(lock_type, p);
+ decode(object_info, p);
+ decode(authpins, p);
+ decode(srcdnpath, p);
+ decode(destdnpath, p);
+ decode(witnesses, p);
+ decode(op_stamp, p);
+ decode(inode_export, p);
+ decode(inode_export_v, p);
+ decode(srcdn_auth, p);
+ decode(straybl, p);
+ decode(srci_snapbl, p);
+ decode(desti_snapbl, p);
+ }
+
+ std::string_view get_type_name() const override { return "slave_request"; }
+ void print(ostream& out) const override {
+ out << "slave_request(" << reqid
+ << "." << attempt
+ << " " << get_opname(op)
+ << ")";
+ }
+
+};
+
+#endif
diff --git a/src/messages/MMDSSnapUpdate.h b/src/messages/MMDSSnapUpdate.h
new file mode 100644
index 00000000..06872cdc
--- /dev/null
+++ b/src/messages/MMDSSnapUpdate.h
@@ -0,0 +1,63 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMDSSNAPUPDATE_H
+#define CEPH_MMDSSNAPUPDATE_H
+
+#include "msg/Message.h"
+
+class MMDSSnapUpdate : public MessageInstance<MMDSSnapUpdate> {
+public:
+ friend factory;
+private:
+
+ inodeno_t ino;
+ __s16 snap_op;
+
+public:
+ inodeno_t get_ino() const { return ino; }
+ int get_snap_op() const { return snap_op; }
+
+ bufferlist snap_blob;
+
+protected:
+ MMDSSnapUpdate() : MessageInstance(MSG_MDS_SNAPUPDATE) {}
+ MMDSSnapUpdate(inodeno_t i, version_t tid, int op) :
+ MessageInstance(MSG_MDS_SNAPUPDATE), ino(i), snap_op(op) {
+ set_tid(tid);
+ }
+ ~MMDSSnapUpdate() override {}
+
+public:
+ std::string_view get_type_name() const override { return "snap_update"; }
+ void print(ostream& o) const override {
+ o << "snap_update(" << ino << " table_tid " << get_tid() << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(ino, payload);
+ encode(snap_op, payload);
+ encode(snap_blob, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(snap_op, p);
+ decode(snap_blob, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMDSTableRequest.h b/src/messages/MMDSTableRequest.h
new file mode 100644
index 00000000..4a6e2ca9
--- /dev/null
+++ b/src/messages/MMDSTableRequest.h
@@ -0,0 +1,68 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMDSTABLEREQUEST_H
+#define CEPH_MMDSTABLEREQUEST_H
+
+#include "msg/Message.h"
+#include "mds/mds_table_types.h"
+
+class MMDSTableRequest : public MessageInstance<MMDSTableRequest> {
+public:
+ friend factory;
+
+ __u16 table = 0;
+ __s16 op = 0;
+ uint64_t reqid = 0;
+ bufferlist bl;
+
+protected:
+ MMDSTableRequest() : MessageInstance(MSG_MDS_TABLE_REQUEST) {}
+ MMDSTableRequest(int tab, int o, uint64_t r, version_t v=0) :
+ MessageInstance(MSG_MDS_TABLE_REQUEST),
+ table(tab), op(o), reqid(r) {
+ set_tid(v);
+ }
+ ~MMDSTableRequest() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mds_table_request"; }
+ void print(ostream& o) const override {
+ o << "mds_table_request(" << get_mdstable_name(table)
+ << " " << get_mdstableserver_opname(op);
+ if (reqid) o << " " << reqid;
+ if (get_tid()) o << " tid " << get_tid();
+ if (bl.length()) o << " " << bl.length() << " bytes";
+ o << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(table, p);
+ decode(op, p);
+ decode(reqid, p);
+ decode(bl, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(table, payload);
+ encode(op, payload);
+ encode(reqid, payload);
+ encode(bl, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MMgrBeacon.h b/src/messages/MMgrBeacon.h
new file mode 100644
index 00000000..f3bb8384
--- /dev/null
+++ b/src/messages/MMgrBeacon.h
@@ -0,0 +1,185 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMGRBEACON_H
+#define CEPH_MMGRBEACON_H
+
+#include "messages/PaxosServiceMessage.h"
+#include "mon/MonCommand.h"
+#include "mon/MgrMap.h"
+
+#include "include/types.h"
+
+
+class MMgrBeacon : public MessageInstance<MMgrBeacon, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 8;
+
+protected:
+ uint64_t gid;
+ entity_addrvec_t server_addrs;
+ bool available;
+ std::string name;
+ uuid_d fsid;
+
+ // From active daemon to populate MgrMap::services
+ std::map<std::string, std::string> services;
+
+ // Only populated during activation
+ std::vector<MonCommand> command_descs;
+
+ // Information about the modules found locally on this daemon
+ std::vector<MgrMap::ModuleInfo> modules;
+
+ map<string,string> metadata; ///< misc metadata about this osd
+
+public:
+ MMgrBeacon()
+ : MessageInstance(MSG_MGR_BEACON, 0, HEAD_VERSION, COMPAT_VERSION),
+ gid(0), available(false)
+ {
+ }
+
+ MMgrBeacon(const uuid_d& fsid_, uint64_t gid_, const std::string &name_,
+ entity_addrvec_t server_addrs_, bool available_,
+ std::vector<MgrMap::ModuleInfo>&& modules_,
+ map<string,string>&& metadata_)
+ : MessageInstance(MSG_MGR_BEACON, 0, HEAD_VERSION, COMPAT_VERSION),
+ gid(gid_), server_addrs(server_addrs_), available(available_), name(name_),
+ fsid(fsid_), modules(std::move(modules_)), metadata(std::move(metadata_))
+ {
+ }
+
+ uint64_t get_gid() const { return gid; }
+ entity_addrvec_t get_server_addrs() const { return server_addrs; }
+ bool get_available() const { return available; }
+ const std::string& get_name() const { return name; }
+ const uuid_d& get_fsid() const { return fsid; }
+ const std::map<std::string,std::string>& get_metadata() const {
+ return metadata;
+ }
+
+ const std::map<std::string,std::string>& get_services() const {
+ return services;
+ }
+
+ void set_services(const std::map<std::string, std::string> &svcs)
+ {
+ services = svcs;
+ }
+
+ void set_command_descs(const std::vector<MonCommand> &cmds)
+ {
+ command_descs = cmds;
+ }
+
+ const std::vector<MonCommand> &get_command_descs()
+ {
+ return command_descs;
+ }
+
+ const std::vector<MgrMap::ModuleInfo> &get_available_modules() const
+ {
+ return modules;
+ }
+
+private:
+ ~MMgrBeacon() override {}
+
+public:
+
+ std::string_view get_type_name() const override { return "mgrbeacon"; }
+
+ void print(ostream& out) const override {
+ out << get_type_name() << " mgr." << name << "(" << fsid << ","
+ << gid << ", " << server_addrs << ", " << available
+ << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ using ceph::encode;
+ paxos_encode();
+
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ header.version = 7;
+ header.compat_version = 1;
+ encode(server_addrs.legacy_addr(), payload, features);
+ } else {
+ encode(server_addrs, payload, features);
+ }
+ encode(gid, payload);
+ encode(available, payload);
+ encode(name, payload);
+ encode(fsid, payload);
+
+ // Fill out old-style list of module names (deprecated by
+ // later field of full ModuleInfos)
+ std::set<std::string> module_names;
+ for (const auto &info : modules) {
+ module_names.insert(info.name);
+ }
+ encode(module_names, payload);
+
+ encode(command_descs, payload);
+ encode(metadata, payload);
+ encode(services, payload);
+
+ encode(modules, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(server_addrs, p); // entity_addr_t for version < 8
+ decode(gid, p);
+ decode(available, p);
+ decode(name, p);
+ if (header.version >= 2) {
+ decode(fsid, p);
+ }
+ if (header.version >= 3) {
+ std::set<std::string> module_name_list;
+ decode(module_name_list, p);
+ // Only need to unpack this field if we won't have the full
+ // ModuleInfo structures added in v7
+ if (header.version < 7) {
+ for (const auto &i : module_name_list) {
+ MgrMap::ModuleInfo info;
+ info.name = i;
+ modules.push_back(std::move(info));
+ }
+ }
+ }
+ if (header.version >= 4) {
+ decode(command_descs, p);
+ }
+ if (header.version >= 5) {
+ decode(metadata, p);
+ }
+ if (header.version >= 6) {
+ decode(services, p);
+ }
+ if (header.version >= 7) {
+ decode(modules, p);
+ }
+ }
+};
+
+
+#endif
diff --git a/src/messages/MMgrClose.h b/src/messages/MMgrClose.h
new file mode 100644
index 00000000..43d603a8
--- /dev/null
+++ b/src/messages/MMgrClose.h
@@ -0,0 +1,48 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+
+class MMgrClose : public MessageInstance<MMgrClose> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ std::string daemon_name;
+ std::string service_name; // optional; otherwise infer from entity type
+
+ void decode_payload() override
+ {
+ auto p = payload.cbegin();
+ decode(daemon_name, p);
+ decode(service_name, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(daemon_name, payload);
+ encode(service_name, payload);
+ }
+
+ std::string_view get_type_name() const override { return "mgrclose"; }
+ void print(ostream& out) const override {
+ out << get_type_name() << "(";
+ if (service_name.length()) {
+ out << service_name;
+ } else {
+ out << ceph_entity_type_name(get_source().type());
+ }
+ out << "." << daemon_name;
+ out << ")";
+ }
+
+ MMgrClose()
+ : MessageInstance(MSG_MGR_CLOSE, HEAD_VERSION, COMPAT_VERSION)
+ {}
+};
diff --git a/src/messages/MMgrConfigure.h b/src/messages/MMgrConfigure.h
new file mode 100644
index 00000000..b9f69095
--- /dev/null
+++ b/src/messages/MMgrConfigure.h
@@ -0,0 +1,72 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 John Spray <john.spray@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ */
+
+
+#ifndef CEPH_MMGRCONFIGURE_H_
+#define CEPH_MMGRCONFIGURE_H_
+
+#include "msg/Message.h"
+#include "mgr/OSDPerfMetricTypes.h"
+
+/**
+ * This message is sent from ceph-mgr to MgrClient, instructing it
+ * it about what data to send back to ceph-mgr at what frequency.
+ */
+class MMgrConfigure : public MessageInstance<MMgrConfigure> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ uint32_t stats_period = 0;
+
+ // Default 0 means if unspecified will include all stats
+ uint32_t stats_threshold = 0;
+
+ std::map<OSDPerfMetricQuery, OSDPerfMetricLimits> osd_perf_metric_queries;
+
+ void decode_payload() override
+ {
+ auto p = payload.cbegin();
+ decode(stats_period, p);
+ if (header.version >= 2) {
+ decode(stats_threshold, p);
+ }
+ if (header.version >= 3) {
+ decode(osd_perf_metric_queries, p);
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(stats_period, payload);
+ encode(stats_threshold, payload);
+ encode(osd_perf_metric_queries, payload);
+ }
+
+ std::string_view get_type_name() const override { return "mgrconfigure"; }
+ void print(ostream& out) const override {
+ out << get_type_name() << "(period=" << stats_period
+ << ", threshold=" << stats_threshold << ")";
+ }
+
+ MMgrConfigure()
+ : MessageInstance(MSG_MGR_CONFIGURE, HEAD_VERSION, COMPAT_VERSION)
+ {}
+};
+
+#endif
+
diff --git a/src/messages/MMgrDigest.h b/src/messages/MMgrDigest.h
new file mode 100644
index 00000000..ec4800d4
--- /dev/null
+++ b/src/messages/MMgrDigest.h
@@ -0,0 +1,56 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMGRDIGEST_H
+#define CEPH_MMGRDIGEST_H
+
+#include "msg/Message.h"
+
+/**
+ * The mgr digest is a way for the mgr to subscribe to things
+ * other than the cluster maps, which are needed by
+ */
+class MMgrDigest : public MessageInstance<MMgrDigest> {
+public:
+ friend factory;
+
+ bufferlist mon_status_json;
+ bufferlist health_json;
+
+ MMgrDigest() :
+ MessageInstance(MSG_MGR_DIGEST) {}
+
+ std::string_view get_type_name() const override { return "mgrdigest"; }
+ void print(ostream& out) const override {
+ out << get_type_name();
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(mon_status_json, p);
+ decode(health_json, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(mon_status_json, payload);
+ encode(health_json, payload);
+ }
+
+private:
+ ~MMgrDigest() override {}
+
+};
+
+#endif
diff --git a/src/messages/MMgrMap.h b/src/messages/MMgrMap.h
new file mode 100644
index 00000000..032a9c1a
--- /dev/null
+++ b/src/messages/MMgrMap.h
@@ -0,0 +1,58 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMGRMAP_H
+#define CEPH_MMGRMAP_H
+
+#include "msg/Message.h"
+#include "mon/MgrMap.h"
+
+class MMgrMap : public MessageInstance<MMgrMap> {
+public:
+ friend factory;
+
+protected:
+ MgrMap map;
+
+public:
+ const MgrMap & get_map() {return map;}
+
+ MMgrMap() :
+ MessageInstance(MSG_MGR_MAP) {}
+ MMgrMap(const MgrMap &map_) :
+ MessageInstance(MSG_MGR_MAP), map(map_)
+ {
+ }
+
+private:
+ ~MMgrMap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mgrmap"; }
+ void print(ostream& out) const override {
+ out << get_type_name() << "(e " << map.epoch << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(map, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(map, payload, features);
+ }
+};
+
+#endif
diff --git a/src/messages/MMgrOpen.h b/src/messages/MMgrOpen.h
new file mode 100644
index 00000000..754daf7d
--- /dev/null
+++ b/src/messages/MMgrOpen.h
@@ -0,0 +1,95 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 John Spray <john.spray@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ */
+
+
+#ifndef CEPH_MMGROPEN_H_
+#define CEPH_MMGROPEN_H_
+
+#include "msg/Message.h"
+
+class MMgrOpen : public MessageInstance<MMgrOpen> {
+public:
+ friend factory;
+private:
+
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+
+ std::string daemon_name;
+ std::string service_name; // optional; otherwise infer from entity type
+
+ bool service_daemon = false;
+ std::map<std::string,std::string> daemon_metadata;
+ std::map<std::string,std::string> daemon_status;
+
+ // encode map<string,map<int32_t,string>> of current config
+ bufferlist config_bl;
+
+ // encode map<string,string> of compiled-in defaults
+ bufferlist config_defaults_bl;
+
+ void decode_payload() override
+ {
+ auto p = payload.cbegin();
+ decode(daemon_name, p);
+ if (header.version >= 2) {
+ decode(service_name, p);
+ decode(service_daemon, p);
+ if (service_daemon) {
+ decode(daemon_metadata, p);
+ decode(daemon_status, p);
+ }
+ }
+ if (header.version >= 3) {
+ decode(config_bl, p);
+ decode(config_defaults_bl, p);
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(daemon_name, payload);
+ encode(service_name, payload);
+ encode(service_daemon, payload);
+ if (service_daemon) {
+ encode(daemon_metadata, payload);
+ encode(daemon_status, payload);
+ }
+ encode(config_bl, payload);
+ encode(config_defaults_bl, payload);
+ }
+
+ std::string_view get_type_name() const override { return "mgropen"; }
+ void print(ostream& out) const override {
+ out << get_type_name() << "(";
+ if (service_name.length()) {
+ out << service_name;
+ } else {
+ out << ceph_entity_type_name(get_source().type());
+ }
+ out << "." << daemon_name;
+ if (service_daemon) {
+ out << " daemon";
+ }
+ out << ")";
+ }
+
+ MMgrOpen()
+ : MessageInstance(MSG_MGR_OPEN, HEAD_VERSION, COMPAT_VERSION)
+ {}
+};
+
+#endif
+
diff --git a/src/messages/MMgrReport.h b/src/messages/MMgrReport.h
new file mode 100644
index 00000000..e9887117
--- /dev/null
+++ b/src/messages/MMgrReport.h
@@ -0,0 +1,186 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 John Spray <john.spray@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ */
+
+
+#ifndef CEPH_MMGRREPORT_H_
+#define CEPH_MMGRREPORT_H_
+
+#include <boost/optional.hpp>
+
+#include "msg/Message.h"
+#include "mgr/OSDPerfMetricTypes.h"
+
+#include "common/perf_counters.h"
+#include "mgr/DaemonHealthMetric.h"
+
+class PerfCounterType
+{
+public:
+ std::string path;
+ std::string description;
+ std::string nick;
+ enum perfcounter_type_d type;
+
+ // For older clients that did not send priority, pretend everything
+ // is "useful" so that mgr plugins filtering on prio will get some
+ // data (albeit probably more than they wanted)
+ uint8_t priority = PerfCountersBuilder::PRIO_USEFUL;
+ enum unit_t unit;
+
+ void encode(bufferlist &bl) const
+ {
+ // TODO: decide whether to drop the per-type
+ // encoding here, we could rely on the MgrReport
+ // verisoning instead.
+ ENCODE_START(3, 1, bl);
+ encode(path, bl);
+ encode(description, bl);
+ encode(nick, bl);
+ static_assert(sizeof(type) == 1, "perfcounter_type_d must be one byte");
+ encode((uint8_t)type, bl);
+ encode(priority, bl);
+ encode((uint8_t)unit, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::const_iterator &p)
+ {
+ DECODE_START(3, p);
+ decode(path, p);
+ decode(description, p);
+ decode(nick, p);
+ uint8_t raw_type;
+ decode(raw_type, p);
+ type = (enum perfcounter_type_d)raw_type;
+ if (struct_v >= 2) {
+ decode(priority, p);
+ }
+ if (struct_v >= 3) {
+ uint8_t raw_unit;
+ decode(raw_unit, p);
+ unit = (enum unit_t)raw_unit;
+ }
+ DECODE_FINISH(p);
+ }
+};
+WRITE_CLASS_ENCODER(PerfCounterType)
+
+class MMgrReport : public MessageInstance<MMgrReport> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ /**
+ * Client is responsible for remembering whether it has introduced
+ * each perf counter to the server. When first sending a particular
+ * counter, it must inline the counter's schema here.
+ */
+ std::vector<PerfCounterType> declare_types;
+ std::vector<std::string> undeclare_types;
+
+ // For all counters present, sorted by idx, output
+ // as many bytes as are needed to represent them
+
+ // Decode: iterate over the types we know about, sorted by idx,
+ // and use the current type's type to decide how to decode
+ // the next bytes from the bufferlist.
+ bufferlist packed;
+
+ std::string daemon_name;
+ std::string service_name; // optional; otherwise infer from entity type
+
+ // for service registration
+ boost::optional<std::map<std::string,std::string>> daemon_status;
+ boost::optional<std::map<std::string,std::string>> task_status;
+
+ std::vector<DaemonHealthMetric> daemon_health_metrics;
+
+ // encode map<string,map<int32_t,string>> of current config
+ bufferlist config_bl;
+
+ std::map<OSDPerfMetricQuery, OSDPerfMetricReport> osd_perf_metric_reports;
+
+ void decode_payload() override
+ {
+ auto p = payload.cbegin();
+ decode(daemon_name, p);
+ decode(declare_types, p);
+ decode(packed, p);
+ if (header.version >= 2)
+ decode(undeclare_types, p);
+ if (header.version >= 3) {
+ decode(service_name, p);
+ decode(daemon_status, p);
+ }
+ if (header.version >= 5) {
+ decode(daemon_health_metrics, p);
+ }
+ if (header.version >= 6) {
+ decode(config_bl, p);
+ }
+ if (header.version >= 7) {
+ decode(osd_perf_metric_reports, p);
+ }
+ if (header.version >= 8) {
+ decode(task_status, p);
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(daemon_name, payload);
+ encode(declare_types, payload);
+ encode(packed, payload);
+ encode(undeclare_types, payload);
+ encode(service_name, payload);
+ encode(daemon_status, payload);
+ encode(daemon_health_metrics, payload);
+ encode(config_bl, payload);
+ encode(osd_perf_metric_reports, payload);
+ encode(task_status, payload);
+ }
+
+ std::string_view get_type_name() const override { return "mgrreport"; }
+ void print(ostream& out) const override {
+ out << get_type_name() << "(";
+ if (service_name.length()) {
+ out << service_name;
+ } else {
+ out << ceph_entity_type_name(get_source().type());
+ }
+ out << "." << daemon_name
+ << " +" << declare_types.size()
+ << "-" << undeclare_types.size()
+ << " packed " << packed.length();
+ if (daemon_status) {
+ out << " status=" << daemon_status->size();
+ }
+ if (!daemon_health_metrics.empty()) {
+ out << " daemon_metrics=" << daemon_health_metrics.size();
+ }
+ if (task_status) {
+ out << " task_status=" << task_status->size();
+ }
+ out << ")";
+ }
+
+ MMgrReport()
+ : MessageInstance(MSG_MGR_REPORT, HEAD_VERSION, COMPAT_VERSION)
+ {}
+};
+
+#endif
+
diff --git a/src/messages/MMonCommand.h b/src/messages/MMonCommand.h
new file mode 100644
index 00000000..18900832
--- /dev/null
+++ b/src/messages/MMonCommand.h
@@ -0,0 +1,81 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONCOMMAND_H
+#define CEPH_MMONCOMMAND_H
+
+#include "common/cmdparse.h"
+#include "messages/PaxosServiceMessage.h"
+
+#include <vector>
+#include <string>
+
+class MMonCommand : public MessageInstance<MMonCommand, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ uuid_d fsid;
+ std::vector<std::string> cmd;
+
+ MMonCommand() : MessageInstance(MSG_MON_COMMAND, 0) {}
+ MMonCommand(const uuid_d &f)
+ : MessageInstance(MSG_MON_COMMAND, 0),
+ fsid(f)
+ { }
+
+private:
+ ~MMonCommand() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_command"; }
+ void print(ostream& o) const override {
+ cmdmap_t cmdmap;
+ stringstream ss;
+ string prefix;
+ cmdmap_from_json(cmd, &cmdmap, ss);
+ cmd_getval(g_ceph_context, cmdmap, "prefix", prefix);
+ // Some config values contain sensitive data, so don't log them
+ o << "mon_command(";
+ if (prefix == "config set") {
+ string name;
+ cmd_getval(g_ceph_context, cmdmap, "name", name);
+ o << "[{prefix=" << prefix << ", name=" << name << "}]";
+ } else if (prefix == "config-key set") {
+ string key;
+ cmd_getval(g_ceph_context, cmdmap, "key", key);
+ o << "[{prefix=" << prefix << ", key=" << key << "}]";
+ } else {
+ for (unsigned i=0; i<cmd.size(); i++) {
+ if (i) o << ' ';
+ o << cmd[i];
+ }
+ }
+ o << " v " << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(cmd, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(cmd, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonCommandAck.h b/src/messages/MMonCommandAck.h
new file mode 100644
index 00000000..7802e6e0
--- /dev/null
+++ b/src/messages/MMonCommandAck.h
@@ -0,0 +1,79 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONCOMMANDACK_H
+#define CEPH_MMONCOMMANDACK_H
+
+#include "common/cmdparse.h"
+#include "messages/PaxosServiceMessage.h"
+
+class MMonCommandAck : public MessageInstance<MMonCommandAck, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ vector<string> cmd;
+ errorcode32_t r;
+ string rs;
+
+ MMonCommandAck() : MessageInstance(MSG_MON_COMMAND_ACK, 0) {}
+ MMonCommandAck(vector<string>& c, int _r, string s, version_t v) :
+ MessageInstance(MSG_MON_COMMAND_ACK, v),
+ cmd(c), r(_r), rs(s) { }
+private:
+ ~MMonCommandAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_command"; }
+ void print(ostream& o) const override {
+ cmdmap_t cmdmap;
+ stringstream ss;
+ string prefix;
+ cmdmap_from_json(cmd, &cmdmap, ss);
+ cmd_getval(g_ceph_context, cmdmap, "prefix", prefix);
+ // Some config values contain sensitive data, so don't log them
+ o << "mon_command_ack(";
+ if (prefix == "config set") {
+ string name;
+ cmd_getval(g_ceph_context, cmdmap, "name", name);
+ o << "[{prefix=" << prefix
+ << ", name=" << name << "}]"
+ << "=" << r << " " << rs << " v" << version << ")";
+ } else if (prefix == "config-key set") {
+ string key;
+ cmd_getval(g_ceph_context, cmdmap, "key", key);
+ o << "[{prefix=" << prefix << ", key=" << key << "}]"
+ << "=" << r << " " << rs << " v" << version << ")";
+ } else {
+ o << cmd;
+ }
+ o << "=" << r << " " << rs << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(r, payload);
+ encode(rs, payload);
+ encode(cmd, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(r, p);
+ decode(rs, p);
+ decode(cmd, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonElection.h b/src/messages/MMonElection.h
new file mode 100644
index 00000000..0114ea12
--- /dev/null
+++ b/src/messages/MMonElection.h
@@ -0,0 +1,132 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMONELECTION_H
+#define CEPH_MMONELECTION_H
+
+#include "msg/Message.h"
+#include "mon/MonMap.h"
+#include "mon/mon_types.h"
+
+class MMonElection : public MessageInstance<MMonElection> {
+public:
+ friend factory;
+
+private:
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 5;
+
+public:
+ static constexpr int OP_PROPOSE = 1;
+ static constexpr int OP_ACK = 2;
+ static constexpr int OP_NAK = 3;
+ static constexpr int OP_VICTORY = 4;
+ static const char *get_opname(int o) {
+ switch (o) {
+ case OP_PROPOSE: return "propose";
+ case OP_ACK: return "ack";
+ case OP_NAK: return "nak";
+ case OP_VICTORY: return "victory";
+ default: ceph_abort(); return 0;
+ }
+ }
+
+ uuid_d fsid;
+ int32_t op;
+ epoch_t epoch;
+ bufferlist monmap_bl;
+ set<int32_t> quorum;
+ uint64_t quorum_features;
+ mon_feature_t mon_features;
+ uint8_t mon_release = 0;
+ bufferlist sharing_bl;
+ map<string,string> metadata;
+
+ MMonElection() : MessageInstance(MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION),
+ op(0), epoch(0),
+ quorum_features(0),
+ mon_features(0)
+ { }
+
+ MMonElection(int o, epoch_t e, MonMap *m)
+ : MessageInstance(MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION),
+ fsid(m->fsid), op(o), epoch(e),
+ quorum_features(0),
+ mon_features(0)
+ {
+ // encode using full feature set; we will reencode for dest later,
+ // if necessary
+ m->encode(monmap_bl, CEPH_FEATURES_ALL);
+ }
+private:
+ ~MMonElection() override {}
+
+public:
+ std::string_view get_type_name() const override { return "election"; }
+ void print(ostream& out) const override {
+ out << "election(" << fsid << " " << get_opname(op)
+ << " rel " << (int)mon_release << " e" << epoch << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if (monmap_bl.length() && (features != CEPH_FEATURES_ALL)) {
+ // reencode old-format monmap
+ MonMap t;
+ t.decode(monmap_bl);
+ monmap_bl.clear();
+ t.encode(monmap_bl, features);
+ }
+
+ encode(fsid, payload);
+ encode(op, payload);
+ encode(epoch, payload);
+ encode(monmap_bl, payload);
+ encode(quorum, payload);
+ encode(quorum_features, payload);
+ encode((version_t)0, payload); // defunct
+ encode((version_t)0, payload); // defunct
+ encode(sharing_bl, payload);
+ encode(mon_features, payload);
+ encode(metadata, payload);
+ encode(mon_release, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(op, p);
+ decode(epoch, p);
+ decode(monmap_bl, p);
+ decode(quorum, p);
+ decode(quorum_features, p);
+ {
+ version_t v; // defunct fields from old encoding
+ decode(v, p);
+ decode(v, p);
+ }
+ decode(sharing_bl, p);
+ if (header.version >= 6)
+ decode(mon_features, p);
+ if (header.version >= 7)
+ decode(metadata, p);
+ if (header.version >= 8)
+ decode(mon_release, p);
+ else
+ mon_release = infer_ceph_release_from_mon_features(mon_features);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MMonGetMap.h b/src/messages/MMonGetMap.h
new file mode 100644
index 00000000..99950ef4
--- /dev/null
+++ b/src/messages/MMonGetMap.h
@@ -0,0 +1,37 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONGETMAP_H
+#define CEPH_MMONGETMAP_H
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+class MMonGetMap : public MessageInstance<MMonGetMap> {
+public:
+ friend factory;
+
+ MMonGetMap() : MessageInstance(CEPH_MSG_MON_GET_MAP) { }
+private:
+ ~MMonGetMap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_getmap"; }
+
+ void encode_payload(uint64_t features) override { }
+ void decode_payload() override { }
+};
+
+#endif
diff --git a/src/messages/MMonGetOSDMap.h b/src/messages/MMonGetOSDMap.h
new file mode 100644
index 00000000..926a6083
--- /dev/null
+++ b/src/messages/MMonGetOSDMap.h
@@ -0,0 +1,93 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2014 Red Hat
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONGETOSDMAP_H
+#define CEPH_MMONGETOSDMAP_H
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+class MMonGetOSDMap : public MessageInstance<MMonGetOSDMap, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+
+ epoch_t full_first, full_last;
+ epoch_t inc_first, inc_last;
+
+public:
+ MMonGetOSDMap()
+ : MessageInstance(CEPH_MSG_MON_GET_OSDMAP, 0),
+ full_first(0),
+ full_last(0),
+ inc_first(0),
+ inc_last(0) { }
+private:
+ ~MMonGetOSDMap() override {}
+
+public:
+ void request_full(epoch_t first, epoch_t last) {
+ ceph_assert(last >= first);
+ full_first = first;
+ full_last = last;
+ }
+ void request_inc(epoch_t first, epoch_t last) {
+ ceph_assert(last >= first);
+ inc_first = first;
+ inc_last = last;
+ }
+ epoch_t get_full_first() const {
+ return full_first;
+ }
+ epoch_t get_full_last() const {
+ return full_last;
+ }
+ epoch_t get_inc_first() const {
+ return inc_first;
+ }
+ epoch_t get_inc_last() const {
+ return inc_last;
+ }
+
+ std::string_view get_type_name() const override { return "mon_get_osdmap"; }
+ void print(ostream& out) const override {
+ out << "mon_get_osdmap(";
+ if (full_first && full_last)
+ out << "full " << full_first << "-" << full_last;
+ if (inc_first && inc_last)
+ out << " inc" << inc_first << "-" << inc_last;
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(full_first, payload);
+ encode(full_last, payload);
+ encode(inc_first, payload);
+ encode(inc_last, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(full_first, p);
+ decode(full_last, p);
+ decode(inc_first, p);
+ decode(inc_last, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonGetVersion.h b/src/messages/MMonGetVersion.h
new file mode 100644
index 00000000..84a88d26
--- /dev/null
+++ b/src/messages/MMonGetVersion.h
@@ -0,0 +1,61 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONGETVERSION_H
+#define CEPH_MMONGETVERSION_H
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+/*
+ * This message is sent to the monitors to verify that the client's
+ * version of the map(s) is the latest available. For example, this
+ * can be used to determine whether a pool actually does not exist, or
+ * if it may have been created but the map was not received yet.
+ */
+class MMonGetVersion : public MessageInstance<MMonGetVersion> {
+public:
+ friend factory;
+
+ MMonGetVersion() : MessageInstance(CEPH_MSG_MON_GET_VERSION) {}
+
+ std::string_view get_type_name() const override {
+ return "mon_get_version";
+ }
+
+ void print(ostream& o) const override {
+ o << "mon_get_version(what=" << what << " handle=" << handle << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(handle, payload);
+ encode(what, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(handle, p);
+ decode(what, p);
+ }
+
+ ceph_tid_t handle = 0;
+ string what;
+
+private:
+ ~MMonGetVersion() override {}
+};
+
+#endif
diff --git a/src/messages/MMonGetVersionReply.h b/src/messages/MMonGetVersionReply.h
new file mode 100644
index 00000000..768ea18c
--- /dev/null
+++ b/src/messages/MMonGetVersionReply.h
@@ -0,0 +1,67 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONGETVERSIONREPLY_H
+#define CEPH_MMONGETVERSIONREPLY_H
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+/*
+ * This message is sent from the monitors to clients in response to a
+ * MMonGetVersion. The latest version of the requested thing is sent
+ * back.
+ */
+class MMonGetVersionReply : public MessageInstance<MMonGetVersionReply> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+
+public:
+ MMonGetVersionReply() : MessageInstance(CEPH_MSG_MON_GET_VERSION_REPLY, HEAD_VERSION) { }
+
+ std::string_view get_type_name() const override {
+ return "mon_get_version_reply";
+ }
+
+ void print(ostream& o) const override {
+ o << "mon_get_version_reply(handle=" << handle << " version=" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(handle, payload);
+ encode(version, payload);
+ encode(oldest_version, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(handle, p);
+ decode(version, p);
+ if (header.version >= 2)
+ decode(oldest_version, p);
+ }
+
+ ceph_tid_t handle = 0;
+ version_t version = 0;
+ version_t oldest_version = 0;
+
+private:
+ ~MMonGetVersionReply() override {}
+};
+
+#endif
diff --git a/src/messages/MMonGlobalID.h b/src/messages/MMonGlobalID.h
new file mode 100644
index 00000000..79535a6b
--- /dev/null
+++ b/src/messages/MMonGlobalID.h
@@ -0,0 +1,47 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONGLOBALID_H
+#define CEPH_MMONGLOBALID_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MMonGlobalID : public MessageInstance<MMonGlobalID, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ uint64_t old_max_id;
+ MMonGlobalID() : MessageInstance(MSG_MON_GLOBAL_ID, 0), old_max_id(0) { }
+private:
+ ~MMonGlobalID() override {}
+
+public:
+ std::string_view get_type_name() const override { return "global_id"; }
+ void print(ostream& out) const override {
+ out << "global_id (" << old_max_id << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(old_max_id, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(old_max_id, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonHealth.h b/src/messages/MMonHealth.h
new file mode 100644
index 00000000..1d837184
--- /dev/null
+++ b/src/messages/MMonHealth.h
@@ -0,0 +1,65 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2012 Inktank, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+#ifndef CEPH_MMON_HEALTH_H
+#define CEPH_MMON_HEALTH_H
+
+#include "msg/Message.h"
+#include "messages/MMonQuorumService.h"
+#include "mon/mon_types.h"
+
+class MMonHealth : public MessageInstance<MMonHealth, MMonQuorumService> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+
+ int service_type = 0;
+ int service_op = 0;
+
+ // service specific data
+ DataStats data_stats;
+
+ MMonHealth() : MessageInstance(MSG_MON_HEALTH, HEAD_VERSION) { }
+
+private:
+ ~MMonHealth() override { }
+
+public:
+ std::string_view get_type_name() const override { return "mon_health"; }
+ void print(ostream &o) const override {
+ o << "mon_health("
+ << " e " << get_epoch()
+ << " r " << get_round()
+ << " )";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ service_decode(p);
+ decode(service_type, p);
+ decode(service_op, p);
+ decode(data_stats, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ service_encode();
+ encode(service_type, payload);
+ encode(service_op, payload);
+ encode(data_stats, payload);
+ }
+
+};
+
+#endif /* CEPH_MMON_HEALTH_H */
diff --git a/src/messages/MMonHealthChecks.h b/src/messages/MMonHealthChecks.h
new file mode 100644
index 00000000..e9e611b1
--- /dev/null
+++ b/src/messages/MMonHealthChecks.h
@@ -0,0 +1,50 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MMON_HEALTH_CHECKS_H
+#define CEPH_MMON_HEALTH_CHECKS_H
+
+#include "messages/PaxosServiceMessage.h"
+#include "mon/health_check.h"
+
+class MMonHealthChecks : public MessageInstance<MMonHealthChecks, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ health_check_map_t health_checks;
+
+ MMonHealthChecks()
+ : MessageInstance(MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION) {
+ }
+ MMonHealthChecks(health_check_map_t& m)
+ : MessageInstance(MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION),
+ health_checks(m) {
+ }
+
+private:
+ ~MMonHealthChecks() override { }
+
+public:
+ std::string_view get_type_name() const override { return "mon_health_checks"; }
+ void print(ostream &o) const override {
+ o << "mon_health_checks(" << health_checks.checks.size() << " checks)";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(health_checks, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(health_checks, payload);
+ }
+
+};
+
+#endif
diff --git a/src/messages/MMonJoin.h b/src/messages/MMonJoin.h
new file mode 100644
index 00000000..15d8ac94
--- /dev/null
+++ b/src/messages/MMonJoin.h
@@ -0,0 +1,79 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONJOIN_H
+#define CEPH_MMONJOIN_H
+
+#include "messages/PaxosServiceMessage.h"
+
+#include <vector>
+using std::vector;
+
+class MMonJoin : public MessageInstance<MMonJoin, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+ uuid_d fsid;
+ string name;
+ entity_addrvec_t addrs;
+
+ MMonJoin() : MessageInstance(MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION) {}
+ MMonJoin(uuid_d &f, string n, const entity_addrvec_t& av)
+ : MessageInstance(MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), name(n), addrs(av)
+ { }
+
+private:
+ ~MMonJoin() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_join"; }
+ void print(ostream& o) const override {
+ o << "mon_join(" << name << " " << addrs << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(name, payload);
+ if (HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(addrs, payload, features);
+ } else {
+ header.version = 1;
+ header.compat_version = 1;
+ encode(addrs.legacy_addr(), payload, features);
+ }
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(name, p);
+ if (header.version == 1) {
+ entity_addr_t addr;
+ decode(addr, p);
+ addrs = entity_addrvec_t(addr);
+ } else {
+ decode(addrs, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MMonMap.h b/src/messages/MMonMap.h
new file mode 100644
index 00000000..57034b8b
--- /dev/null
+++ b/src/messages/MMonMap.h
@@ -0,0 +1,58 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONMAP_H
+#define CEPH_MMONMAP_H
+
+#include "include/ceph_features.h"
+#include "msg/Message.h"
+#include "mon/MonMap.h"
+
+class MMonMap : public MessageInstance<MMonMap> {
+public:
+ friend factory;
+
+ bufferlist monmapbl;
+
+ MMonMap() : MessageInstance(CEPH_MSG_MON_MAP) { }
+ explicit MMonMap(bufferlist &bl) : MessageInstance(CEPH_MSG_MON_MAP) {
+ monmapbl.claim(bl);
+ }
+private:
+ ~MMonMap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_map"; }
+
+ void encode_payload(uint64_t features) override {
+ if (monmapbl.length() &&
+ ((features & CEPH_FEATURE_MONENC) == 0 ||
+ (features & CEPH_FEATURE_MSG_ADDR2) == 0)) {
+ // reencode old-format monmap
+ MonMap t;
+ t.decode(monmapbl);
+ monmapbl.clear();
+ t.encode(monmapbl, features);
+ }
+
+ using ceph::encode;
+ encode(monmapbl, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(monmapbl, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonMetadata.h b/src/messages/MMonMetadata.h
new file mode 100644
index 00000000..70c517b4
--- /dev/null
+++ b/src/messages/MMonMetadata.h
@@ -0,0 +1,55 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONMETADATA_H
+#define CEPH_MMONMETADATA_H
+
+#include "mon/mon_types.h"
+#include "msg/Message.h"
+
+class MMonMetadata : public MessageInstance<MMonMetadata> {
+public:
+ friend factory;
+
+ Metadata data;
+
+private:
+ static constexpr int HEAD_VERSION = 1;
+ ~MMonMetadata() override {}
+
+public:
+ MMonMetadata() :
+ MessageInstance(CEPH_MSG_MON_METADATA)
+ {}
+ MMonMetadata(const Metadata& metadata) :
+ MessageInstance(CEPH_MSG_MON_METADATA, HEAD_VERSION),
+ data(metadata)
+ {}
+
+ std::string_view get_type_name() const override {
+ return "mon_metadata";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(data, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(data, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonMgrReport.h b/src/messages/MMonMgrReport.h
new file mode 100644
index 00000000..097fa014
--- /dev/null
+++ b/src/messages/MMonMgrReport.h
@@ -0,0 +1,87 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2017 Greg Farnum/Red Hat <gfarnum@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONMGRREPORT_H
+#define CEPH_MMONMGRREPORT_H
+
+#include "messages/PaxosServiceMessage.h"
+#include "include/types.h"
+#include "include/health.h"
+#include "mon/health_check.h"
+#include "mon/PGMap.h"
+
+class MMonMgrReport
+ : public MessageInstance<MMonMgrReport, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ // PGMapDigest is in data payload
+ health_check_map_t health_checks;
+ bufferlist service_map_bl; // encoded ServiceMap
+ std::map<std::string,ProgressEvent> progress_events;
+
+ MMonMgrReport()
+ : MessageInstance(MSG_MON_MGR_REPORT, 0, HEAD_VERSION, COMPAT_VERSION)
+ {}
+private:
+ ~MMonMgrReport() override {}
+
+public:
+ std::string_view get_type_name() const override { return "monmgrreport"; }
+
+ void print(ostream& out) const override {
+ out << get_type_name() << "(" << health_checks.checks.size() << " checks, "
+ << progress_events.size() << " progress events)";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(health_checks, payload);
+ encode(service_map_bl, payload);
+ encode(progress_events, payload);
+
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS) ||
+ !HAVE_FEATURE(features, SERVER_MIMIC)) {
+ // PGMapDigest had a backwards-incompatible change between
+ // luminous and mimic, and conditionally encodes based on
+ // provided features, so reencode the one in our data payload.
+ // The mgr isn't able to do this at the time the encoded
+ // PGMapDigest is constructed because we don't know which mon we
+ // will target. Note that this only triggers if the user
+ // upgrades ceph-mgr before ceph-mon (tsk tsk).
+ PGMapDigest digest;
+ auto p = data.cbegin();
+ decode(digest, p);
+ bufferlist bl;
+ encode(digest, bl, features);
+ set_data(bl);
+ }
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(health_checks, p);
+ decode(service_map_bl, p);
+ if (header.version >= 2) {
+ decode(progress_events, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MMonPaxos.h b/src/messages/MMonPaxos.h
new file mode 100644
index 00000000..b0fc1f70
--- /dev/null
+++ b/src/messages/MMonPaxos.h
@@ -0,0 +1,133 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMONPAXOS_H
+#define CEPH_MMONPAXOS_H
+
+#include "messages/PaxosServiceMessage.h"
+#include "mon/mon_types.h"
+#include "include/ceph_features.h"
+
+class MMonPaxos : public MessageInstance<MMonPaxos> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 3;
+
+ public:
+ // op types
+ static constexpr int OP_COLLECT = 1; // proposer: propose round
+ static constexpr int OP_LAST = 2; // voter: accept proposed round
+ static constexpr int OP_BEGIN = 3; // proposer: value proposed for this round
+ static constexpr int OP_ACCEPT = 4; // voter: accept propsed value
+ static constexpr int OP_COMMIT = 5; // proposer: notify learners of agreed value
+ static constexpr int OP_LEASE = 6; // leader: extend peon lease
+ static constexpr int OP_LEASE_ACK = 7; // peon: lease ack
+ static const char *get_opname(int op) {
+ switch (op) {
+ case OP_COLLECT: return "collect";
+ case OP_LAST: return "last";
+ case OP_BEGIN: return "begin";
+ case OP_ACCEPT: return "accept";
+ case OP_COMMIT: return "commit";
+ case OP_LEASE: return "lease";
+ case OP_LEASE_ACK: return "lease_ack";
+ default: ceph_abort(); return 0;
+ }
+ }
+
+ epoch_t epoch = 0; // monitor epoch
+ __s32 op = 0; // paxos op
+
+ version_t first_committed = 0; // i've committed to
+ version_t last_committed = 0; // i've committed to
+ version_t pn_from = 0; // i promise to accept after
+ version_t pn = 0; // with with proposal
+ version_t uncommitted_pn = 0; // previous pn, if we are a LAST with an uncommitted value
+ utime_t lease_timestamp;
+ utime_t sent_timestamp;
+
+ version_t latest_version = 0;
+ bufferlist latest_value;
+
+ map<version_t,bufferlist> values;
+
+ bufferlist feature_map;
+
+ MMonPaxos() : MessageInstance(MSG_MON_PAXOS, HEAD_VERSION, COMPAT_VERSION) { }
+ MMonPaxos(epoch_t e, int o, utime_t now) :
+ MessageInstance(MSG_MON_PAXOS, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e),
+ op(o),
+ first_committed(0), last_committed(0), pn_from(0), pn(0), uncommitted_pn(0),
+ sent_timestamp(now),
+ latest_version(0) {
+ }
+
+private:
+ ~MMonPaxos() override {}
+
+public:
+ std::string_view get_type_name() const override { return "paxos"; }
+
+ void print(ostream& out) const override {
+ out << "paxos(" << get_opname(op)
+ << " lc " << last_committed
+ << " fc " << first_committed
+ << " pn " << pn << " opn " << uncommitted_pn;
+ if (latest_version)
+ out << " latest " << latest_version << " (" << latest_value.length() << " bytes)";
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ header.version = HEAD_VERSION;
+ encode(epoch, payload);
+ encode(op, payload);
+ encode(first_committed, payload);
+ encode(last_committed, payload);
+ encode(pn_from, payload);
+ encode(pn, payload);
+ encode(uncommitted_pn, payload);
+ encode(lease_timestamp, payload);
+ encode(sent_timestamp, payload);
+ encode(latest_version, payload);
+ encode(latest_value, payload);
+ encode(values, payload);
+ encode(feature_map, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(op, p);
+ decode(first_committed, p);
+ decode(last_committed, p);
+ decode(pn_from, p);
+ decode(pn, p);
+ decode(uncommitted_pn, p);
+ decode(lease_timestamp, p);
+ decode(sent_timestamp, p);
+ decode(latest_version, p);
+ decode(latest_value, p);
+ decode(values, p);
+ if (header.version >= 4) {
+ decode(feature_map, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MMonProbe.h b/src/messages/MMonProbe.h
new file mode 100644
index 00000000..8b878dfd
--- /dev/null
+++ b/src/messages/MMonProbe.h
@@ -0,0 +1,142 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MMONPROBE_H
+#define CEPH_MMONPROBE_H
+
+#include "include/ceph_features.h"
+#include "msg/Message.h"
+#include "mon/MonMap.h"
+
+class MMonProbe : public MessageInstance<MMonProbe> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 7;
+ static constexpr int COMPAT_VERSION = 5;
+
+ enum {
+ OP_PROBE = 1,
+ OP_REPLY = 2,
+ OP_SLURP = 3,
+ OP_SLURP_LATEST = 4,
+ OP_DATA = 5,
+ OP_MISSING_FEATURES = 6,
+ };
+
+ static const char *get_opname(int o) {
+ switch (o) {
+ case OP_PROBE: return "probe";
+ case OP_REPLY: return "reply";
+ case OP_SLURP: return "slurp";
+ case OP_SLURP_LATEST: return "slurp_latest";
+ case OP_DATA: return "data";
+ case OP_MISSING_FEATURES: return "missing_features";
+ default: ceph_abort(); return 0;
+ }
+ }
+
+ uuid_d fsid;
+ int32_t op = 0;
+ string name;
+ set<int32_t> quorum;
+ bufferlist monmap_bl;
+ version_t paxos_first_version = 0;
+ version_t paxos_last_version = 0;
+ bool has_ever_joined = 0;
+ uint64_t required_features = 0;
+ uint8_t mon_release = 0;
+
+ MMonProbe()
+ : MessageInstance(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION) {}
+ MMonProbe(const uuid_d& f, int o, const string& n, bool hej, uint8_t mr)
+ : MessageInstance(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f),
+ op(o),
+ name(n),
+ paxos_first_version(0),
+ paxos_last_version(0),
+ has_ever_joined(hej),
+ required_features(0),
+ mon_release(mr) {}
+private:
+ ~MMonProbe() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_probe"; }
+ void print(ostream& out) const override {
+ out << "mon_probe(" << get_opname(op) << " " << fsid << " name " << name;
+ if (quorum.size())
+ out << " quorum " << quorum;
+ if (op == OP_REPLY) {
+ out << " paxos("
+ << " fc " << paxos_first_version
+ << " lc " << paxos_last_version
+ << " )";
+ }
+ if (!has_ever_joined)
+ out << " new";
+ if (required_features)
+ out << " required_features " << required_features;
+ if (mon_release)
+ out << " mon_release " << (int)mon_release;
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if (monmap_bl.length() &&
+ ((features & CEPH_FEATURE_MONENC) == 0 ||
+ (features & CEPH_FEATURE_MSG_ADDR2) == 0)) {
+ // reencode old-format monmap
+ MonMap t;
+ t.decode(monmap_bl);
+ monmap_bl.clear();
+ t.encode(monmap_bl, features);
+ }
+
+ encode(fsid, payload);
+ encode(op, payload);
+ encode(name, payload);
+ encode(quorum, payload);
+ encode(monmap_bl, payload);
+ encode(has_ever_joined, payload);
+ encode(paxos_first_version, payload);
+ encode(paxos_last_version, payload);
+ encode(required_features, payload);
+ encode(mon_release, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(op, p);
+ decode(name, p);
+ decode(quorum, p);
+ decode(monmap_bl, p);
+ decode(has_ever_joined, p);
+ decode(paxos_first_version, p);
+ decode(paxos_last_version, p);
+ if (header.version >= 6)
+ decode(required_features, p);
+ else
+ required_features = 0;
+ if (header.version >= 7)
+ decode(mon_release, p);
+ else
+ mon_release = 0;
+ }
+};
+
+#endif
diff --git a/src/messages/MMonQuorumService.h b/src/messages/MMonQuorumService.h
new file mode 100644
index 00000000..7ad1eeb5
--- /dev/null
+++ b/src/messages/MMonQuorumService.h
@@ -0,0 +1,70 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2012 Inktank, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+#ifndef CEPH_MMON_QUORUM_SERVICE_H
+#define CEPH_MMON_QUORUM_SERVICE_H
+
+#include "msg/Message.h"
+
+class MMonQuorumService : public MessageSubType<MMonQuorumService> {
+public:
+ epoch_t epoch = 0;
+ version_t round = 0;
+
+protected:
+template<typename... Args>
+ MMonQuorumService(Args&&... args) : MessageSubType(std::forward<Args>(args)...) {}
+
+ ~MMonQuorumService() override { }
+
+public:
+
+ void set_epoch(epoch_t e) {
+ epoch = e;
+ }
+
+ void set_round(version_t r) {
+ round = r;
+ }
+
+ epoch_t get_epoch() const {
+ return epoch;
+ }
+
+ version_t get_round() const {
+ return round;
+ }
+
+ void service_encode() {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(round, payload);
+ }
+
+ void service_decode(bufferlist::const_iterator &p) {
+ decode(epoch, p);
+ decode(round, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ ceph_abort_msg("MMonQuorumService message must always be a base class");
+ }
+
+ void decode_payload() override {
+ ceph_abort_msg("MMonQuorumService message must always be a base class");
+ }
+
+ std::string_view get_type_name() const override { return "quorum_service"; }
+};
+
+#endif /* CEPH_MMON_QUORUM_SERVICE_H */
diff --git a/src/messages/MMonScrub.h b/src/messages/MMonScrub.h
new file mode 100644
index 00000000..8924bad9
--- /dev/null
+++ b/src/messages/MMonScrub.h
@@ -0,0 +1,90 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+* Ceph - scalable distributed file system
+*
+* Copyright (C) 2013 Inktank, Inc.
+*
+* This is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License version 2.1, as published by the Free Software
+* Foundation. See file COPYING.
+*/
+#ifndef CEPH_MMONSCRUB_H
+#define CEPH_MMONSCRUB_H
+
+#include "msg/Message.h"
+#include "mon/mon_types.h"
+
+class MMonScrub : public MessageInstance<MMonScrub> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ typedef enum {
+ OP_SCRUB = 1, // leader->peon: scrub (a range of) keys
+ OP_RESULT = 2, // peon->leader: result of a scrub
+ } op_type_t;
+
+ static const char *get_opname(op_type_t op) {
+ switch (op) {
+ case OP_SCRUB: return "scrub";
+ case OP_RESULT: return "result";
+ default: ceph_abort_msg("unknown op type"); return NULL;
+ }
+ }
+
+ op_type_t op = OP_SCRUB;
+ version_t version = 0;
+ ScrubResult result;
+ int32_t num_keys;
+ pair<string,string> key;
+
+ MMonScrub()
+ : MessageInstance(MSG_MON_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ num_keys(-1)
+ { }
+
+ MMonScrub(op_type_t op, version_t v, int32_t num_keys)
+ : MessageInstance(MSG_MON_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ op(op), version(v), num_keys(num_keys)
+ { }
+
+ std::string_view get_type_name() const override { return "mon_scrub"; }
+
+ void print(ostream& out) const override {
+ out << "mon_scrub(" << get_opname((op_type_t)op);
+ out << " v " << version;
+ if (op == OP_RESULT)
+ out << " " << result;
+ out << " num_keys " << num_keys;
+ out << " key (" << key << ")";
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ uint8_t o = op;
+ encode(o, payload);
+ encode(version, payload);
+ encode(result, payload);
+ encode(num_keys, payload);
+ encode(key, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ uint8_t o;
+ decode(o, p);
+ op = (op_type_t)o;
+ decode(version, p);
+ decode(result, p);
+ decode(num_keys, p);
+ decode(key, p);
+ }
+};
+
+#endif /* CEPH_MMONSCRUB_H */
diff --git a/src/messages/MMonSubscribe.h b/src/messages/MMonSubscribe.h
new file mode 100644
index 00000000..bbc88334
--- /dev/null
+++ b/src/messages/MMonSubscribe.h
@@ -0,0 +1,105 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONSUBSCRIBE_H
+#define CEPH_MMONSUBSCRIBE_H
+
+#include "msg/Message.h"
+#include "include/ceph_features.h"
+
+/*
+ * compatibility with old crap
+ */
+struct ceph_mon_subscribe_item_old {
+ ceph_le64 unused;
+ ceph_le64 have;
+ __u8 onetime;
+} __attribute__ ((packed));
+WRITE_RAW_ENCODER(ceph_mon_subscribe_item_old)
+
+
+class MMonSubscribe : public MessageInstance<MMonSubscribe> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+ string hostname;
+ map<string, ceph_mon_subscribe_item> what;
+
+ MMonSubscribe() : MessageInstance(CEPH_MSG_MON_SUBSCRIBE, HEAD_VERSION, COMPAT_VERSION) { }
+private:
+ ~MMonSubscribe() override {}
+
+public:
+ void sub_want(const char *w, version_t start, unsigned flags) {
+ what[w].start = start;
+ what[w].flags = flags;
+ }
+
+ std::string_view get_type_name() const override { return "mon_subscribe"; }
+ void print(ostream& o) const override {
+ o << "mon_subscribe(" << what << ")";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ if (header.version < 2) {
+ map<string, ceph_mon_subscribe_item_old> oldwhat;
+ decode(oldwhat, p);
+ what.clear();
+ for (map<string, ceph_mon_subscribe_item_old>::iterator q = oldwhat.begin();
+ q != oldwhat.end();
+ q++) {
+ if (q->second.have)
+ what[q->first].start = q->second.have + 1;
+ else
+ what[q->first].start = 0;
+ what[q->first].flags = 0;
+ if (q->second.onetime)
+ what[q->first].flags |= CEPH_SUBSCRIBE_ONETIME;
+ }
+ return;
+ }
+ decode(what, p);
+ if (header.version >= 3) {
+ decode(hostname, p);
+ }
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if ((features & CEPH_FEATURE_SUBSCRIBE2) == 0) {
+ header.version = 0;
+ map<string, ceph_mon_subscribe_item_old> oldwhat;
+ for (map<string, ceph_mon_subscribe_item>::iterator q = what.begin();
+ q != what.end();
+ q++) {
+ if (q->second.start)
+ // warning: start=1 -> have=0, which was ambiguous
+ oldwhat[q->first].have = q->second.start - 1;
+ else
+ oldwhat[q->first].have = 0;
+ oldwhat[q->first].onetime = q->second.flags & CEPH_SUBSCRIBE_ONETIME;
+ }
+ encode(oldwhat, payload);
+ return;
+ }
+ header.version = HEAD_VERSION;
+ encode(what, payload);
+ encode(hostname, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonSubscribeAck.h b/src/messages/MMonSubscribeAck.h
new file mode 100644
index 00000000..087e5069
--- /dev/null
+++ b/src/messages/MMonSubscribeAck.h
@@ -0,0 +1,53 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MMONSUBSCRIBEACK_H
+#define CEPH_MMONSUBSCRIBEACK_H
+
+#include "msg/Message.h"
+
+class MMonSubscribeAck : public MessageInstance<MMonSubscribeAck> {
+public:
+ friend factory;
+
+ __u32 interval;
+ uuid_d fsid;
+
+ MMonSubscribeAck() : MessageInstance(CEPH_MSG_MON_SUBSCRIBE_ACK),
+ interval(0) {
+ }
+ MMonSubscribeAck(uuid_d& f, int i) : MessageInstance(CEPH_MSG_MON_SUBSCRIBE_ACK),
+ interval(i), fsid(f) { }
+private:
+ ~MMonSubscribeAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_subscribe_ack"; }
+ void print(ostream& o) const override {
+ o << "mon_subscribe_ack(" << interval << "s)";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(interval, p);
+ decode(fsid, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(interval, payload);
+ encode(fsid, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MMonSync.h b/src/messages/MMonSync.h
new file mode 100644
index 00000000..a4f82207
--- /dev/null
+++ b/src/messages/MMonSync.h
@@ -0,0 +1,114 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+* Ceph - scalable distributed file system
+*
+* Copyright (C) 2012 Inktank, Inc.
+*
+* This is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License version 2.1, as published by the Free Software
+* Foundation. See file COPYING.
+*/
+#ifndef CEPH_MMONSYNC_H
+#define CEPH_MMONSYNC_H
+
+#include "msg/Message.h"
+
+class MMonSync : public MessageInstance<MMonSync> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ /**
+ * Operation types
+ */
+ enum {
+ OP_GET_COOKIE_FULL = 1, // -> start a session (full scan)
+ OP_GET_COOKIE_RECENT = 2, // -> start a session (only recent paxos events)
+ OP_COOKIE = 3, // <- pass the iterator cookie, or
+ OP_GET_CHUNK = 4, // -> get some keys
+ OP_CHUNK = 5, // <- return some keys
+ OP_LAST_CHUNK = 6, // <- return the last set of keys
+ OP_NO_COOKIE = 8, // <- sorry, no cookie
+ };
+
+ /**
+ * Obtain a string corresponding to the operation type @p op
+ *
+ * @param op Operation type
+ * @returns A string
+ */
+ static const char *get_opname(int op) {
+ switch (op) {
+ case OP_GET_COOKIE_FULL: return "get_cookie_full";
+ case OP_GET_COOKIE_RECENT: return "get_cookie_recent";
+ case OP_COOKIE: return "cookie";
+ case OP_GET_CHUNK: return "get_chunk";
+ case OP_CHUNK: return "chunk";
+ case OP_LAST_CHUNK: return "last_chunk";
+ case OP_NO_COOKIE: return "no_cookie";
+ default: ceph_abort_msg("unknown op type"); return NULL;
+ }
+ }
+
+ uint32_t op = 0;
+ uint64_t cookie = 0;
+ version_t last_committed = 0;
+ pair<string,string> last_key;
+ bufferlist chunk_bl;
+ entity_inst_t reply_to;
+
+ MMonSync()
+ : MessageInstance(MSG_MON_SYNC, HEAD_VERSION, COMPAT_VERSION)
+ { }
+
+ MMonSync(uint32_t op, uint64_t c = 0)
+ : MessageInstance(MSG_MON_SYNC, HEAD_VERSION, COMPAT_VERSION),
+ op(op),
+ cookie(c),
+ last_committed(0)
+ { }
+
+ std::string_view get_type_name() const override { return "mon_sync"; }
+
+ void print(ostream& out) const override {
+ out << "mon_sync(" << get_opname(op);
+ if (cookie)
+ out << " cookie " << cookie;
+ if (last_committed > 0)
+ out << " lc " << last_committed;
+ if (chunk_bl.length())
+ out << " bl " << chunk_bl.length() << " bytes";
+ if (!last_key.first.empty() || !last_key.second.empty())
+ out << " last_key " << last_key.first << "," << last_key.second;
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(cookie, payload);
+ encode(last_committed, payload);
+ encode(last_key.first, payload);
+ encode(last_key.second, payload);
+ encode(chunk_bl, payload);
+ encode(reply_to, payload, features);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(cookie, p);
+ decode(last_committed, p);
+ decode(last_key.first, p);
+ decode(last_key.second, p);
+ decode(chunk_bl, p);
+ decode(reply_to, p);
+ }
+};
+
+#endif /* CEPH_MMONSYNC_H */
diff --git a/src/messages/MNop.h b/src/messages/MNop.h
new file mode 100644
index 00000000..452f509c
--- /dev/null
+++ b/src/messages/MNop.h
@@ -0,0 +1,57 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ * Portions Copyright (C) 2014 CohortFS, LLC
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MSG_NOP_H
+#define CEPH_MSG_NOP_H
+
+#include "msg/Message.h"
+#include "msg/msg_types.h"
+
+/*
+ * A message with no (remote) effect.
+ */
+class MNop : public MessageInstance<MNop> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ __u32 tag; // ignored tag value
+
+ MNop()
+ : MessageInstance(MSG_NOP, HEAD_VERSION, COMPAT_VERSION)
+ {}
+
+ ~MNop() {}
+
+ void encode_payload(uint64_t _features) {
+ using ceph::encode;
+ encode(tag, payload);
+ }
+
+ void decode_payload() {
+ auto p = payload.cbegin();
+ decode(tag, p);
+ }
+
+ std::string_view get_type_name() const { return "MNop"; }
+
+ void print(ostream& out) const {
+ out << get_type_name() << " ";
+ }
+}; /* MNop */
+
+#endif /* CEPH_MSG_NOP_H */
diff --git a/src/messages/MOSDAlive.h b/src/messages/MOSDAlive.h
new file mode 100644
index 00000000..47ed5f2a
--- /dev/null
+++ b/src/messages/MOSDAlive.h
@@ -0,0 +1,52 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+
+#ifndef CEPH_MOSDALIVE_H
+#define CEPH_MOSDALIVE_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDAlive : public MessageInstance<MOSDAlive, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ epoch_t want = 0;
+
+ MOSDAlive(epoch_t h, epoch_t w) : MessageInstance(MSG_OSD_ALIVE, h), want(w) { }
+ MOSDAlive() : MessageInstance(MSG_OSD_ALIVE, 0) {}
+private:
+ ~MOSDAlive() override {}
+
+public:
+ void encode_payload(uint64_t features) override {
+ paxos_encode();
+ using ceph::encode;
+ encode(want, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(want, p);
+ }
+
+ std::string_view get_type_name() const override { return "osd_alive"; }
+ void print(ostream &out) const override {
+ out << "osd_alive(want up_thru " << want << " have " << version << ")";
+ }
+
+};
+
+#endif
diff --git a/src/messages/MOSDBackoff.h b/src/messages/MOSDBackoff.h
new file mode 100644
index 00000000..97285420
--- /dev/null
+++ b/src/messages/MOSDBackoff.h
@@ -0,0 +1,84 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2017 Red Hat
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDBACKOFF_H
+#define CEPH_MOSDBACKOFF_H
+
+#include "MOSDFastDispatchOp.h"
+#include "osd/osd_types.h"
+
+class MOSDBackoff : public MessageInstance<MOSDBackoff, MOSDFastDispatchOp> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ spg_t pgid;
+ epoch_t map_epoch = 0;
+ uint8_t op = 0; ///< CEPH_OSD_BACKOFF_OP_*
+ uint64_t id = 0; ///< unique id within this session
+ hobject_t begin, end; ///< [) range to block, unless ==, block single obj
+
+ spg_t get_spg() const override {
+ return pgid;
+ }
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+
+ MOSDBackoff()
+ : MessageInstance(CEPH_MSG_OSD_BACKOFF, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDBackoff(spg_t pgid_, epoch_t ep, uint8_t op_, uint64_t id_,
+ hobject_t begin_, hobject_t end_)
+ : MessageInstance(CEPH_MSG_OSD_BACKOFF, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid_),
+ map_epoch(ep),
+ op(op_),
+ id(id_),
+ begin(begin_),
+ end(end_) { }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(op, payload);
+ encode(id, payload);
+ encode(begin, payload);
+ encode(end, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ decode(id, p);
+ decode(begin, p);
+ decode(end, p);
+ }
+
+ std::string_view get_type_name() const override { return "osd_backoff"; }
+
+ void print(ostream& out) const override {
+ out << "osd_backoff(" << pgid << " " << ceph_osd_backoff_op_name(op)
+ << " id " << id
+ << " [" << begin << "," << end << ")"
+ << " e" << map_epoch << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDBeacon.h b/src/messages/MOSDBeacon.h
new file mode 100644
index 00000000..76140119
--- /dev/null
+++ b/src/messages/MOSDBeacon.h
@@ -0,0 +1,41 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "PaxosServiceMessage.h"
+
+class MOSDBeacon : public MessageInstance<MOSDBeacon, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ std::vector<pg_t> pgs;
+ epoch_t min_last_epoch_clean = 0;
+
+ MOSDBeacon()
+ : MessageInstance(MSG_OSD_BEACON, 0)
+ {}
+ MOSDBeacon(epoch_t e, epoch_t min_lec)
+ : MessageInstance(MSG_OSD_BEACON, e),
+ min_last_epoch_clean(min_lec)
+ {}
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(pgs, payload);
+ encode(min_last_epoch_clean, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(pgs, p);
+ decode(min_last_epoch_clean, p);
+ }
+ std::string_view get_type_name() const override { return "osd_beacon"; }
+ void print(ostream &out) const {
+ out << get_type_name()
+ << "(pgs " << pgs
+ << " lec " << min_last_epoch_clean
+ << " v" << version << ")";
+ }
+};
diff --git a/src/messages/MOSDBoot.h b/src/messages/MOSDBoot.h
new file mode 100644
index 00000000..ccd49991
--- /dev/null
+++ b/src/messages/MOSDBoot.h
@@ -0,0 +1,120 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDBOOT_H
+#define CEPH_MOSDBOOT_H
+
+#include "messages/PaxosServiceMessage.h"
+
+#include "include/ceph_features.h"
+#include "include/types.h"
+#include "osd/osd_types.h"
+
+class MOSDBoot : public MessageInstance<MOSDBoot, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 7;
+ static constexpr int COMPAT_VERSION = 7;
+
+ public:
+ OSDSuperblock sb;
+ entity_addrvec_t hb_back_addrs, hb_front_addrs;
+ entity_addrvec_t cluster_addrs;
+ epoch_t boot_epoch; // last epoch this daemon was added to the map (if any)
+ map<string,string> metadata; ///< misc metadata about this osd
+ uint64_t osd_features;
+
+ MOSDBoot()
+ : MessageInstance(MSG_OSD_BOOT, 0, HEAD_VERSION, COMPAT_VERSION),
+ boot_epoch(0), osd_features(0)
+ { }
+ MOSDBoot(OSDSuperblock& s, epoch_t e, epoch_t be,
+ const entity_addrvec_t& hb_back_addr_ref,
+ const entity_addrvec_t& hb_front_addr_ref,
+ const entity_addrvec_t& cluster_addr_ref,
+ uint64_t feat)
+ : MessageInstance(MSG_OSD_BOOT, e, HEAD_VERSION, COMPAT_VERSION),
+ sb(s),
+ hb_back_addrs(hb_back_addr_ref),
+ hb_front_addrs(hb_front_addr_ref),
+ cluster_addrs(cluster_addr_ref),
+ boot_epoch(be),
+ osd_features(feat)
+ { }
+
+private:
+ ~MOSDBoot() override { }
+
+public:
+ std::string_view get_type_name() const override { return "osd_boot"; }
+ void print(ostream& out) const override {
+ out << "osd_boot(osd." << sb.whoami << " booted " << boot_epoch
+ << " features " << osd_features
+ << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ using ceph::encode;
+ paxos_encode();
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ header.version = 6;
+ header.compat_version = 6;
+ encode(sb, payload);
+ hb_back_addrs.legacy_addr().encode(payload, features);
+ cluster_addrs.legacy_addr().encode(payload, features);
+ encode(boot_epoch, payload);
+ hb_front_addrs.legacy_addr().encode(payload, features);
+ encode(metadata, payload);
+ encode(osd_features, payload);
+ return;
+ }
+ encode(sb, payload);
+ encode(hb_back_addrs, payload, features);
+ encode(cluster_addrs, payload, features);
+ encode(boot_epoch, payload);
+ encode(hb_front_addrs, payload, features);
+ encode(metadata, payload);
+ encode(osd_features, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ if (header.version < 7) {
+ entity_addr_t a;
+ decode(sb, p);
+ decode(a, p);
+ hb_back_addrs = entity_addrvec_t(a);
+ decode(a, p);
+ cluster_addrs = entity_addrvec_t(a);
+ decode(boot_epoch, p);
+ decode(a, p);
+ hb_front_addrs = entity_addrvec_t(a);
+ decode(metadata, p);
+ decode(osd_features, p);
+ return;
+ }
+ decode(sb, p);
+ decode(hb_back_addrs, p);
+ decode(cluster_addrs, p);
+ decode(boot_epoch, p);
+ decode(hb_front_addrs, p);
+ decode(metadata, p);
+ decode(osd_features, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpRead.h b/src/messages/MOSDECSubOpRead.h
new file mode 100644
index 00000000..c006a85c
--- /dev/null
+++ b/src/messages/MOSDECSubOpRead.h
@@ -0,0 +1,82 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDECSUBOPREAD_H
+#define MOSDECSUBOPREAD_H
+
+#include "MOSDFastDispatchOp.h"
+#include "osd/ECMsgTypes.h"
+
+class MOSDECSubOpRead : public MessageInstance<MOSDECSubOpRead, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ ECSubRead op;
+
+ int get_cost() const override {
+ return 0;
+ }
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDECSubOpRead()
+ : MessageInstance(MSG_OSD_EC_READ, HEAD_VERSION, COMPAT_VERSION)
+ {}
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ if (header.version >= 3) {
+ decode(min_epoch, p);
+ decode_trace(p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(op, payload, features);
+ encode(min_epoch, payload);
+ encode_trace(payload, features);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDECSubOpRead"; }
+
+ void print(ostream& out) const override {
+ out << "MOSDECSubOpRead(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpReadReply.h b/src/messages/MOSDECSubOpReadReply.h
new file mode 100644
index 00000000..091e5391
--- /dev/null
+++ b/src/messages/MOSDECSubOpReadReply.h
@@ -0,0 +1,82 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDECSUBOPREADREPLY_H
+#define MOSDECSUBOPREADREPLY_H
+
+#include "MOSDFastDispatchOp.h"
+#include "osd/ECMsgTypes.h"
+
+class MOSDECSubOpReadReply : public MessageInstance<MOSDECSubOpReadReply, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ ECSubReadReply op;
+
+ int get_cost() const override {
+ return 0;
+ }
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDECSubOpReadReply()
+ : MessageInstance(MSG_OSD_EC_READ_REPLY, HEAD_VERSION, COMPAT_VERSION)
+ {}
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ decode_trace(p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(op, payload);
+ encode(min_epoch, payload);
+ encode_trace(payload, features);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDECSubOpReadReply"; }
+
+ void print(ostream& out) const override {
+ out << "MOSDECSubOpReadReply(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpWrite.h b/src/messages/MOSDECSubOpWrite.h
new file mode 100644
index 00000000..5b286cff
--- /dev/null
+++ b/src/messages/MOSDECSubOpWrite.h
@@ -0,0 +1,91 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDECSUBOPWRITE_H
+#define MOSDECSUBOPWRITE_H
+
+#include "MOSDFastDispatchOp.h"
+#include "osd/ECMsgTypes.h"
+
+class MOSDECSubOpWrite : public MessageInstance<MOSDECSubOpWrite, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ ECSubWrite op;
+
+ int get_cost() const override {
+ return 0;
+ }
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDECSubOpWrite()
+ : MessageInstance(MSG_OSD_EC_WRITE, HEAD_VERSION, COMPAT_VERSION)
+ {}
+ MOSDECSubOpWrite(ECSubWrite &in_op)
+ : MessageInstance(MSG_OSD_EC_WRITE, HEAD_VERSION, COMPAT_VERSION) {
+ op.claim(in_op);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ decode_trace(p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(op, payload);
+ encode(min_epoch, payload);
+ encode_trace(payload, features);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDECSubOpWrite"; }
+
+ void print(ostream& out) const override {
+ out << "MOSDECSubOpWrite(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+
+ void clear_buffers() override {
+ op.t = ObjectStore::Transaction();
+ op.log_entries.clear();
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpWriteReply.h b/src/messages/MOSDECSubOpWriteReply.h
new file mode 100644
index 00000000..dfcaf9ae
--- /dev/null
+++ b/src/messages/MOSDECSubOpWriteReply.h
@@ -0,0 +1,82 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDECSUBOPWRITEREPLY_H
+#define MOSDECSUBOPWRITEREPLY_H
+
+#include "MOSDFastDispatchOp.h"
+#include "osd/ECMsgTypes.h"
+
+class MOSDECSubOpWriteReply : public MessageInstance<MOSDECSubOpWriteReply, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ ECSubWriteReply op;
+
+ int get_cost() const override {
+ return 0;
+ }
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDECSubOpWriteReply()
+ : MessageInstance(MSG_OSD_EC_WRITE_REPLY, HEAD_VERSION, COMPAT_VERSION)
+ {}
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ decode_trace(p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(op, payload);
+ encode(min_epoch, payload);
+ encode_trace(payload, features);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDECSubOpWriteReply"; }
+
+ void print(ostream& out) const override {
+ out << "MOSDECSubOpWriteReply(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDFailure.h b/src/messages/MOSDFailure.h
new file mode 100644
index 00000000..27888dd4
--- /dev/null
+++ b/src/messages/MOSDFailure.h
@@ -0,0 +1,128 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDFAILURE_H
+#define CEPH_MOSDFAILURE_H
+
+#include "messages/PaxosServiceMessage.h"
+
+
+class MOSDFailure : public MessageInstance<MOSDFailure, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 4;
+
+ public:
+ enum {
+ FLAG_ALIVE = 0, // use this on its own to mark as "I'm still alive"
+ FLAG_FAILED = 1, // if set, failure; if not, recovery
+ FLAG_IMMEDIATE = 2, // known failure, not a timeout
+ };
+
+ uuid_d fsid;
+ int32_t target_osd;
+ entity_addrvec_t target_addrs;
+ __u8 flags = 0;
+ epoch_t epoch = 0;
+ int32_t failed_for = 0; // known to be failed since at least this long
+
+ MOSDFailure() : MessageInstance(MSG_OSD_FAILURE, 0, HEAD_VERSION) { }
+ MOSDFailure(const uuid_d &fs, int osd, const entity_addrvec_t& av,
+ int duration, epoch_t e)
+ : MessageInstance(MSG_OSD_FAILURE, e, HEAD_VERSION, COMPAT_VERSION),
+ fsid(fs),
+ target_osd(osd),
+ target_addrs(av),
+ flags(FLAG_FAILED),
+ epoch(e), failed_for(duration) { }
+ MOSDFailure(const uuid_d &fs, int osd, const entity_addrvec_t& av,
+ int duration,
+ epoch_t e, __u8 extra_flags)
+ : MessageInstance(MSG_OSD_FAILURE, e, HEAD_VERSION, COMPAT_VERSION),
+ fsid(fs),
+ target_osd(osd),
+ target_addrs(av),
+ flags(extra_flags),
+ epoch(e), failed_for(duration) { }
+private:
+ ~MOSDFailure() override {}
+
+public:
+ int get_target_osd() { return target_osd; }
+ const entity_addrvec_t& get_target_addrs() { return target_addrs; }
+ bool if_osd_failed() const {
+ return flags & FLAG_FAILED;
+ }
+ bool is_immediate() const {
+ return flags & FLAG_IMMEDIATE;
+ }
+ epoch_t get_epoch() const { return epoch; }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ if (header.version < 4) {
+ entity_inst_t i;
+ decode(i, p);
+ target_osd = i.name.num();
+ target_addrs.v.push_back(i.addr);
+ } else {
+ decode(target_osd, p);
+ decode(target_addrs, p);
+ }
+ decode(epoch, p);
+ decode(flags, p);
+ decode(failed_for, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ header.version = 3;
+ header.compat_version = 3;
+ encode(fsid, payload);
+ encode(entity_inst_t(entity_name_t::OSD(target_osd),
+ target_addrs.legacy_addr()), payload, features);
+ encode(epoch, payload);
+ encode(flags, payload);
+ encode(failed_for, payload);
+ return;
+ }
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(fsid, payload);
+ encode(target_osd, payload, features);
+ encode(target_addrs, payload, features);
+ encode(epoch, payload);
+ encode(flags, payload);
+ encode(failed_for, payload);
+ }
+
+ std::string_view get_type_name() const override { return "osd_failure"; }
+ void print(ostream& out) const override {
+ out << "osd_failure("
+ << (if_osd_failed() ? "failed " : "recovered ")
+ << (is_immediate() ? "immediate " : "timeout ")
+ << "osd." << target_osd << " " << target_addrs
+ << " for " << failed_for << "sec e" << epoch
+ << " v" << version << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDFastDispatchOp.h b/src/messages/MOSDFastDispatchOp.h
new file mode 100644
index 00000000..1f5f7abe
--- /dev/null
+++ b/src/messages/MOSDFastDispatchOp.h
@@ -0,0 +1,23 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MOSDFASTDISPATCHOP_H
+#define CEPH_MOSDFASTDISPATCHOP_H
+
+#include "msg/Message.h"
+#include "osd/osd_types.h"
+
+class MOSDFastDispatchOp : public MessageSubType<MOSDFastDispatchOp> {
+public:
+
+template<typename... Args>
+ MOSDFastDispatchOp(Args&&... args) : MessageSubType(std::forward<Args>(args)...) {}
+
+ virtual epoch_t get_map_epoch() const = 0;
+ virtual epoch_t get_min_epoch() const {
+ return get_map_epoch();
+ }
+ virtual spg_t get_spg() const = 0;
+};
+
+#endif
diff --git a/src/messages/MOSDForceRecovery.h b/src/messages/MOSDForceRecovery.h
new file mode 100644
index 00000000..9ee824a1
--- /dev/null
+++ b/src/messages/MOSDForceRecovery.h
@@ -0,0 +1,112 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2017 OVH
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDFORCERECOVERY_H
+#define CEPH_MOSDFORCERECOVERY_H
+
+#include "msg/Message.h"
+
+/*
+ * instruct an OSD to boost/unboost recovery/backfill priority of some or all pg(s)
+ */
+
+// boost priority of recovery
+static const int OFR_RECOVERY = 1;
+
+// boost priority of backfill
+static const int OFR_BACKFILL = 2;
+
+// cancel priority boost, requeue if necessary
+static const int OFR_CANCEL = 4;
+
+class MOSDForceRecovery : public MessageInstance<MOSDForceRecovery> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+ uuid_d fsid;
+ vector<spg_t> forced_pgs;
+ uint8_t options = 0;
+
+ MOSDForceRecovery() : MessageInstance(MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDForceRecovery(const uuid_d& f, char opts) :
+ MessageInstance(MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), options(opts) {}
+ MOSDForceRecovery(const uuid_d& f, vector<spg_t>& pgs, char opts) :
+ MessageInstance(MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), forced_pgs(pgs), options(opts) {}
+private:
+ ~MOSDForceRecovery() {}
+
+public:
+ std::string_view get_type_name() const { return "force_recovery"; }
+ void print(ostream& out) const {
+ out << "force_recovery(";
+ if (forced_pgs.empty())
+ out << "osd";
+ else
+ out << forced_pgs;
+ if (options & OFR_RECOVERY)
+ out << " recovery";
+ if (options & OFR_BACKFILL)
+ out << " backfill";
+ if (options & OFR_CANCEL)
+ out << " cancel";
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) {
+ using ceph::encode;
+ if (!HAVE_FEATURE(features, SERVER_MIMIC)) {
+ header.version = 1;
+ header.compat_version = 1;
+ vector<pg_t> pgs;
+ for (auto pgid : forced_pgs) {
+ pgs.push_back(pgid.pgid);
+ }
+ encode(fsid, payload);
+ encode(pgs, payload);
+ encode(options, payload);
+ return;
+ }
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(fsid, payload);
+ encode(forced_pgs, payload);
+ encode(options, payload);
+ }
+ void decode_payload() {
+ auto p = payload.cbegin();
+ if (header.version == 1) {
+ vector<pg_t> pgs;
+ decode(fsid, p);
+ decode(pgs, p);
+ decode(options, p);
+ for (auto pg : pgs) {
+ // note: this only works with replicated pools. if a pre-mimic mon
+ // tries to force a mimic+ osd on an ec pool it will not work.
+ forced_pgs.push_back(spg_t(pg));
+ }
+ return;
+ }
+ decode(fsid, p);
+ decode(forced_pgs, p);
+ decode(options, p);
+ }
+};
+
+#endif /* CEPH_MOSDFORCERECOVERY_H_ */
diff --git a/src/messages/MOSDFull.h b/src/messages/MOSDFull.h
new file mode 100644
index 00000000..bfe0c24e
--- /dev/null
+++ b/src/messages/MOSDFull.h
@@ -0,0 +1,53 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MOSDFULL_H
+#define CEPH_MOSDFULL_H
+
+#include "messages/PaxosServiceMessage.h"
+#include "osd/OSDMap.h"
+
+// tell the mon to update the full/nearfull bits. note that in the
+// future this message could be generalized to other state bits, but
+// for now name it for its sole application.
+
+class MOSDFull : public MessageInstance<MOSDFull, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ epoch_t map_epoch = 0;
+ uint32_t state = 0;
+
+private:
+ ~MOSDFull() {}
+
+public:
+ MOSDFull(epoch_t e, unsigned s)
+ : MessageInstance(MSG_OSD_FULL, e), map_epoch(e), state(s) { }
+ MOSDFull()
+ : MessageInstance(MSG_OSD_FULL, 0) {}
+
+public:
+ void encode_payload(uint64_t features) {
+ using ceph::encode;
+ paxos_encode();
+ encode(map_epoch, payload);
+ encode(state, payload);
+ }
+ void decode_payload() {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(map_epoch, p);
+ decode(state, p);
+ }
+
+ std::string_view get_type_name() const { return "osd_full"; }
+ void print(ostream &out) const {
+ set<string> states;
+ OSDMap::calc_state_set(state, states);
+ out << "osd_full(e" << map_epoch << " " << states << " v" << version << ")";
+ }
+
+};
+
+#endif
diff --git a/src/messages/MOSDMap.h b/src/messages/MOSDMap.h
new file mode 100644
index 00000000..9a5062c6
--- /dev/null
+++ b/src/messages/MOSDMap.h
@@ -0,0 +1,173 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDMAP_H
+#define CEPH_MOSDMAP_H
+
+#include "msg/Message.h"
+#include "osd/OSDMap.h"
+#include "include/ceph_features.h"
+
+class MOSDMap : public MessageInstance<MOSDMap> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 3;
+
+ public:
+ uuid_d fsid;
+ uint64_t encode_features = 0;
+ map<epoch_t, bufferlist> maps;
+ map<epoch_t, bufferlist> incremental_maps;
+ epoch_t oldest_map =0, newest_map = 0;
+
+ // if we are fetching maps from the mon and have to jump a gap
+ // (client's next needed map is older than mon's oldest) we can
+ // share removed snaps from the gap here.
+ mempool::osdmap::map<int64_t,OSDMap::snap_interval_set_t> gap_removed_snaps;
+
+ epoch_t get_first() const {
+ epoch_t e = 0;
+ map<epoch_t, bufferlist>::const_iterator i = maps.begin();
+ if (i != maps.end()) e = i->first;
+ i = incremental_maps.begin();
+ if (i != incremental_maps.end() &&
+ (e == 0 || i->first < e)) e = i->first;
+ return e;
+ }
+ epoch_t get_last() const {
+ epoch_t e = 0;
+ map<epoch_t, bufferlist>::const_reverse_iterator i = maps.rbegin();
+ if (i != maps.rend()) e = i->first;
+ i = incremental_maps.rbegin();
+ if (i != incremental_maps.rend() &&
+ (e == 0 || i->first > e)) e = i->first;
+ return e;
+ }
+ epoch_t get_oldest() {
+ return oldest_map;
+ }
+ epoch_t get_newest() {
+ return newest_map;
+ }
+
+
+ MOSDMap() : MessageInstance(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION) { }
+ MOSDMap(const uuid_d &f, const uint64_t features)
+ : MessageInstance(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), encode_features(features),
+ oldest_map(0), newest_map(0) { }
+private:
+ ~MOSDMap() override {}
+public:
+ // marshalling
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(incremental_maps, p);
+ decode(maps, p);
+ if (header.version >= 2) {
+ decode(oldest_map, p);
+ decode(newest_map, p);
+ } else {
+ oldest_map = 0;
+ newest_map = 0;
+ }
+ if (header.version >= 4) {
+ decode(gap_removed_snaps, p);
+ }
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(fsid, payload);
+ if (OSDMap::get_significant_features(encode_features) !=
+ OSDMap::get_significant_features(features)) {
+ if ((features & CEPH_FEATURE_PGID64) == 0 ||
+ (features & CEPH_FEATURE_PGPOOL3) == 0) {
+ header.version = 1; // old old_client version
+ header.compat_version = 1;
+ } else if ((features & CEPH_FEATURE_OSDENC) == 0) {
+ header.version = 2; // old pg_pool_t
+ header.compat_version = 2;
+ }
+
+ // reencode maps using old format
+ //
+ // FIXME: this can probably be done more efficiently higher up
+ // the stack, or maybe replaced with something that only
+ // includes the pools the client cares about.
+ for (map<epoch_t,bufferlist>::iterator p = incremental_maps.begin();
+ p != incremental_maps.end();
+ ++p) {
+ OSDMap::Incremental inc;
+ auto q = p->second.cbegin();
+ inc.decode(q);
+ // always encode with subset of osdmaps canonical features
+ uint64_t f = inc.encode_features & features;
+ p->second.clear();
+ if (inc.fullmap.length()) {
+ // embedded full map?
+ OSDMap m;
+ m.decode(inc.fullmap);
+ inc.fullmap.clear();
+ m.encode(inc.fullmap, f | CEPH_FEATURE_RESERVED);
+ }
+ if (inc.crush.length()) {
+ // embedded crush map
+ CrushWrapper c;
+ auto p = inc.crush.cbegin();
+ c.decode(p);
+ inc.crush.clear();
+ c.encode(inc.crush, f);
+ }
+ inc.encode(p->second, f | CEPH_FEATURE_RESERVED);
+ }
+ for (map<epoch_t,bufferlist>::iterator p = maps.begin();
+ p != maps.end();
+ ++p) {
+ OSDMap m;
+ m.decode(p->second);
+ // always encode with subset of osdmaps canonical features
+ uint64_t f = m.get_encoding_features() & features;
+ p->second.clear();
+ m.encode(p->second, f | CEPH_FEATURE_RESERVED);
+ }
+ }
+ encode(incremental_maps, payload);
+ encode(maps, payload);
+ if (header.version >= 2) {
+ encode(oldest_map, payload);
+ encode(newest_map, payload);
+ }
+ if (header.version >= 4) {
+ encode(gap_removed_snaps, payload);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "osdmap"; }
+ void print(ostream& out) const override {
+ out << "osd_map(" << get_first() << ".." << get_last();
+ if (oldest_map || newest_map)
+ out << " src has " << oldest_map << ".." << newest_map;
+ if (!gap_removed_snaps.empty())
+ out << " +gap_removed_snaps";
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDMarkMeDown.h b/src/messages/MOSDMarkMeDown.h
new file mode 100644
index 00000000..89c3d75c
--- /dev/null
+++ b/src/messages/MOSDMarkMeDown.h
@@ -0,0 +1,103 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDMARKMEDOWN_H
+#define CEPH_MOSDMARKMEDOWN_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDMarkMeDown : public MessageInstance<MOSDMarkMeDown, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+
+ public:
+ uuid_d fsid;
+ int32_t target_osd;
+ entity_addrvec_t target_addrs;
+ epoch_t epoch = 0;
+ bool request_ack = false; // ack requested
+
+ MOSDMarkMeDown()
+ : MessageInstance(MSG_OSD_MARK_ME_DOWN, 0,
+ HEAD_VERSION, COMPAT_VERSION) { }
+ MOSDMarkMeDown(const uuid_d &fs, int osd, const entity_addrvec_t& av,
+ epoch_t e, bool request_ack)
+ : MessageInstance(MSG_OSD_MARK_ME_DOWN, e,
+ HEAD_VERSION, COMPAT_VERSION),
+ fsid(fs), target_osd(osd), target_addrs(av),
+ epoch(e), request_ack(request_ack) {}
+ private:
+ ~MOSDMarkMeDown() override {}
+
+public:
+ epoch_t get_epoch() const { return epoch; }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ if (header.version <= 2) {
+ decode(fsid, p);
+ entity_inst_t i;
+ decode(i, p);
+ target_osd = i.name.num();
+ target_addrs = entity_addrvec_t(i.addr);
+ decode(epoch, p);
+ decode(request_ack, p);
+ return;
+ }
+ decode(fsid, p);
+ decode(target_osd, p);
+ decode(target_addrs, p);
+ decode(epoch, p);
+ decode(request_ack, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ header.version = 2;
+ header.compat_version = 2;
+ encode(fsid, payload);
+ encode(entity_inst_t(entity_name_t::OSD(target_osd),
+ target_addrs.legacy_addr()),
+ payload, features);
+ encode(epoch, payload);
+ encode(request_ack, payload);
+ return;
+ }
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(fsid, payload);
+ encode(target_osd, payload, features);
+ encode(target_addrs, payload, features);
+ encode(epoch, payload);
+ encode(request_ack, payload);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDMarkMeDown"; }
+ void print(ostream& out) const override {
+ out << "MOSDMarkMeDown("
+ << "request_ack=" << request_ack
+ << ", osd." << target_osd
+ << ", " << target_addrs
+ << ", fsid=" << fsid
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDOp.h b/src/messages/MOSDOp.h
new file mode 100644
index 00000000..c751b53d
--- /dev/null
+++ b/src/messages/MOSDOp.h
@@ -0,0 +1,598 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDOP_H
+#define CEPH_MOSDOP_H
+
+#include "MOSDFastDispatchOp.h"
+#include "include/ceph_features.h"
+#include "common/hobject.h"
+#include <atomic>
+
+/*
+ * OSD op
+ *
+ * oid - object id
+ * op - OSD_OP_DELETE, etc.
+ *
+ */
+
+class OSD;
+
+class MOSDOp : public MessageInstance<MOSDOp, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 3;
+
+private:
+ uint32_t client_inc = 0;
+ __u32 osdmap_epoch = 0;
+ __u32 flags = 0;
+ utime_t mtime;
+ int32_t retry_attempt = -1; // 0 is first attempt. -1 if we don't know.
+
+ hobject_t hobj;
+ spg_t pgid;
+ bufferlist::const_iterator p;
+ // Decoding flags. Decoding is only needed for messages caught by pipe reader.
+ // Transition from true -> false without locks being held
+ // Can never see final_decode_needed == false and partial_decode_needed == true
+ atomic<bool> partial_decode_needed;
+ atomic<bool> final_decode_needed;
+ //
+public:
+ vector<OSDOp> ops;
+private:
+ snapid_t snap_seq;
+ vector<snapid_t> snaps;
+
+ uint64_t features;
+ bool bdata_encode;
+ osd_reqid_t reqid; // reqid explicitly set by sender
+
+public:
+ friend class MOSDOpReply;
+
+ ceph_tid_t get_client_tid() { return header.tid; }
+ void set_snapid(const snapid_t& s) {
+ hobj.snap = s;
+ }
+ void set_snaps(const vector<snapid_t>& i) {
+ snaps = i;
+ }
+ void set_snap_seq(const snapid_t& s) { snap_seq = s; }
+ void set_reqid(const osd_reqid_t rid) {
+ reqid = rid;
+ }
+ void set_spg(spg_t p) {
+ pgid = p;
+ }
+
+ // Fields decoded in partial decoding
+ pg_t get_pg() const {
+ ceph_assert(!partial_decode_needed);
+ return pgid.pgid;
+ }
+ spg_t get_spg() const override {
+ ceph_assert(!partial_decode_needed);
+ return pgid;
+ }
+ pg_t get_raw_pg() const {
+ ceph_assert(!partial_decode_needed);
+ return pg_t(hobj.get_hash(), pgid.pgid.pool());
+ }
+ epoch_t get_map_epoch() const override {
+ ceph_assert(!partial_decode_needed);
+ return osdmap_epoch;
+ }
+ int get_flags() const {
+ ceph_assert(!partial_decode_needed);
+ return flags;
+ }
+ osd_reqid_t get_reqid() const {
+ ceph_assert(!partial_decode_needed);
+ if (reqid.name != entity_name_t() || reqid.tid != 0) {
+ return reqid;
+ } else {
+ if (!final_decode_needed)
+ ceph_assert(reqid.inc == (int32_t)client_inc); // decode() should have done this
+ return osd_reqid_t(get_orig_source(),
+ reqid.inc,
+ header.tid);
+ }
+ }
+
+ // Fields decoded in final decoding
+ int get_client_inc() const {
+ ceph_assert(!final_decode_needed);
+ return client_inc;
+ }
+ utime_t get_mtime() const {
+ ceph_assert(!final_decode_needed);
+ return mtime;
+ }
+ object_locator_t get_object_locator() const {
+ ceph_assert(!final_decode_needed);
+ if (hobj.oid.name.empty())
+ return object_locator_t(hobj.pool, hobj.nspace, hobj.get_hash());
+ else
+ return object_locator_t(hobj);
+ }
+ const object_t& get_oid() const {
+ ceph_assert(!final_decode_needed);
+ return hobj.oid;
+ }
+ const hobject_t &get_hobj() const {
+ return hobj;
+ }
+ snapid_t get_snapid() const {
+ ceph_assert(!final_decode_needed);
+ return hobj.snap;
+ }
+ const snapid_t& get_snap_seq() const {
+ ceph_assert(!final_decode_needed);
+ return snap_seq;
+ }
+ const vector<snapid_t> &get_snaps() const {
+ ceph_assert(!final_decode_needed);
+ return snaps;
+ }
+
+ /**
+ * get retry attempt
+ *
+ * 0 is the first attempt.
+ *
+ * @return retry attempt, or -1 if we don't know
+ */
+ int get_retry_attempt() const {
+ return retry_attempt;
+ }
+ uint64_t get_features() const {
+ if (features)
+ return features;
+ return get_connection()->get_features();
+ }
+
+ MOSDOp()
+ : MessageInstance(CEPH_MSG_OSD_OP, HEAD_VERSION, COMPAT_VERSION),
+ partial_decode_needed(true),
+ final_decode_needed(true),
+ bdata_encode(false) { }
+ MOSDOp(int inc, long tid, const hobject_t& ho, spg_t& _pgid,
+ epoch_t _osdmap_epoch,
+ int _flags, uint64_t feat)
+ : MessageInstance(CEPH_MSG_OSD_OP, HEAD_VERSION, COMPAT_VERSION),
+ client_inc(inc),
+ osdmap_epoch(_osdmap_epoch), flags(_flags), retry_attempt(-1),
+ hobj(ho),
+ pgid(_pgid),
+ partial_decode_needed(false),
+ final_decode_needed(false),
+ features(feat),
+ bdata_encode(false) {
+ set_tid(tid);
+
+ // also put the client_inc in reqid.inc, so that get_reqid() can
+ // be used before the full message is decoded.
+ reqid.inc = inc;
+ }
+private:
+ ~MOSDOp() override {}
+
+public:
+ void set_mtime(utime_t mt) { mtime = mt; }
+ void set_mtime(ceph::real_time mt) {
+ mtime = ceph::real_clock::to_timespec(mt);
+ }
+
+ // ops
+ void add_simple_op(int o, uint64_t off, uint64_t len) {
+ OSDOp osd_op;
+ osd_op.op.op = o;
+ osd_op.op.extent.offset = off;
+ osd_op.op.extent.length = len;
+ ops.push_back(osd_op);
+ }
+ void write(uint64_t off, uint64_t len, bufferlist& bl) {
+ add_simple_op(CEPH_OSD_OP_WRITE, off, len);
+ data.claim(bl);
+ header.data_off = off;
+ }
+ void writefull(bufferlist& bl) {
+ add_simple_op(CEPH_OSD_OP_WRITEFULL, 0, bl.length());
+ data.claim(bl);
+ header.data_off = 0;
+ }
+ void zero(uint64_t off, uint64_t len) {
+ add_simple_op(CEPH_OSD_OP_ZERO, off, len);
+ }
+ void truncate(uint64_t off) {
+ add_simple_op(CEPH_OSD_OP_TRUNCATE, off, 0);
+ }
+ void remove() {
+ add_simple_op(CEPH_OSD_OP_DELETE, 0, 0);
+ }
+
+ void read(uint64_t off, uint64_t len) {
+ add_simple_op(CEPH_OSD_OP_READ, off, len);
+ }
+ void stat() {
+ add_simple_op(CEPH_OSD_OP_STAT, 0, 0);
+ }
+
+ bool has_flag(__u32 flag) const { return flags & flag; };
+
+ bool is_retry_attempt() const { return flags & CEPH_OSD_FLAG_RETRY; }
+ void set_retry_attempt(unsigned a) {
+ if (a)
+ flags |= CEPH_OSD_FLAG_RETRY;
+ else
+ flags &= ~CEPH_OSD_FLAG_RETRY;
+ retry_attempt = a;
+ }
+
+ // marshalling
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if( false == bdata_encode ) {
+ OSDOp::merge_osd_op_vector_in_data(ops, data);
+ bdata_encode = true;
+ }
+
+ if ((features & CEPH_FEATURE_OBJECTLOCATOR) == 0) {
+ // here is the old structure we are encoding to: //
+#if 0
+struct ceph_osd_request_head {
+ __le32 client_inc; /* client incarnation */
+ struct ceph_object_layout layout; /* pgid */
+ __le32 osdmap_epoch; /* client's osdmap epoch */
+
+ __le32 flags;
+
+ struct ceph_timespec mtime; /* for mutations only */
+ struct ceph_eversion reassert_version; /* if we are replaying op */
+
+ __le32 object_len; /* length of object name */
+
+ __le64 snapid; /* snapid to read */
+ __le64 snap_seq; /* writer's snap context */
+ __le32 num_snaps;
+
+ __le16 num_ops;
+ struct ceph_osd_op ops[]; /* followed by ops[], obj, ticket, snaps */
+} __attribute__ ((packed));
+#endif
+ header.version = 1;
+
+ encode(client_inc, payload);
+
+ __u32 su = 0;
+ encode(get_raw_pg(), payload);
+ encode(su, payload);
+
+ encode(osdmap_epoch, payload);
+ encode(flags, payload);
+ encode(mtime, payload);
+ encode(eversion_t(), payload); // reassert_version
+
+ __u32 oid_len = hobj.oid.name.length();
+ encode(oid_len, payload);
+ encode(hobj.snap, payload);
+ encode(snap_seq, payload);
+ __u32 num_snaps = snaps.size();
+ encode(num_snaps, payload);
+
+ //::encode(ops, payload);
+ __u16 num_ops = ops.size();
+ encode(num_ops, payload);
+ for (unsigned i = 0; i < ops.size(); i++)
+ encode(ops[i].op, payload);
+
+ encode_nohead(hobj.oid.name, payload);
+ encode_nohead(snaps, payload);
+ } else if ((features & CEPH_FEATURE_NEW_OSDOP_ENCODING) == 0) {
+ header.version = 6;
+ encode(client_inc, payload);
+ encode(osdmap_epoch, payload);
+ encode(flags, payload);
+ encode(mtime, payload);
+ encode(eversion_t(), payload); // reassert_version
+ encode(get_object_locator(), payload);
+ encode(get_raw_pg(), payload);
+
+ encode(hobj.oid, payload);
+
+ __u16 num_ops = ops.size();
+ encode(num_ops, payload);
+ for (unsigned i = 0; i < ops.size(); i++)
+ encode(ops[i].op, payload);
+
+ encode(hobj.snap, payload);
+ encode(snap_seq, payload);
+ encode(snaps, payload);
+
+ encode(retry_attempt, payload);
+ encode(features, payload);
+ if (reqid.name != entity_name_t() || reqid.tid != 0) {
+ encode(reqid, payload);
+ } else {
+ // don't include client_inc in the reqid for the legacy v6
+ // encoding or else we'll confuse older peers.
+ encode(osd_reqid_t(), payload);
+ }
+ } else if (!HAVE_FEATURE(features, RESEND_ON_SPLIT)) {
+ // reordered, v7 message encoding
+ header.version = 7;
+ encode(get_raw_pg(), payload);
+ encode(osdmap_epoch, payload);
+ encode(flags, payload);
+ encode(eversion_t(), payload); // reassert_version
+ encode(reqid, payload);
+ encode(client_inc, payload);
+ encode(mtime, payload);
+ encode(get_object_locator(), payload);
+ encode(hobj.oid, payload);
+
+ __u16 num_ops = ops.size();
+ encode(num_ops, payload);
+ for (unsigned i = 0; i < ops.size(); i++)
+ encode(ops[i].op, payload);
+
+ encode(hobj.snap, payload);
+ encode(snap_seq, payload);
+ encode(snaps, payload);
+
+ encode(retry_attempt, payload);
+ encode(features, payload);
+ } else {
+ // latest v8 encoding with hobject_t hash separate from pgid, no
+ // reassert version
+ header.version = HEAD_VERSION;
+
+ encode(pgid, payload);
+ encode(hobj.get_hash(), payload);
+ encode(osdmap_epoch, payload);
+ encode(flags, payload);
+ encode(reqid, payload);
+ encode_trace(payload, features);
+
+ // -- above decoded up front; below decoded post-dispatch thread --
+
+ encode(client_inc, payload);
+ encode(mtime, payload);
+ encode(get_object_locator(), payload);
+ encode(hobj.oid, payload);
+
+ __u16 num_ops = ops.size();
+ encode(num_ops, payload);
+ for (unsigned i = 0; i < ops.size(); i++)
+ encode(ops[i].op, payload);
+
+ encode(hobj.snap, payload);
+ encode(snap_seq, payload);
+ encode(snaps, payload);
+
+ encode(retry_attempt, payload);
+ encode(features, payload);
+ }
+ }
+
+ void decode_payload() override {
+ ceph_assert(partial_decode_needed && final_decode_needed);
+ p = std::cbegin(payload);
+
+ // Always keep here the newest version of decoding order/rule
+ if (header.version == HEAD_VERSION) {
+ decode(pgid, p); // actual pgid
+ uint32_t hash;
+ decode(hash, p); // raw hash value
+ hobj.set_hash(hash);
+ decode(osdmap_epoch, p);
+ decode(flags, p);
+ decode(reqid, p);
+ decode_trace(p);
+ } else if (header.version == 7) {
+ decode(pgid.pgid, p); // raw pgid
+ hobj.set_hash(pgid.pgid.ps());
+ decode(osdmap_epoch, p);
+ decode(flags, p);
+ eversion_t reassert_version;
+ decode(reassert_version, p);
+ decode(reqid, p);
+ } else if (header.version < 2) {
+ // old decode
+ decode(client_inc, p);
+
+ old_pg_t opgid;
+ ::decode_raw(opgid, p);
+ pgid.pgid = opgid;
+
+ __u32 su;
+ decode(su, p);
+
+ decode(osdmap_epoch, p);
+ decode(flags, p);
+ decode(mtime, p);
+ eversion_t reassert_version;
+ decode(reassert_version, p);
+
+ __u32 oid_len;
+ decode(oid_len, p);
+ decode(hobj.snap, p);
+ decode(snap_seq, p);
+ __u32 num_snaps;
+ decode(num_snaps, p);
+
+ //::decode(ops, p);
+ __u16 num_ops;
+ decode(num_ops, p);
+ ops.resize(num_ops);
+ for (unsigned i = 0; i < num_ops; i++)
+ decode(ops[i].op, p);
+
+ decode_nohead(oid_len, hobj.oid.name, p);
+ decode_nohead(num_snaps, snaps, p);
+
+ // recalculate pgid hash value
+ pgid.pgid.set_ps(ceph_str_hash(CEPH_STR_HASH_RJENKINS,
+ hobj.oid.name.c_str(),
+ hobj.oid.name.length()));
+ hobj.pool = pgid.pgid.pool();
+ hobj.set_hash(pgid.pgid.ps());
+
+ retry_attempt = -1;
+ features = 0;
+ OSDOp::split_osd_op_vector_in_data(ops, data);
+
+ // we did the full decode
+ final_decode_needed = false;
+
+ // put client_inc in reqid.inc for get_reqid()'s benefit
+ reqid = osd_reqid_t();
+ reqid.inc = client_inc;
+ } else if (header.version < 7) {
+ decode(client_inc, p);
+ decode(osdmap_epoch, p);
+ decode(flags, p);
+ decode(mtime, p);
+ eversion_t reassert_version;
+ decode(reassert_version, p);
+
+ object_locator_t oloc;
+ decode(oloc, p);
+
+ if (header.version < 3) {
+ old_pg_t opgid;
+ ::decode_raw(opgid, p);
+ pgid.pgid = opgid;
+ } else {
+ decode(pgid.pgid, p);
+ }
+
+ decode(hobj.oid, p);
+
+ //::decode(ops, p);
+ __u16 num_ops;
+ decode(num_ops, p);
+ ops.resize(num_ops);
+ for (unsigned i = 0; i < num_ops; i++)
+ decode(ops[i].op, p);
+
+ decode(hobj.snap, p);
+ decode(snap_seq, p);
+ decode(snaps, p);
+
+ if (header.version >= 4)
+ decode(retry_attempt, p);
+ else
+ retry_attempt = -1;
+
+ if (header.version >= 5)
+ decode(features, p);
+ else
+ features = 0;
+
+ if (header.version >= 6)
+ decode(reqid, p);
+ else
+ reqid = osd_reqid_t();
+
+ hobj.pool = pgid.pgid.pool();
+ hobj.set_key(oloc.key);
+ hobj.nspace = oloc.nspace;
+ hobj.set_hash(pgid.pgid.ps());
+
+ OSDOp::split_osd_op_vector_in_data(ops, data);
+
+ // we did the full decode
+ final_decode_needed = false;
+
+ // put client_inc in reqid.inc for get_reqid()'s benefit
+ if (reqid.name == entity_name_t() && reqid.tid == 0)
+ reqid.inc = client_inc;
+ }
+
+ partial_decode_needed = false;
+ }
+
+ bool finish_decode() {
+ ceph_assert(!partial_decode_needed); // partial decoding required
+ if (!final_decode_needed)
+ return false; // Message is already final decoded
+ ceph_assert(header.version >= 7);
+
+ decode(client_inc, p);
+ decode(mtime, p);
+ object_locator_t oloc;
+ decode(oloc, p);
+ decode(hobj.oid, p);
+
+ __u16 num_ops;
+ decode(num_ops, p);
+ ops.resize(num_ops);
+ for (unsigned i = 0; i < num_ops; i++)
+ decode(ops[i].op, p);
+
+ decode(hobj.snap, p);
+ decode(snap_seq, p);
+ decode(snaps, p);
+
+ decode(retry_attempt, p);
+
+ decode(features, p);
+
+ hobj.pool = pgid.pgid.pool();
+ hobj.set_key(oloc.key);
+ hobj.nspace = oloc.nspace;
+
+ OSDOp::split_osd_op_vector_in_data(ops, data);
+
+ final_decode_needed = false;
+ return true;
+ }
+
+ void clear_buffers() override {
+ OSDOp::clear_data(ops);
+ bdata_encode = false;
+ }
+
+ std::string_view get_type_name() const override { return "osd_op"; }
+ void print(ostream& out) const override {
+ out << "osd_op(";
+ if (!partial_decode_needed) {
+ out << get_reqid() << ' ';
+ out << pgid;
+ if (!final_decode_needed) {
+ out << ' ';
+ out << hobj
+ << " " << ops
+ << " snapc " << get_snap_seq() << "=" << snaps;
+ if (is_retry_attempt())
+ out << " RETRY=" << get_retry_attempt();
+ } else {
+ out << " " << get_raw_pg() << " (undecoded)";
+ }
+ out << " " << ceph_osd_flag_string(get_flags());
+ out << " e" << osdmap_epoch;
+ }
+ out << ")";
+ }
+};
+
+
+#endif
diff --git a/src/messages/MOSDOpReply.h b/src/messages/MOSDOpReply.h
new file mode 100644
index 00000000..3649921e
--- /dev/null
+++ b/src/messages/MOSDOpReply.h
@@ -0,0 +1,340 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDOPREPLY_H
+#define CEPH_MOSDOPREPLY_H
+
+#include "msg/Message.h"
+
+#include "MOSDOp.h"
+#include "common/errno.h"
+
+/*
+ * OSD op reply
+ *
+ * oid - object id
+ * op - OSD_OP_DELETE, etc.
+ *
+ */
+
+class MOSDOpReply : public MessageInstance<MOSDOpReply> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 2;
+
+ object_t oid;
+ pg_t pgid;
+ vector<OSDOp> ops;
+ bool bdata_encode;
+ int64_t flags = 0;
+ errorcode32_t result;
+ eversion_t bad_replay_version;
+ eversion_t replay_version;
+ version_t user_version = 0;
+ epoch_t osdmap_epoch = 0;
+ int32_t retry_attempt = -1;
+ bool do_redirect;
+ request_redirect_t redirect;
+
+public:
+ const object_t& get_oid() const { return oid; }
+ const pg_t& get_pg() const { return pgid; }
+ int get_flags() const { return flags; }
+
+ bool is_ondisk() const { return get_flags() & CEPH_OSD_FLAG_ONDISK; }
+ bool is_onnvram() const { return get_flags() & CEPH_OSD_FLAG_ONNVRAM; }
+
+ int get_result() const { return result; }
+ const eversion_t& get_replay_version() const { return replay_version; }
+ const version_t& get_user_version() const { return user_version; }
+
+ void set_result(int r) { result = r; }
+
+ void set_reply_versions(eversion_t v, version_t uv) {
+ replay_version = v;
+ user_version = uv;
+ /* We go through some shenanigans here for backwards compatibility
+ * with old clients, who do not look at our replay_version and
+ * user_version but instead see what we now call the
+ * bad_replay_version. On pools without caching
+ * the user_version infrastructure is a slightly-laggy copy of
+ * the regular pg version/at_version infrastructure; the difference
+ * being it is not updated on watch ops like that is -- but on updates
+ * it is set equal to at_version. This means that for non-watch write ops
+ * on classic pools, all three of replay_version, user_version, and
+ * bad_replay_version are identical. But for watch ops the replay_version
+ * has been updated, while the user_at_version has not, and the semantics
+ * we promised old clients are that the version they see is not an update.
+ * So set the bad_replay_version to be the same as the user_at_version. */
+ bad_replay_version = v;
+ if (uv) {
+ bad_replay_version.version = uv;
+ }
+ }
+
+ /* Don't fill in replay_version for non-write ops */
+ void set_enoent_reply_versions(const eversion_t& v, const version_t& uv) {
+ user_version = uv;
+ bad_replay_version = v;
+ }
+
+ void set_redirect(const request_redirect_t& redir) { redirect = redir; }
+ const request_redirect_t& get_redirect() const { return redirect; }
+ bool is_redirect_reply() const { return do_redirect; }
+
+ void add_flags(int f) { flags |= f; }
+
+ void claim_op_out_data(vector<OSDOp>& o) {
+ ceph_assert(ops.size() == o.size());
+ for (unsigned i = 0; i < o.size(); i++) {
+ ops[i].outdata.claim(o[i].outdata);
+ }
+ }
+ void claim_ops(vector<OSDOp>& o) {
+ o.swap(ops);
+ bdata_encode = false;
+ }
+
+ /**
+ * get retry attempt
+ *
+ * If we don't know the attempt (because the server is old), return -1.
+ */
+ int get_retry_attempt() const {
+ return retry_attempt;
+ }
+
+ // osdmap
+ epoch_t get_map_epoch() const { return osdmap_epoch; }
+
+ /*osd_reqid_t get_reqid() { return osd_reqid_t(get_dest(),
+ head.client_inc,
+ head.tid); }
+ */
+
+public:
+ MOSDOpReply()
+ : MessageInstance(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION),
+ bdata_encode(false) {
+ do_redirect = false;
+ }
+ MOSDOpReply(const MOSDOp *req, int r, epoch_t e, int acktype,
+ bool ignore_out_data)
+ : MessageInstance(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION),
+ oid(req->hobj.oid), pgid(req->pgid.pgid), ops(req->ops),
+ bdata_encode(false) {
+
+ set_tid(req->get_tid());
+ result = r;
+ flags =
+ (req->flags & ~(CEPH_OSD_FLAG_ONDISK|CEPH_OSD_FLAG_ONNVRAM|CEPH_OSD_FLAG_ACK)) | acktype;
+ osdmap_epoch = e;
+ user_version = 0;
+ retry_attempt = req->get_retry_attempt();
+ do_redirect = false;
+
+ // zero out ops payload_len and possibly out data
+ for (unsigned i = 0; i < ops.size(); i++) {
+ ops[i].op.payload_len = 0;
+ if (ignore_out_data)
+ ops[i].outdata.clear();
+ }
+ }
+private:
+ ~MOSDOpReply() override {}
+
+public:
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ if(false == bdata_encode) {
+ OSDOp::merge_osd_op_vector_out_data(ops, data);
+ bdata_encode = true;
+ }
+
+ if ((features & CEPH_FEATURE_PGID64) == 0) {
+ header.version = 1;
+ ceph_osd_reply_head head;
+ memset(&head, 0, sizeof(head));
+ head.layout.ol_pgid = pgid.get_old_pg().v;
+ head.flags = flags;
+ head.osdmap_epoch = osdmap_epoch;
+ head.reassert_version = bad_replay_version;
+ head.result = result;
+ head.num_ops = ops.size();
+ head.object_len = oid.name.length();
+ encode(head, payload);
+ for (unsigned i = 0; i < head.num_ops; i++) {
+ encode(ops[i].op, payload);
+ }
+ encode_nohead(oid.name, payload);
+ } else {
+ header.version = HEAD_VERSION;
+ encode(oid, payload);
+ encode(pgid, payload);
+ encode(flags, payload);
+ encode(result, payload);
+ encode(bad_replay_version, payload);
+ encode(osdmap_epoch, payload);
+
+ __u32 num_ops = ops.size();
+ encode(num_ops, payload);
+ for (unsigned i = 0; i < num_ops; i++)
+ encode(ops[i].op, payload);
+
+ encode(retry_attempt, payload);
+
+ for (unsigned i = 0; i < num_ops; i++)
+ encode(ops[i].rval, payload);
+
+ encode(replay_version, payload);
+ encode(user_version, payload);
+ if ((features & CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING) == 0) {
+ header.version = 6;
+ encode(redirect, payload);
+ } else {
+ do_redirect = !redirect.empty();
+ encode(do_redirect, payload);
+ if (do_redirect) {
+ encode(redirect, payload);
+ }
+ }
+ encode_trace(payload, features);
+ }
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+
+ // Always keep here the newest version of decoding order/rule
+ if (header.version == HEAD_VERSION) {
+ decode(oid, p);
+ decode(pgid, p);
+ decode(flags, p);
+ decode(result, p);
+ decode(bad_replay_version, p);
+ decode(osdmap_epoch, p);
+
+ __u32 num_ops = ops.size();
+ decode(num_ops, p);
+ ops.resize(num_ops);
+ for (unsigned i = 0; i < num_ops; i++)
+ decode(ops[i].op, p);
+ decode(retry_attempt, p);
+
+ for (unsigned i = 0; i < num_ops; ++i)
+ decode(ops[i].rval, p);
+
+ OSDOp::split_osd_op_vector_out_data(ops, data);
+
+ decode(replay_version, p);
+ decode(user_version, p);
+ decode(do_redirect, p);
+ if (do_redirect)
+ decode(redirect, p);
+ decode_trace(p);
+ } else if (header.version < 2) {
+ ceph_osd_reply_head head;
+ decode(head, p);
+ ops.resize(head.num_ops);
+ for (unsigned i = 0; i < head.num_ops; i++) {
+ decode(ops[i].op, p);
+ }
+ decode_nohead(head.object_len, oid.name, p);
+ pgid = pg_t(head.layout.ol_pgid);
+ result = (int32_t)head.result;
+ flags = head.flags;
+ replay_version = head.reassert_version;
+ user_version = replay_version.version;
+ osdmap_epoch = head.osdmap_epoch;
+ retry_attempt = -1;
+ } else {
+ decode(oid, p);
+ decode(pgid, p);
+ decode(flags, p);
+ decode(result, p);
+ decode(bad_replay_version, p);
+ decode(osdmap_epoch, p);
+
+ __u32 num_ops = ops.size();
+ decode(num_ops, p);
+ ops.resize(num_ops);
+ for (unsigned i = 0; i < num_ops; i++)
+ decode(ops[i].op, p);
+
+ if (header.version >= 3)
+ decode(retry_attempt, p);
+ else
+ retry_attempt = -1;
+
+ if (header.version >= 4) {
+ for (unsigned i = 0; i < num_ops; ++i)
+ decode(ops[i].rval, p);
+
+ OSDOp::split_osd_op_vector_out_data(ops, data);
+ }
+
+ if (header.version >= 5) {
+ decode(replay_version, p);
+ decode(user_version, p);
+ } else {
+ replay_version = bad_replay_version;
+ user_version = replay_version.version;
+ }
+
+ if (header.version == 6) {
+ decode(redirect, p);
+ do_redirect = !redirect.empty();
+ }
+ if (header.version >= 7) {
+ decode(do_redirect, p);
+ if (do_redirect) {
+ decode(redirect, p);
+ }
+ }
+ if (header.version >= 8) {
+ decode_trace(p);
+ }
+ }
+ }
+
+ std::string_view get_type_name() const override { return "osd_op_reply"; }
+
+ void print(ostream& out) const override {
+ out << "osd_op_reply(" << get_tid()
+ << " " << oid << " " << ops
+ << " v" << get_replay_version()
+ << " uv" << get_user_version();
+ if (is_ondisk())
+ out << " ondisk";
+ else if (is_onnvram())
+ out << " onnvram";
+ else
+ out << " ack";
+ out << " = " << get_result();
+ if (get_result() < 0) {
+ out << " (" << cpp_strerror(get_result()) << ")";
+ }
+ if (is_redirect_reply()) {
+ out << " redirect: { " << redirect << " }";
+ }
+ out << ")";
+ }
+
+};
+
+
+#endif
diff --git a/src/messages/MOSDPGBackfill.h b/src/messages/MOSDPGBackfill.h
new file mode 100644
index 00000000..47d25b0c
--- /dev/null
+++ b/src/messages/MOSDPGBackfill.h
@@ -0,0 +1,114 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDPGBACKFILL_H
+#define CEPH_MOSDPGBACKFILL_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGBackfill : public MessageInstance<MOSDPGBackfill, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+public:
+ enum {
+ OP_BACKFILL_PROGRESS = 2,
+ OP_BACKFILL_FINISH = 3,
+ OP_BACKFILL_FINISH_ACK = 4,
+ };
+ const char *get_op_name(int o) const {
+ switch (o) {
+ case OP_BACKFILL_PROGRESS: return "progress";
+ case OP_BACKFILL_FINISH: return "finish";
+ case OP_BACKFILL_FINISH_ACK: return "finish_ack";
+ default: return "???";
+ }
+ }
+
+ __u32 op = 0;
+ epoch_t map_epoch = 0, query_epoch = 0;
+ spg_t pgid;
+ hobject_t last_backfill;
+ pg_stat_t stats;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return query_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(map_epoch, p);
+ decode(query_epoch, p);
+ decode(pgid.pgid, p);
+ decode(last_backfill, p);
+
+ // For compatibility with version 1
+ decode(stats.stats, p);
+
+ decode(stats, p);
+
+ // Handle hobject_t format change
+ if (!last_backfill.is_max() &&
+ last_backfill.pool == -1)
+ last_backfill.pool = pgid.pool();
+ decode(pgid.shard, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(map_epoch, payload);
+ encode(query_epoch, payload);
+ encode(pgid.pgid, payload);
+ encode(last_backfill, payload);
+
+ // For compatibility with version 1
+ encode(stats.stats, payload);
+
+ encode(stats, payload);
+
+ encode(pgid.shard, payload);
+ }
+
+ MOSDPGBackfill()
+ : MessageInstance(MSG_OSD_PG_BACKFILL, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDPGBackfill(__u32 o, epoch_t e, epoch_t qe, spg_t p)
+ : MessageInstance(MSG_OSD_PG_BACKFILL, HEAD_VERSION, COMPAT_VERSION),
+ op(o),
+ map_epoch(e), query_epoch(e),
+ pgid(p) {}
+private:
+ ~MOSDPGBackfill() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_backfill"; }
+ void print(ostream& out) const override {
+ out << "pg_backfill(" << get_op_name(op)
+ << " " << pgid
+ << " e " << map_epoch << "/" << query_epoch
+ << " lb " << last_backfill
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGBackfillRemove.h b/src/messages/MOSDPGBackfillRemove.h
new file mode 100644
index 00000000..35914518
--- /dev/null
+++ b/src/messages/MOSDPGBackfillRemove.h
@@ -0,0 +1,78 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2017 Sage Weil <sage@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDPGBACKFILLREMOVE_H
+#define CEPH_MOSDPGBACKFILLREMOVE_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * instruct non-primary to remove some objects during backfill
+ */
+
+class MOSDPGBackfillRemove : public MessageInstance<MOSDPGBackfillRemove, MOSDFastDispatchOp> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ spg_t pgid; ///< target spg_t
+ epoch_t map_epoch = 0;
+ list<pair<hobject_t,eversion_t>> ls; ///< objects to remove
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDPGBackfillRemove()
+ : MessageInstance(MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION,
+ COMPAT_VERSION) {}
+
+ MOSDPGBackfillRemove(spg_t pgid, epoch_t map_epoch)
+ : MessageInstance(MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION,
+ COMPAT_VERSION),
+ pgid(pgid),
+ map_epoch(map_epoch) {}
+
+private:
+ ~MOSDPGBackfillRemove() {}
+
+public:
+ std::string_view get_type_name() const override { return "backfill_remove"; }
+ void print(ostream& out) const override {
+ out << "backfill_remove(" << pgid << " e" << map_epoch
+ << " " << ls << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(ls, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(ls, p);
+ }
+};
+
+
+
+#endif
diff --git a/src/messages/MOSDPGCreate.h b/src/messages/MOSDPGCreate.h
new file mode 100644
index 00000000..eef056ab
--- /dev/null
+++ b/src/messages/MOSDPGCreate.h
@@ -0,0 +1,72 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGCREATE_H
+#define CEPH_MOSDPGCREATE_H
+
+#include "msg/Message.h"
+#include "osd/osd_types.h"
+
+/*
+ * PGCreate - instruct an OSD to create a pg, if it doesn't already exist
+ */
+
+class MOSDPGCreate : public MessageInstance<MOSDPGCreate> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+
+ version_t epoch = 0;
+ map<pg_t,pg_create_t> mkpg;
+ map<pg_t,utime_t> ctimes;
+
+ MOSDPGCreate()
+ : MessageInstance(MSG_OSD_PG_CREATE, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDPGCreate(epoch_t e)
+ : MessageInstance(MSG_OSD_PG_CREATE, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e) { }
+private:
+ ~MOSDPGCreate() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_create"; }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(mkpg, payload);
+ encode(ctimes, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(mkpg, p);
+ decode(ctimes, p);
+ }
+
+ void print(ostream& out) const override {
+ out << "osd_pg_create(e" << epoch;
+ for (map<pg_t,pg_create_t>::const_iterator i = mkpg.begin();
+ i != mkpg.end();
+ ++i) {
+ out << " " << i->first << ":" << i->second.created;
+ }
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGCreate2.h b/src/messages/MOSDPGCreate2.h
new file mode 100644
index 00000000..f232483f
--- /dev/null
+++ b/src/messages/MOSDPGCreate2.h
@@ -0,0 +1,50 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+#include "osd/osd_types.h"
+
+/*
+ * PGCreate2 - instruct an OSD to create some pgs
+ */
+
+class MOSDPGCreate2 : public MessageInstance<MOSDPGCreate2> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ epoch_t epoch = 0;
+ map<spg_t,pair<epoch_t,utime_t>> pgs;
+
+ MOSDPGCreate2()
+ : MessageInstance(MSG_OSD_PG_CREATE2, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDPGCreate2(epoch_t e)
+ : MessageInstance(MSG_OSD_PG_CREATE2, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e) { }
+private:
+ ~MOSDPGCreate2() override {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "pg_create2";
+ }
+ void print(ostream& out) const override {
+ out << "pg_create2(e" << epoch << " " << pgs << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(pgs, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ using ceph::decode;
+ decode(epoch, p);
+ decode(pgs, p);
+ }
+};
diff --git a/src/messages/MOSDPGCreated.h b/src/messages/MOSDPGCreated.h
new file mode 100644
index 00000000..6ccb9f97
--- /dev/null
+++ b/src/messages/MOSDPGCreated.h
@@ -0,0 +1,35 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "osd/osd_types.h"
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDPGCreated : public MessageInstance<MOSDPGCreated, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ pg_t pgid;
+ MOSDPGCreated()
+ : MessageInstance(MSG_OSD_PG_CREATED, 0)
+ {}
+ MOSDPGCreated(pg_t pgid)
+ : MessageInstance(MSG_OSD_PG_CREATED, 0),
+ pgid(pgid)
+ {}
+ std::string_view get_type_name() const override { return "pg_created"; }
+ void print(ostream& out) const override {
+ out << "osd_pg_created(" << pgid << ")";
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(pgid, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(pgid, p);
+ }
+};
diff --git a/src/messages/MOSDPGInfo.h b/src/messages/MOSDPGInfo.h
new file mode 100644
index 00000000..461a0fa6
--- /dev/null
+++ b/src/messages/MOSDPGInfo.h
@@ -0,0 +1,75 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGINFO_H
+#define CEPH_MOSDPGINFO_H
+
+#include "msg/Message.h"
+#include "osd/osd_types.h"
+
+class MOSDPGInfo : public MessageInstance<MOSDPGInfo> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 5;
+ static constexpr int COMPAT_VERSION = 5;
+
+ epoch_t epoch = 0;
+
+public:
+ vector<pair<pg_notify_t,PastIntervals> > pg_list;
+
+ epoch_t get_epoch() const { return epoch; }
+
+ MOSDPGInfo()
+ : MessageInstance(MSG_OSD_PG_INFO, HEAD_VERSION, COMPAT_VERSION) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGInfo(version_t mv)
+ : MessageInstance(MSG_OSD_PG_INFO, HEAD_VERSION, COMPAT_VERSION),
+ epoch(mv) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+private:
+ ~MOSDPGInfo() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_info"; }
+ void print(ostream& out) const override {
+ out << "pg_info(";
+ for (auto i = pg_list.begin();
+ i != pg_list.end();
+ ++i) {
+ if (i != pg_list.begin())
+ out << " ";
+ out << i->first << "=" << i->second;
+ }
+ out << " epoch " << epoch
+ << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(pg_list, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pg_list, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGLog.h b/src/messages/MOSDPGLog.h
new file mode 100644
index 00000000..6c9728ef
--- /dev/null
+++ b/src/messages/MOSDPGLog.h
@@ -0,0 +1,124 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGLOG_H
+#define CEPH_MOSDPGLOG_H
+
+#include "messages/MOSDPeeringOp.h"
+
+class MOSDPGLog : public MessageInstance<MOSDPGLog, MOSDPeeringOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 5;
+ static constexpr int COMPAT_VERSION = 5;
+
+ epoch_t epoch = 0;
+ /// query_epoch is the epoch of the query being responded to, or
+ /// the current epoch if this is not being sent in response to a
+ /// query. This allows the recipient to disregard responses to old
+ /// queries.
+ epoch_t query_epoch = 0;
+
+public:
+ shard_id_t to;
+ shard_id_t from;
+ pg_info_t info;
+ pg_log_t log;
+ pg_missing_t missing;
+ PastIntervals past_intervals;
+
+ epoch_t get_epoch() const { return epoch; }
+ spg_t get_pgid() const { return spg_t(info.pgid.pgid, to); }
+ epoch_t get_query_epoch() const { return query_epoch; }
+
+ spg_t get_spg() const override {
+ return spg_t(info.pgid.pgid, to);
+ }
+ epoch_t get_map_epoch() const override {
+ return epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return query_epoch;
+ }
+
+ PGPeeringEvent *get_event() override {
+ return new PGPeeringEvent(
+ epoch, query_epoch,
+ MLogRec(pg_shard_t(get_source().num(), from),
+ this),
+ true,
+ new PGCreateInfo(
+ get_spg(),
+ query_epoch,
+ info.history,
+ past_intervals,
+ false));
+ }
+
+ MOSDPGLog() : MessageInstance(MSG_OSD_PG_LOG, HEAD_VERSION, COMPAT_VERSION) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGLog(shard_id_t to, shard_id_t from,
+ version_t mv, pg_info_t& i, epoch_t query_epoch)
+ : MessageInstance(MSG_OSD_PG_LOG, HEAD_VERSION, COMPAT_VERSION),
+ epoch(mv), query_epoch(query_epoch),
+ to(to), from(from),
+ info(i) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+
+private:
+ ~MOSDPGLog() override {}
+
+public:
+ std::string_view get_type_name() const override { return "PGlog"; }
+ void inner_print(ostream& out) const override {
+ // NOTE: log is not const, but operator<< doesn't touch fields
+ // swapped out by OSD code.
+ out << "log " << log
+ << " pi " << past_intervals;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(info, payload);
+ encode(log, payload);
+ encode(missing, payload);
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ // pre-nautilus OSDs do not set last_peering_reset properly
+ encode(epoch, payload);
+ } else {
+ encode(query_epoch, payload);
+ }
+ encode(past_intervals, payload);
+ encode(to, payload);
+ encode(from, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(info, p);
+ log.decode(p, info.pgid.pool());
+ missing.decode(p, info.pgid.pool());
+ decode(query_epoch, p);
+ decode(past_intervals, p);
+ decode(to, p);
+ decode(from, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGNotify.h b/src/messages/MOSDPGNotify.h
new file mode 100644
index 00000000..4370eae3
--- /dev/null
+++ b/src/messages/MOSDPGNotify.h
@@ -0,0 +1,87 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDPGPEERNOTIFY_H
+#define CEPH_MOSDPGPEERNOTIFY_H
+
+#include "msg/Message.h"
+
+#include "osd/osd_types.h"
+
+/*
+ * PGNotify - notify primary of my PGs and versions.
+ */
+
+class MOSDPGNotify : public MessageInstance<MOSDPGNotify> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 6;
+ static constexpr int COMPAT_VERSION = 6;
+
+ epoch_t epoch = 0;
+ /// query_epoch is the epoch of the query being responded to, or
+ /// the current epoch if this is not being sent in response to a
+ /// query. This allows the recipient to disregard responses to old
+ /// queries.
+ vector<pair<pg_notify_t,PastIntervals> > pg_list; // pgid -> version
+
+ public:
+ version_t get_epoch() const { return epoch; }
+ const vector<pair<pg_notify_t,PastIntervals> >& get_pg_list() const {
+ return pg_list;
+ }
+
+ MOSDPGNotify()
+ : MessageInstance(MSG_OSD_PG_NOTIFY, HEAD_VERSION, COMPAT_VERSION) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGNotify(epoch_t e, vector<pair<pg_notify_t,PastIntervals> >& l)
+ : MessageInstance(MSG_OSD_PG_NOTIFY, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e) {
+ pg_list.swap(l);
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+private:
+ ~MOSDPGNotify() override {}
+
+public:
+ std::string_view get_type_name() const override { return "PGnot"; }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(pg_list, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pg_list, p);
+ }
+ void print(ostream& out) const override {
+ out << "pg_notify(";
+ for (auto i = pg_list.begin();
+ i != pg_list.end();
+ ++i) {
+ if (i != pg_list.begin())
+ out << " ";
+ out << i->first << "=" << i->second;
+ }
+ out << " epoch " << epoch
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGPull.h b/src/messages/MOSDPGPull.h
new file mode 100644
index 00000000..16eeca7e
--- /dev/null
+++ b/src/messages/MOSDPGPull.h
@@ -0,0 +1,106 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDPGPULL_H
+#define MOSDPGPULL_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGPull : public MessageInstance<MOSDPGPull, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 2;
+
+ vector<PullOp> pulls;
+
+public:
+ pg_shard_t from;
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ uint64_t cost;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ void take_pulls(vector<PullOp> *outpulls) {
+ outpulls->swap(pulls);
+ }
+ void set_pulls(vector<PullOp> *inpulls) {
+ inpulls->swap(pulls);
+ }
+
+ MOSDPGPull()
+ : MessageInstance(MSG_OSD_PG_PULL, HEAD_VERSION, COMPAT_VERSION),
+ cost(0)
+ {}
+
+ void compute_cost(CephContext *cct) {
+ cost = 0;
+ for (vector<PullOp>::iterator i = pulls.begin();
+ i != pulls.end();
+ ++i) {
+ cost += i->cost(cct);
+ }
+ }
+
+ int get_cost() const override {
+ return cost;
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(map_epoch, p);
+ decode(pulls, p);
+ decode(cost, p);
+ decode(pgid.shard, p);
+ decode(from, p);
+ if (header.version >= 3) {
+ decode(min_epoch, p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid.pgid, payload);
+ encode(map_epoch, payload);
+ encode(pulls, payload, features);
+ encode(cost, payload);
+ encode(pgid.shard, payload);
+ encode(from, payload);
+ encode(min_epoch, payload);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDPGPull"; }
+
+ void print(ostream& out) const override {
+ out << "MOSDPGPull(" << pgid
+ << " e" << map_epoch << "/" << min_epoch
+ << " cost " << cost
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGPush.h b/src/messages/MOSDPGPush.h
new file mode 100644
index 00000000..3960ad70
--- /dev/null
+++ b/src/messages/MOSDPGPush.h
@@ -0,0 +1,112 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDPGPUSH_H
+#define MOSDPGPUSH_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGPush : public MessageInstance<MOSDPGPush, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ pg_shard_t from;
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ vector<PushOp> pushes;
+ bool is_repair = false;
+
+private:
+ uint64_t cost;
+
+public:
+ void compute_cost(CephContext *cct) {
+ cost = 0;
+ for (vector<PushOp>::iterator i = pushes.begin();
+ i != pushes.end();
+ ++i) {
+ cost += i->cost(cct);
+ }
+ }
+
+ int get_cost() const override {
+ return cost;
+ }
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ void set_cost(uint64_t c) {
+ cost = c;
+ }
+
+ MOSDPGPush()
+ : MessageInstance(MSG_OSD_PG_PUSH, HEAD_VERSION, COMPAT_VERSION),
+ cost(0)
+ {}
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(map_epoch, p);
+ decode(pushes, p);
+ decode(cost, p);
+ decode(pgid.shard, p);
+ decode(from, p);
+ if (header.version >= 3) {
+ decode(min_epoch, p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ if (header.version >= 4) {
+ decode(is_repair, p);
+ } else {
+ is_repair = false;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid.pgid, payload);
+ encode(map_epoch, payload);
+ encode(pushes, payload, features);
+ encode(cost, payload);
+ encode(pgid.shard, payload);
+ encode(from, payload);
+ encode(min_epoch, payload);
+ encode(is_repair, payload);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDPGPush"; }
+
+ void print(ostream& out) const override {
+ out << "MOSDPGPush(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << pushes;
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGPushReply.h b/src/messages/MOSDPGPushReply.h
new file mode 100644
index 00000000..b9b7687e
--- /dev/null
+++ b/src/messages/MOSDPGPushReply.h
@@ -0,0 +1,98 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Inktank Storage, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef MOSDPGPUSHREPLY_H
+#define MOSDPGPUSHREPLY_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGPushReply : public MessageInstance<MOSDPGPushReply, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ pg_shard_t from;
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ vector<PushReplyOp> replies;
+ uint64_t cost;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDPGPushReply()
+ : MessageInstance(MSG_OSD_PG_PUSH_REPLY, HEAD_VERSION, COMPAT_VERSION),
+ cost(0)
+ {}
+
+ void compute_cost(CephContext *cct) {
+ cost = 0;
+ for (vector<PushReplyOp>::iterator i = replies.begin();
+ i != replies.end();
+ ++i) {
+ cost += i->cost(cct);
+ }
+ }
+
+ int get_cost() const override {
+ return cost;
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(map_epoch, p);
+ decode(replies, p);
+ decode(cost, p);
+ decode(pgid.shard, p);
+ decode(from, p);
+ if (header.version >= 3) {
+ decode(min_epoch, p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid.pgid, payload);
+ encode(map_epoch, payload);
+ encode(replies, payload);
+ encode(cost, payload);
+ encode(pgid.shard, payload);
+ encode(from, payload);
+ encode(min_epoch, payload);
+ }
+
+ void print(ostream& out) const override {
+ out << "MOSDPGPushReply(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << replies;
+ out << ")";
+ }
+
+ std::string_view get_type_name() const override { return "MOSDPGPushReply"; }
+};
+
+#endif
diff --git a/src/messages/MOSDPGQuery.h b/src/messages/MOSDPGQuery.h
new file mode 100644
index 00000000..d1d9ecd9
--- /dev/null
+++ b/src/messages/MOSDPGQuery.h
@@ -0,0 +1,80 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGQUERY_H
+#define CEPH_MOSDPGQUERY_H
+
+#include "common/hobject.h"
+#include "msg/Message.h"
+
+/*
+ * PGQuery - query another OSD as to the contents of their PGs
+ */
+
+class MOSDPGQuery : public MessageInstance<MOSDPGQuery> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 4;
+
+ version_t epoch = 0;
+
+ public:
+ version_t get_epoch() const { return epoch; }
+ map<spg_t, pg_query_t> pg_list;
+
+ MOSDPGQuery() : MessageInstance(MSG_OSD_PG_QUERY,
+ HEAD_VERSION,
+ COMPAT_VERSION) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGQuery(epoch_t e, map<spg_t,pg_query_t>& ls) :
+ MessageInstance(MSG_OSD_PG_QUERY,
+ HEAD_VERSION,
+ COMPAT_VERSION),
+ epoch(e) {
+ pg_list.swap(ls);
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+private:
+ ~MOSDPGQuery() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_query"; }
+ void print(ostream& out) const override {
+ out << "pg_query(";
+ for (map<spg_t,pg_query_t>::const_iterator p = pg_list.begin();
+ p != pg_list.end(); ++p) {
+ if (p != pg_list.begin())
+ out << ",";
+ out << p->first;
+ }
+ out << " epoch " << epoch << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(pg_list, payload, features);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pg_list, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGReadyToMerge.h b/src/messages/MOSDPGReadyToMerge.h
new file mode 100644
index 00000000..b8c18095
--- /dev/null
+++ b/src/messages/MOSDPGReadyToMerge.h
@@ -0,0 +1,58 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+class MOSDPGReadyToMerge
+ : public MessageInstance<MOSDPGReadyToMerge, PaxosServiceMessage> {
+public:
+ pg_t pgid;
+ eversion_t source_version, target_version;
+ epoch_t last_epoch_started = 0;
+ epoch_t last_epoch_clean = 0;
+ bool ready = true;
+
+ MOSDPGReadyToMerge()
+ : MessageInstance(MSG_OSD_PG_READY_TO_MERGE, 0)
+ {}
+ MOSDPGReadyToMerge(pg_t p, eversion_t sv, eversion_t tv,
+ epoch_t les, epoch_t lec, bool r, epoch_t v)
+ : MessageInstance(MSG_OSD_PG_READY_TO_MERGE, v),
+ pgid(p),
+ source_version(sv),
+ target_version(tv),
+ last_epoch_started(les),
+ last_epoch_clean(lec),
+ ready(r)
+ {}
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(pgid, payload);
+ encode(source_version, payload);
+ encode(target_version, payload);
+ encode(last_epoch_started, payload);
+ encode(last_epoch_clean, payload);
+ encode(ready, payload);
+ }
+ void decode_payload() override {
+ bufferlist::const_iterator p = payload.begin();
+ paxos_decode(p);
+ decode(pgid, p);
+ decode(source_version, p);
+ decode(target_version, p);
+ decode(last_epoch_started, p);
+ decode(last_epoch_clean, p);
+ decode(ready, p);
+ }
+ std::string_view get_type_name() const override { return "osd_pg_ready_to_merge"; }
+ void print(ostream &out) const {
+ out << get_type_name()
+ << "(" << pgid
+ << " sv " << source_version
+ << " tv " << target_version
+ << " les/c " << last_epoch_started << "/" << last_epoch_clean
+ << (ready ? " ready" : " NOT READY")
+ << " v" << version << ")";
+ }
+};
diff --git a/src/messages/MOSDPGRecoveryDelete.h b/src/messages/MOSDPGRecoveryDelete.h
new file mode 100644
index 00000000..c6fa1366
--- /dev/null
+++ b/src/messages/MOSDPGRecoveryDelete.h
@@ -0,0 +1,93 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MOSDPGRECOVERYDELETE_H
+#define CEPH_MOSDPGRECOVERYDELETE_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * instruct non-primary to remove some objects during recovery
+ */
+
+class MOSDPGRecoveryDelete : public MessageInstance<MOSDPGRecoveryDelete, MOSDFastDispatchOp> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ pg_shard_t from;
+ spg_t pgid; ///< target spg_t
+ epoch_t map_epoch, min_epoch;
+ list<pair<hobject_t, eversion_t> > objects; ///< objects to remove
+
+private:
+ uint64_t cost;
+
+public:
+ int get_cost() const override {
+ return cost;
+ }
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ void set_cost(uint64_t c) {
+ cost = c;
+ }
+
+ MOSDPGRecoveryDelete()
+ : MessageInstance(MSG_OSD_PG_RECOVERY_DELETE, HEAD_VERSION,
+ COMPAT_VERSION), cost(0) {}
+
+ MOSDPGRecoveryDelete(pg_shard_t from, spg_t pgid, epoch_t map_epoch,
+ epoch_t min_epoch)
+ : MessageInstance(MSG_OSD_PG_RECOVERY_DELETE, HEAD_VERSION,
+ COMPAT_VERSION),
+ from(from),
+ pgid(pgid),
+ map_epoch(map_epoch),
+ min_epoch(min_epoch),
+ cost(0) {}
+
+private:
+ ~MOSDPGRecoveryDelete() {}
+
+public:
+ std::string_view get_type_name() const { return "recovery_delete"; }
+ void print(ostream& out) const {
+ out << "MOSDPGRecoveryDelete(" << pgid << " e" << map_epoch << ","
+ << min_epoch << " " << objects << ")";
+ }
+
+ void encode_payload(uint64_t features) {
+ using ceph::encode;
+ encode(from, payload);
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(min_epoch, payload);
+ encode(cost, payload);
+ encode(objects, payload);
+ }
+ void decode_payload() {
+ auto p = payload.cbegin();
+ decode(from, p);
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(min_epoch, p);
+ decode(cost, p);
+ decode(objects, p);
+ }
+};
+
+
+
+#endif
diff --git a/src/messages/MOSDPGRecoveryDeleteReply.h b/src/messages/MOSDPGRecoveryDeleteReply.h
new file mode 100644
index 00000000..e6401774
--- /dev/null
+++ b/src/messages/MOSDPGRecoveryDeleteReply.h
@@ -0,0 +1,64 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef MOSDRECOVERYDELETEREPLY_H
+#define MOSDRECOVERYDELETEREPLY_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGRecoveryDeleteReply : public MessageInstance<MOSDPGRecoveryDeleteReply, MOSDFastDispatchOp> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ pg_shard_t from;
+ spg_t pgid;
+ epoch_t map_epoch, min_epoch;
+ list<pair<hobject_t, eversion_t> > objects;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDPGRecoveryDeleteReply()
+ : MessageInstance(MSG_OSD_PG_RECOVERY_DELETE_REPLY, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(0), min_epoch(0)
+ {}
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(map_epoch, p);
+ decode(min_epoch, p);
+ decode(objects, p);
+ decode(pgid.shard, p);
+ decode(from, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid.pgid, payload);
+ encode(map_epoch, payload);
+ encode(min_epoch, payload);
+ encode(objects, payload);
+ encode(pgid.shard, payload);
+ encode(from, payload);
+ }
+
+ void print(ostream& out) const override {
+ out << "MOSDPGRecoveryDeleteReply(" << pgid
+ << " e" << map_epoch << "," << min_epoch << " " << objects << ")";
+ }
+
+ std::string_view get_type_name() const override { return "recovery_delete_reply"; }
+};
+
+#endif
diff --git a/src/messages/MOSDPGRemove.h b/src/messages/MOSDPGRemove.h
new file mode 100644
index 00000000..94e9885e
--- /dev/null
+++ b/src/messages/MOSDPGRemove.h
@@ -0,0 +1,71 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGREMOVE_H
+#define CEPH_MOSDPGREMOVE_H
+
+#include "common/hobject.h"
+#include "msg/Message.h"
+
+
+class MOSDPGRemove : public MessageInstance<MOSDPGRemove> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+
+ epoch_t epoch = 0;
+
+ public:
+ vector<spg_t> pg_list;
+
+ epoch_t get_epoch() const { return epoch; }
+
+ MOSDPGRemove() :
+ MessageInstance(MSG_OSD_PG_REMOVE, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDPGRemove(epoch_t e, vector<spg_t>& l) :
+ MessageInstance(MSG_OSD_PG_REMOVE, HEAD_VERSION, COMPAT_VERSION) {
+ this->epoch = e;
+ pg_list.swap(l);
+ }
+private:
+ ~MOSDPGRemove() override {}
+
+public:
+ std::string_view get_type_name() const override { return "PGrm"; }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(pg_list, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pg_list, p);
+ }
+ void print(ostream& out) const override {
+ out << "osd pg remove(" << "epoch " << epoch << "; ";
+ for (vector<spg_t>::const_iterator i = pg_list.begin();
+ i != pg_list.end();
+ ++i) {
+ out << "pg" << *i << "; ";
+ }
+ out << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGScan.h b/src/messages/MOSDPGScan.h
new file mode 100644
index 00000000..99f0b0bd
--- /dev/null
+++ b/src/messages/MOSDPGScan.h
@@ -0,0 +1,117 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDPGSCAN_H
+#define CEPH_MOSDPGSCAN_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGScan : public MessageInstance<MOSDPGScan, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ enum {
+ OP_SCAN_GET_DIGEST = 1, // just objects and versions
+ OP_SCAN_DIGEST = 2, // result
+ };
+ const char *get_op_name(int o) const {
+ switch (o) {
+ case OP_SCAN_GET_DIGEST: return "get_digest";
+ case OP_SCAN_DIGEST: return "digest";
+ default: return "???";
+ }
+ }
+
+ __u32 op = 0;
+ epoch_t map_epoch = 0, query_epoch = 0;
+ pg_shard_t from;
+ spg_t pgid;
+ hobject_t begin, end;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return query_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(map_epoch, p);
+ decode(query_epoch, p);
+ decode(pgid.pgid, p);
+ decode(begin, p);
+ decode(end, p);
+
+ // handle hobject_t format upgrade
+ if (!begin.is_max() && begin.pool == -1)
+ begin.pool = pgid.pool();
+ if (!end.is_max() && end.pool == -1)
+ end.pool = pgid.pool();
+
+ decode(from, p);
+ decode(pgid.shard, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(map_epoch, payload);
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ // pre-nautilus OSDs do not set last_peering_reset properly
+ encode(map_epoch, payload);
+ } else {
+ encode(query_epoch, payload);
+ }
+ encode(pgid.pgid, payload);
+ encode(begin, payload);
+ encode(end, payload);
+ encode(from, payload);
+ encode(pgid.shard, payload);
+ }
+
+ MOSDPGScan()
+ : MessageInstance(MSG_OSD_PG_SCAN, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDPGScan(__u32 o, pg_shard_t from,
+ epoch_t e, epoch_t qe, spg_t p, hobject_t be, hobject_t en)
+ : MessageInstance(MSG_OSD_PG_SCAN, HEAD_VERSION, COMPAT_VERSION),
+ op(o),
+ map_epoch(e), query_epoch(qe),
+ from(from),
+ pgid(p),
+ begin(be), end(en) {
+ }
+private:
+ ~MOSDPGScan() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_scan"; }
+ void print(ostream& out) const override {
+ out << "pg_scan(" << get_op_name(op)
+ << " " << pgid
+ << " " << begin << "-" << end
+ << " e " << map_epoch << "/" << query_epoch
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGTemp.h b/src/messages/MOSDPGTemp.h
new file mode 100644
index 00000000..22a8602b
--- /dev/null
+++ b/src/messages/MOSDPGTemp.h
@@ -0,0 +1,67 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+
+#ifndef CEPH_MOSDPGTEMP_H
+#define CEPH_MOSDPGTEMP_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDPGTemp : public MessageInstance<MOSDPGTemp, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ epoch_t map_epoch = 0;
+ map<pg_t, vector<int32_t> > pg_temp;
+ bool forced = false;
+
+ MOSDPGTemp(epoch_t e)
+ : MessageInstance(MSG_OSD_PGTEMP, e, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(e)
+ {}
+ MOSDPGTemp()
+ : MOSDPGTemp(0)
+ {}
+private:
+ ~MOSDPGTemp() override {}
+
+public:
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(map_epoch, payload);
+ encode(pg_temp, payload);
+ encode(forced, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(map_epoch, p);
+ decode(pg_temp, p);
+ if (header.version >= 2) {
+ decode(forced, p);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "osd_pgtemp"; }
+ void print(ostream &out) const override {
+ out << "osd_pgtemp(e" << map_epoch << " " << pg_temp << " v" << version << ")";
+ }
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+};
+
+#endif
diff --git a/src/messages/MOSDPGTrim.h b/src/messages/MOSDPGTrim.h
new file mode 100644
index 00000000..e596d12b
--- /dev/null
+++ b/src/messages/MOSDPGTrim.h
@@ -0,0 +1,79 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDPGTRIM_H
+#define CEPH_MOSDPGTRIM_H
+
+#include "msg/Message.h"
+#include "messages/MOSDPeeringOp.h"
+
+class MOSDPGTrim : public MessageInstance<MOSDPGTrim, MOSDPeeringOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ epoch_t epoch = 0;
+ spg_t pgid;
+ eversion_t trim_to;
+
+ epoch_t get_epoch() const { return epoch; }
+ spg_t get_spg() const {
+ return pgid;
+ }
+ epoch_t get_map_epoch() const {
+ return epoch;
+ }
+ epoch_t get_min_epoch() const {
+ return epoch;
+ }
+ PGPeeringEvent *get_event() override {
+ return new PGPeeringEvent(
+ epoch,
+ epoch,
+ MTrim(epoch, get_source().num(), pgid.shard, trim_to));
+ }
+
+ MOSDPGTrim() : MessageInstance(MSG_OSD_PG_TRIM, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDPGTrim(version_t mv, spg_t p, eversion_t tt) :
+ MessageInstance(MSG_OSD_PG_TRIM, HEAD_VERSION, COMPAT_VERSION),
+ epoch(mv), pgid(p), trim_to(tt) { }
+private:
+ ~MOSDPGTrim() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_trim"; }
+ void inner_print(ostream& out) const override {
+ out << trim_to;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(pgid.pgid, payload);
+ encode(trim_to, payload);
+ encode(pgid.shard, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pgid.pgid, p);
+ decode(trim_to, p);
+ decode(pgid.shard, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGUpdateLogMissing.h b/src/messages/MOSDPGUpdateLogMissing.h
new file mode 100644
index 00000000..cbf9485e
--- /dev/null
+++ b/src/messages/MOSDPGUpdateLogMissing.h
@@ -0,0 +1,123 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGUPDATELOGMISSING_H
+#define CEPH_MOSDPGUPDATELOGMISSING_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGUpdateLogMissing : public MessageInstance<MOSDPGUpdateLogMissing, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+
+public:
+ epoch_t map_epoch = 0, min_epoch = 0;
+ spg_t pgid;
+ shard_id_t from;
+ ceph_tid_t rep_tid = 0;
+ mempool::osd_pglog::list<pg_log_entry_t> entries;
+ // piggybacked osd/pg state
+ eversion_t pg_trim_to; // primary->replica: trim to here
+ eversion_t pg_roll_forward_to; // primary->replica: trim rollback info to here
+
+ epoch_t get_epoch() const { return map_epoch; }
+ spg_t get_pgid() const { return pgid; }
+ epoch_t get_query_epoch() const { return map_epoch; }
+ ceph_tid_t get_tid() const { return rep_tid; }
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDPGUpdateLogMissing()
+ : MessageInstance(MSG_OSD_PG_UPDATE_LOG_MISSING, HEAD_VERSION,
+ COMPAT_VERSION) { }
+ MOSDPGUpdateLogMissing(
+ const mempool::osd_pglog::list<pg_log_entry_t> &entries,
+ spg_t pgid,
+ shard_id_t from,
+ epoch_t epoch,
+ epoch_t min_epoch,
+ ceph_tid_t rep_tid,
+ eversion_t pg_trim_to,
+ eversion_t pg_roll_forward_to)
+ : MessageInstance(MSG_OSD_PG_UPDATE_LOG_MISSING, HEAD_VERSION,
+ COMPAT_VERSION),
+ map_epoch(epoch),
+ min_epoch(min_epoch),
+ pgid(pgid),
+ from(from),
+ rep_tid(rep_tid),
+ entries(entries),
+ pg_trim_to(pg_trim_to),
+ pg_roll_forward_to(pg_roll_forward_to)
+ {}
+
+private:
+ ~MOSDPGUpdateLogMissing() override {}
+
+public:
+ std::string_view get_type_name() const override { return "PGUpdateLogMissing"; }
+ void print(ostream& out) const override {
+ out << "pg_update_log_missing(" << pgid << " epoch " << map_epoch
+ << "/" << min_epoch
+ << " rep_tid " << rep_tid
+ << " entries " << entries
+ << " trim_to " << pg_trim_to
+ << " roll_forward_to " << pg_roll_forward_to
+ << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(map_epoch, payload);
+ encode(pgid, payload);
+ encode(from, payload);
+ encode(rep_tid, payload);
+ encode(entries, payload);
+ encode(min_epoch, payload);
+ encode(pg_trim_to, payload);
+ encode(pg_roll_forward_to, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(map_epoch, p);
+ decode(pgid, p);
+ decode(from, p);
+ decode(rep_tid, p);
+ decode(entries, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ if (header.version >= 3) {
+ decode(pg_trim_to, p);
+ decode(pg_roll_forward_to, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPGUpdateLogMissingReply.h b/src/messages/MOSDPGUpdateLogMissingReply.h
new file mode 100644
index 00000000..8d7050f2
--- /dev/null
+++ b/src/messages/MOSDPGUpdateLogMissingReply.h
@@ -0,0 +1,117 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGUPDATELOGMISSINGREPLY_H
+#define CEPH_MOSDPGUPDATELOGMISSINGREPLY_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGUpdateLogMissingReply : public MessageInstance<MOSDPGUpdateLogMissingReply, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+
+public:
+ epoch_t map_epoch = 0, min_epoch = 0;
+ spg_t pgid;
+ shard_id_t from;
+ ceph_tid_t rep_tid = 0;
+ // piggybacked osd state
+ eversion_t last_complete_ondisk;
+
+ epoch_t get_epoch() const { return map_epoch; }
+ spg_t get_pgid() const { return pgid; }
+ epoch_t get_query_epoch() const { return map_epoch; }
+ ceph_tid_t get_tid() const { return rep_tid; }
+ pg_shard_t get_from() const {
+ return pg_shard_t(get_source().num(), from);
+ }
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDPGUpdateLogMissingReply()
+ : MessageInstance(
+ MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY,
+ HEAD_VERSION,
+ COMPAT_VERSION)
+ {}
+ MOSDPGUpdateLogMissingReply(
+ spg_t pgid,
+ shard_id_t from,
+ epoch_t epoch,
+ epoch_t min_epoch,
+ ceph_tid_t rep_tid,
+ eversion_t last_complete_ondisk)
+ : MessageInstance(
+ MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY,
+ HEAD_VERSION,
+ COMPAT_VERSION),
+ map_epoch(epoch),
+ min_epoch(min_epoch),
+ pgid(pgid),
+ from(from),
+ rep_tid(rep_tid),
+ last_complete_ondisk(last_complete_ondisk)
+ {}
+
+private:
+ ~MOSDPGUpdateLogMissingReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "PGUpdateLogMissingReply"; }
+ void print(ostream& out) const override {
+ out << "pg_update_log_missing_reply(" << pgid << " epoch " << map_epoch
+ << "/" << min_epoch
+ << " rep_tid " << rep_tid
+ << " lcod " << last_complete_ondisk << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(map_epoch, payload);
+ encode(pgid, payload);
+ encode(from, payload);
+ encode(rep_tid, payload);
+ encode(min_epoch, payload);
+ encode(last_complete_ondisk, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(map_epoch, p);
+ decode(pgid, p);
+ decode(from, p);
+ decode(rep_tid, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ if (header.version >= 3) {
+ decode(last_complete_ondisk, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDPeeringOp.h b/src/messages/MOSDPeeringOp.h
new file mode 100644
index 00000000..25487488
--- /dev/null
+++ b/src/messages/MOSDPeeringOp.h
@@ -0,0 +1,28 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+#include "osd/osd_types.h"
+#include "osd/PGPeeringEvent.h"
+
+class MOSDPeeringOp : public MessageSubType<MOSDPeeringOp> {
+public:
+
+template<typename... Args>
+ MOSDPeeringOp(Args&&... args) : MessageSubType(std::forward<Args>(args)...) {}
+
+ void print(ostream& out) const override final {
+ out << get_type_name() << "("
+ << get_spg() << " ";
+ inner_print(out);
+ out << " e" << get_map_epoch() << "/" << get_min_epoch() << ")";
+ }
+
+ virtual spg_t get_spg() const = 0;
+ virtual epoch_t get_map_epoch() const = 0;
+ virtual epoch_t get_min_epoch() const = 0;
+ virtual PGPeeringEvent *get_event() = 0;
+ virtual void inner_print(ostream& out) const = 0;
+};
diff --git a/src/messages/MOSDPing.h b/src/messages/MOSDPing.h
new file mode 100644
index 00000000..6a2693a0
--- /dev/null
+++ b/src/messages/MOSDPing.h
@@ -0,0 +1,130 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+/**
+ * This is used to send pings between daemons (so far, the OSDs) for
+ * heartbeat purposes. We include a timestamp and distinguish between
+ * outgoing pings and responses to those. If you set the
+ * min_message in the constructor, the message will inflate itself
+ * to the specified size -- this is good for dealing with network
+ * issues with jumbo frames. See http://tracker.ceph.com/issues/20087
+ *
+ */
+
+#ifndef CEPH_MOSDPING_H
+#define CEPH_MOSDPING_H
+
+#include "common/Clock.h"
+
+#include "msg/Message.h"
+#include "osd/osd_types.h"
+
+
+class MOSDPing : public MessageInstance<MOSDPing> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 4;
+
+ public:
+ enum {
+ HEARTBEAT = 0,
+ START_HEARTBEAT = 1,
+ YOU_DIED = 2,
+ STOP_HEARTBEAT = 3,
+ PING = 4,
+ PING_REPLY = 5,
+ };
+ const char *get_op_name(int op) const {
+ switch (op) {
+ case HEARTBEAT: return "heartbeat";
+ case START_HEARTBEAT: return "start_heartbeat";
+ case STOP_HEARTBEAT: return "stop_heartbeat";
+ case YOU_DIED: return "you_died";
+ case PING: return "ping";
+ case PING_REPLY: return "ping_reply";
+ default: return "???";
+ }
+ }
+
+ uuid_d fsid;
+ epoch_t map_epoch = 0;
+ __u8 op = 0;
+ utime_t stamp;
+ uint32_t min_message_size;
+
+ MOSDPing(const uuid_d& f, epoch_t e, __u8 o, utime_t s, uint32_t min_message)
+ : MessageInstance(MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), map_epoch(e), op(o), stamp(s), min_message_size(min_message)
+ { }
+ MOSDPing()
+ : MessageInstance(MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION), min_message_size(0)
+ {}
+private:
+ ~MOSDPing() override {}
+
+public:
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ decode(stamp, p);
+
+ int payload_mid_length = p.get_off();
+ uint32_t size;
+ decode(size, p);
+ p.advance(size);
+ min_message_size = size + payload_mid_length;
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(fsid, payload);
+ encode(map_epoch, payload);
+ encode(op, payload);
+ encode(stamp, payload);
+
+ size_t s = 0;
+ if (min_message_size > payload.length()) {
+ s = min_message_size - payload.length();
+ }
+ encode((uint32_t)s, payload);
+ if (s) {
+ // this should be big enough for normal min_message padding sizes. since
+ // we are targeting jumbo ethernet frames around 9000 bytes, 16k should
+ // be more than sufficient! the compiler will statically zero this so
+ // that at runtime we are only adding a bufferptr reference to it.
+ static char zeros[16384] = {};
+ while (s > sizeof(zeros)) {
+ payload.append(buffer::create_static(sizeof(zeros), zeros));
+ s -= sizeof(zeros);
+ }
+ if (s) {
+ payload.append(buffer::create_static(s, zeros));
+ }
+ }
+ }
+
+ std::string_view get_type_name() const override { return "osd_ping"; }
+ void print(ostream& out) const override {
+ out << "osd_ping(" << get_op_name(op)
+ << " e" << map_epoch
+ << " stamp " << stamp
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDRepOp.h b/src/messages/MOSDRepOp.h
new file mode 100644
index 00000000..9d087f39
--- /dev/null
+++ b/src/messages/MOSDRepOp.h
@@ -0,0 +1,180 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDREPOP_H
+#define CEPH_MOSDREPOP_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * OSD sub op - for internal ops on pobjects between primary and replicas(/stripes/whatever)
+ */
+
+class MOSDRepOp : public MessageInstance<MOSDRepOp, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ epoch_t map_epoch, min_epoch;
+
+ // metadata from original request
+ osd_reqid_t reqid;
+
+ spg_t pgid;
+
+ bufferlist::const_iterator p;
+ // Decoding flags. Decoding is only needed for messages caught by pipe reader.
+ bool final_decode_needed;
+
+ // subop
+ pg_shard_t from;
+ hobject_t poid;
+
+ __u8 acks_wanted;
+
+ // transaction to exec
+ bufferlist logbl;
+ pg_stat_t pg_stats;
+
+ // subop metadata
+ eversion_t version;
+
+ // piggybacked osd/og state
+ eversion_t pg_trim_to; // primary->replica: trim to here
+ eversion_t pg_roll_forward_to; // primary->replica: trim rollback
+ // info to here
+
+ hobject_t new_temp_oid; ///< new temp object that we must now start tracking
+ hobject_t discard_temp_oid; ///< previously used temp object that we can now stop tracking
+
+ /// non-empty if this transaction involves a hit_set history update
+ boost::optional<pg_hit_set_history_t> updated_hit_set_history;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ int get_cost() const override {
+ return data.length();
+ }
+
+ void decode_payload() override {
+ p = payload.cbegin();
+ // split to partial and final
+ decode(map_epoch, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ decode_trace(p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ decode(reqid, p);
+ decode(pgid, p);
+ }
+
+ void finish_decode() {
+ if (!final_decode_needed)
+ return; // Message is already final decoded
+ decode(poid, p);
+
+ decode(acks_wanted, p);
+ decode(version, p);
+ decode(logbl, p);
+ decode(pg_stats, p);
+ decode(pg_trim_to, p);
+
+
+ decode(new_temp_oid, p);
+ decode(discard_temp_oid, p);
+
+ decode(from, p);
+ decode(updated_hit_set_history, p);
+ decode(pg_roll_forward_to, p);
+ final_decode_needed = false;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(map_epoch, payload);
+ if (HAVE_FEATURE(features, SERVER_LUMINOUS)) {
+ header.version = HEAD_VERSION;
+ encode(min_epoch, payload);
+ encode_trace(payload, features);
+ } else {
+ header.version = 1;
+ }
+ encode(reqid, payload);
+ encode(pgid, payload);
+ encode(poid, payload);
+
+ encode(acks_wanted, payload);
+ encode(version, payload);
+ encode(logbl, payload);
+ encode(pg_stats, payload);
+ encode(pg_trim_to, payload);
+ encode(new_temp_oid, payload);
+ encode(discard_temp_oid, payload);
+ encode(from, payload);
+ encode(updated_hit_set_history, payload);
+ encode(pg_roll_forward_to, payload);
+ }
+
+ MOSDRepOp()
+ : MessageInstance(MSG_OSD_REPOP, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(0),
+ final_decode_needed(true), acks_wanted (0) {}
+ MOSDRepOp(osd_reqid_t r, pg_shard_t from,
+ spg_t p, const hobject_t& po, int aw,
+ epoch_t mape, epoch_t min_epoch, ceph_tid_t rtid, eversion_t v)
+ : MessageInstance(MSG_OSD_REPOP, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(mape),
+ min_epoch(min_epoch),
+ reqid(r),
+ pgid(p),
+ final_decode_needed(false),
+ from(from),
+ poid(po),
+ acks_wanted(aw),
+ version(v) {
+ set_tid(rtid);
+ }
+private:
+ ~MOSDRepOp() override {}
+
+public:
+ std::string_view get_type_name() const override { return "osd_repop"; }
+ void print(ostream& out) const override {
+ out << "osd_repop(" << reqid
+ << " " << pgid << " e" << map_epoch << "/" << min_epoch;
+ if (!final_decode_needed) {
+ out << " " << poid << " v " << version;
+ if (updated_hit_set_history)
+ out << ", has_updated_hit_set_history";
+ }
+ out << ")";
+ }
+};
+
+
+#endif
diff --git a/src/messages/MOSDRepOpReply.h b/src/messages/MOSDRepOpReply.h
new file mode 100644
index 00000000..9ca3a54f
--- /dev/null
+++ b/src/messages/MOSDRepOpReply.h
@@ -0,0 +1,161 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDREPOPREPLY_H
+#define CEPH_MOSDREPOPREPLY_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * OSD Client Subop reply
+ *
+ * oid - object id
+ * op - OSD_OP_DELETE, etc.
+ *
+ */
+
+class MOSDRepOpReply : public MessageInstance<MOSDRepOpReply, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ epoch_t map_epoch, min_epoch;
+
+ // subop metadata
+ osd_reqid_t reqid;
+ pg_shard_t from;
+ spg_t pgid;
+
+ // result
+ __u8 ack_type;
+ int32_t result;
+
+ // piggybacked osd state
+ eversion_t last_complete_ondisk;
+
+ bufferlist::const_iterator p;
+ // Decoding flags. Decoding is only needed for messages caught by pipe reader.
+ bool final_decode_needed;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ void decode_payload() override {
+ p = payload.cbegin();
+ decode(map_epoch, p);
+ if (header.version >= 2) {
+ decode(min_epoch, p);
+ decode_trace(p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ decode(reqid, p);
+ decode(pgid, p);
+ }
+
+ void finish_decode() {
+ if (!final_decode_needed)
+ return; // Message is already final decoded
+ decode(ack_type, p);
+ decode(result, p);
+ decode(last_complete_ondisk, p);
+
+ decode(from, p);
+ final_decode_needed = false;
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(map_epoch, payload);
+ if (HAVE_FEATURE(features, SERVER_LUMINOUS)) {
+ header.version = HEAD_VERSION;
+ encode(min_epoch, payload);
+ encode_trace(payload, features);
+ } else {
+ header.version = 1;
+ }
+ encode(reqid, payload);
+ encode(pgid, payload);
+ encode(ack_type, payload);
+ encode(result, payload);
+ encode(last_complete_ondisk, payload);
+ encode(from, payload);
+ }
+
+ spg_t get_pg() { return pgid; }
+
+ int get_ack_type() { return ack_type; }
+ bool is_ondisk() { return ack_type & CEPH_OSD_FLAG_ONDISK; }
+ bool is_onnvram() { return ack_type & CEPH_OSD_FLAG_ONNVRAM; }
+
+ int get_result() { return result; }
+
+ void set_last_complete_ondisk(eversion_t v) { last_complete_ondisk = v; }
+ eversion_t get_last_complete_ondisk() const { return last_complete_ondisk; }
+
+public:
+ MOSDRepOpReply(
+ const MOSDRepOp *req, pg_shard_t from, int result_, epoch_t e, epoch_t mine,
+ int at) :
+ MessageInstance(MSG_OSD_REPOPREPLY, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(e),
+ min_epoch(mine),
+ reqid(req->reqid),
+ from(from),
+ pgid(req->pgid.pgid, req->from.shard),
+ ack_type(at),
+ result(result_),
+ final_decode_needed(false) {
+ set_tid(req->get_tid());
+ }
+ MOSDRepOpReply()
+ : MessageInstance(MSG_OSD_REPOPREPLY, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(0),
+ min_epoch(0),
+ ack_type(0), result(0),
+ final_decode_needed(true) {}
+private:
+ ~MOSDRepOpReply() override {}
+
+public:
+ std::string_view get_type_name() const override { return "osd_repop_reply"; }
+
+ void print(ostream& out) const override {
+ out << "osd_repop_reply(" << reqid
+ << " " << pgid << " e" << map_epoch << "/" << min_epoch;
+ if (!final_decode_needed) {
+ if (ack_type & CEPH_OSD_FLAG_ONDISK)
+ out << " ondisk";
+ if (ack_type & CEPH_OSD_FLAG_ONNVRAM)
+ out << " onnvram";
+ if (ack_type & CEPH_OSD_FLAG_ACK)
+ out << " ack";
+ out << ", result = " << result;
+ }
+ out << ")";
+ }
+
+};
+
+
+#endif
diff --git a/src/messages/MOSDRepScrub.h b/src/messages/MOSDRepScrub.h
new file mode 100644
index 00000000..40867bed
--- /dev/null
+++ b/src/messages/MOSDRepScrub.h
@@ -0,0 +1,143 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDREPSCRUB_H
+#define CEPH_MOSDREPSCRUB_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * instruct an OSD initiate a replica scrub on a specific PG
+ */
+
+class MOSDRepScrub : public MessageInstance<MOSDRepScrub, MOSDFastDispatchOp> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 9;
+ static constexpr int COMPAT_VERSION = 6;
+
+ spg_t pgid; // PG to scrub
+ eversion_t scrub_from; // only scrub log entries after scrub_from
+ eversion_t scrub_to; // last_update_applied when message sent
+ epoch_t map_epoch = 0, min_epoch = 0;
+ bool chunky; // true for chunky scrubs
+ hobject_t start; // lower bound of scrub, inclusive
+ hobject_t end; // upper bound of scrub, exclusive
+ bool deep; // true if scrub should be deep
+ bool allow_preemption = false;
+ int32_t priority = 0;
+ bool high_priority = false;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDRepScrub()
+ : MessageInstance(MSG_OSD_REP_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ chunky(false),
+ deep(false) { }
+
+ MOSDRepScrub(spg_t pgid, eversion_t scrub_to, epoch_t map_epoch, epoch_t min_epoch,
+ hobject_t start, hobject_t end, bool deep,
+ bool preemption, int prio, bool highprio)
+ : MessageInstance(MSG_OSD_REP_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid),
+ scrub_to(scrub_to),
+ map_epoch(map_epoch),
+ min_epoch(min_epoch),
+ chunky(true),
+ start(start),
+ end(end),
+ deep(deep),
+ allow_preemption(preemption),
+ priority(prio),
+ high_priority(highprio) { }
+
+
+private:
+ ~MOSDRepScrub() override {}
+
+public:
+ std::string_view get_type_name() const override { return "replica scrub"; }
+ void print(ostream& out) const override {
+ out << "replica_scrub(pg: " << pgid
+ << ",from:" << scrub_from
+ << ",to:" << scrub_to
+ << ",epoch:" << map_epoch << "/" << min_epoch
+ << ",start:" << start << ",end:" << end
+ << ",chunky:" << chunky
+ << ",deep:" << deep
+ << ",version:" << header.version
+ << ",allow_preemption:" << (int)allow_preemption
+ << ",priority=" << priority
+ << (high_priority ? " (high)":"")
+ << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid.pgid, payload);
+ encode(scrub_from, payload);
+ encode(scrub_to, payload);
+ encode(map_epoch, payload);
+ encode(chunky, payload);
+ encode(start, payload);
+ encode(end, payload);
+ encode(deep, payload);
+ encode(pgid.shard, payload);
+ encode((uint32_t)-1, payload); // seed
+ encode(min_epoch, payload);
+ encode(allow_preemption, payload);
+ encode(priority, payload);
+ encode(high_priority, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(scrub_from, p);
+ decode(scrub_to, p);
+ decode(map_epoch, p);
+ decode(chunky, p);
+ decode(start, p);
+ decode(end, p);
+ decode(deep, p);
+ decode(pgid.shard, p);
+ {
+ uint32_t seed;
+ decode(seed, p);
+ }
+ if (header.version >= 7) {
+ decode(min_epoch, p);
+ } else {
+ min_epoch = map_epoch;
+ }
+ if (header.version >= 8) {
+ decode(allow_preemption, p);
+ }
+ if (header.version >= 9) {
+ decode(priority, p);
+ decode(high_priority, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDRepScrubMap.h b/src/messages/MOSDRepScrubMap.h
new file mode 100644
index 00000000..984ebb4f
--- /dev/null
+++ b/src/messages/MOSDRepScrubMap.h
@@ -0,0 +1,83 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2017 Sage Weil <sage@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDREPSCRUBMAP_H
+#define CEPH_MOSDREPSCRUBMAP_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * pass a ScrubMap from a shard back to the primary
+ */
+
+class MOSDRepScrubMap : public MessageInstance<MOSDRepScrubMap, MOSDFastDispatchOp> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ spg_t pgid; // primary spg_t
+ epoch_t map_epoch = 0;
+ pg_shard_t from; // whose scrubmap this is
+ bufferlist scrub_map_bl;
+ bool preempted = false;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDRepScrubMap()
+ : MessageInstance(MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION) {}
+
+ MOSDRepScrubMap(spg_t pgid, epoch_t map_epoch, pg_shard_t from)
+ : MessageInstance(MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid),
+ map_epoch(map_epoch),
+ from(from) {}
+
+private:
+ ~MOSDRepScrubMap() {}
+
+public:
+ std::string_view get_type_name() const override { return "rep_scrubmap"; }
+ void print(ostream& out) const override {
+ out << "rep_scrubmap(" << pgid << " e" << map_epoch
+ << " from shard " << from
+ << (preempted ? " PREEMPTED":"") << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(from, payload);
+ encode(preempted, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(from, p);
+ if (header.version >= 2) {
+ decode(preempted, p);
+ }
+ }
+};
+
+
+#endif
diff --git a/src/messages/MOSDScrub.h b/src/messages/MOSDScrub.h
new file mode 100644
index 00000000..8df54670
--- /dev/null
+++ b/src/messages/MOSDScrub.h
@@ -0,0 +1,78 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDSCRUB_H
+#define CEPH_MOSDSCRUB_H
+
+#include "msg/Message.h"
+
+/*
+ * instruct an OSD to scrub some or all pg(s)
+ */
+
+class MOSDScrub : public MessageInstance<MOSDScrub> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+ uuid_d fsid;
+ vector<pg_t> scrub_pgs;
+ bool repair = false;
+ bool deep = false;
+
+ MOSDScrub() : MessageInstance(MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDScrub(const uuid_d& f, bool r, bool d) :
+ MessageInstance(MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), repair(r), deep(d) {}
+ MOSDScrub(const uuid_d& f, vector<pg_t>& pgs, bool r, bool d) :
+ MessageInstance(MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), scrub_pgs(pgs), repair(r), deep(d) {}
+private:
+ ~MOSDScrub() override {}
+
+public:
+ std::string_view get_type_name() const override { return "scrub"; }
+ void print(ostream& out) const override {
+ out << "scrub(";
+ if (scrub_pgs.empty())
+ out << "osd";
+ else
+ out << scrub_pgs;
+ if (repair)
+ out << " repair";
+ if (deep)
+ out << " deep";
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(fsid, payload);
+ encode(scrub_pgs, payload);
+ encode(repair, payload);
+ encode(deep, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(scrub_pgs, p);
+ decode(repair, p);
+ decode(deep, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MOSDScrub2.h b/src/messages/MOSDScrub2.h
new file mode 100644
index 00000000..98fb0f31
--- /dev/null
+++ b/src/messages/MOSDScrub2.h
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+
+/*
+ * instruct an OSD to scrub some or all pg(s)
+ */
+
+class MOSDScrub2 : public MessageInstance<MOSDScrub2> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ uuid_d fsid;
+ epoch_t epoch;
+ vector<spg_t> scrub_pgs;
+ bool repair = false;
+ bool deep = false;
+
+ MOSDScrub2() : MessageInstance(MSG_OSD_SCRUB2, HEAD_VERSION, COMPAT_VERSION) {}
+ MOSDScrub2(const uuid_d& f, epoch_t e, vector<spg_t>& pgs, bool r, bool d) :
+ MessageInstance(MSG_OSD_SCRUB2, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), epoch(e), scrub_pgs(pgs), repair(r), deep(d) {}
+private:
+ ~MOSDScrub2() override {}
+
+public:
+ std::string_view get_type_name() const override { return "scrub2"; }
+ void print(ostream& out) const override {
+ out << "scrub2(" << scrub_pgs;
+ if (repair)
+ out << " repair";
+ if (deep)
+ out << " deep";
+ out << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(fsid, payload);
+ encode(epoch, payload);
+ encode(scrub_pgs, payload);
+ encode(repair, payload);
+ encode(deep, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(epoch, p);
+ decode(scrub_pgs, p);
+ decode(repair, p);
+ decode(deep, p);
+ }
+};
diff --git a/src/messages/MOSDScrubReserve.h b/src/messages/MOSDScrubReserve.h
new file mode 100644
index 00000000..a75796f9
--- /dev/null
+++ b/src/messages/MOSDScrubReserve.h
@@ -0,0 +1,97 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MOSDSCRUBRESERVE_H
+#define CEPH_MOSDSCRUBRESERVE_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDScrubReserve : public MessageInstance<MOSDScrubReserve, MOSDFastDispatchOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ spg_t pgid;
+ epoch_t map_epoch;
+ enum {
+ REQUEST = 0,
+ GRANT = 1,
+ RELEASE = 2,
+ REJECT = 3,
+ };
+ int32_t type;
+ pg_shard_t from;
+
+ epoch_t get_map_epoch() const override {
+ return map_epoch;
+ }
+ spg_t get_spg() const override {
+ return pgid;
+ }
+
+ MOSDScrubReserve()
+ : MessageInstance(MSG_OSD_SCRUB_RESERVE, HEAD_VERSION, COMPAT_VERSION),
+ map_epoch(0), type(-1) {}
+ MOSDScrubReserve(spg_t pgid,
+ epoch_t map_epoch,
+ int type,
+ pg_shard_t from)
+ : MessageInstance(MSG_OSD_SCRUB_RESERVE, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid), map_epoch(map_epoch),
+ type(type), from(from) {}
+
+ std::string_view get_type_name() const {
+ return "MOSDScrubReserve";
+ }
+
+ void print(ostream& out) const {
+ out << "MOSDScrubReserve(" << pgid << " ";
+ switch (type) {
+ case REQUEST:
+ out << "REQUEST ";
+ break;
+ case GRANT:
+ out << "GRANT ";
+ break;
+ case REJECT:
+ out << "REJECT ";
+ break;
+ case RELEASE:
+ out << "RELEASE ";
+ break;
+ }
+ out << "e" << map_epoch << ")";
+ return;
+ }
+
+ void decode_payload() {
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(type, p);
+ decode(from, p);
+ }
+
+ void encode_payload(uint64_t features) {
+ using ceph::encode;
+ encode(pgid, payload);
+ encode(map_epoch, payload);
+ encode(type, payload);
+ encode(from, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MPGStats.h b/src/messages/MPGStats.h
new file mode 100644
index 00000000..e0a299eb
--- /dev/null
+++ b/src/messages/MPGStats.h
@@ -0,0 +1,78 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MPGSTATS_H
+#define CEPH_MPGSTATS_H
+
+#include "osd/osd_types.h"
+#include "messages/PaxosServiceMessage.h"
+
+class MPGStats : public MessageInstance<MPGStats, PaxosServiceMessage> {
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ friend factory;
+
+ uuid_d fsid;
+ map<pg_t, pg_stat_t> pg_stat;
+ osd_stat_t osd_stat;
+ map<int64_t, store_statfs_t> pool_stat;
+ epoch_t epoch = 0;
+ utime_t had_map_for;
+
+ MPGStats() : MessageInstance(MSG_PGSTATS, 0, HEAD_VERSION, COMPAT_VERSION) {}
+ MPGStats(const uuid_d& f, epoch_t e, utime_t had)
+ : MessageInstance(MSG_PGSTATS, 0, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f),
+ epoch(e),
+ had_map_for(had)
+ {}
+
+private:
+ ~MPGStats() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_stats"; }
+ void print(ostream& out) const override {
+ out << "pg_stats(" << pg_stat.size() << " pgs tid " << get_tid() << " v " << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(osd_stat, payload, features);
+ encode(pg_stat, payload);
+ encode(epoch, payload);
+ encode(had_map_for, payload);
+ encode(pool_stat, payload, features);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(osd_stat, p);
+ if (osd_stat.num_osds == 0) {
+ // for the benefit of legacy OSDs who don't set this field
+ osd_stat.num_osds = 1;
+ }
+ decode(pg_stat, p);
+ decode(epoch, p);
+ decode(had_map_for, p);
+ if (header.version >= 2)
+ decode(pool_stat, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MPGStatsAck.h b/src/messages/MPGStatsAck.h
new file mode 100644
index 00000000..5fe78bfc
--- /dev/null
+++ b/src/messages/MPGStatsAck.h
@@ -0,0 +1,47 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MPGSTATSACK_H
+#define CEPH_MPGSTATSACK_H
+
+#include "osd/osd_types.h"
+
+class MPGStatsAck : public MessageInstance<MPGStatsAck> {
+public:
+ friend factory;
+
+ map<pg_t,pair<version_t,epoch_t> > pg_stat;
+
+ MPGStatsAck() : MessageInstance(MSG_PGSTATSACK) {}
+
+private:
+ ~MPGStatsAck() override {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_stats_ack"; }
+ void print(ostream& out) const override {
+ out << "pg_stats_ack(" << pg_stat.size() << " pgs tid " << get_tid() << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pg_stat, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pg_stat, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MPing.h b/src/messages/MPing.h
new file mode 100644
index 00000000..4175a1d5
--- /dev/null
+++ b/src/messages/MPing.h
@@ -0,0 +1,35 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MPING_H
+#define CEPH_MPING_H
+
+#include "msg/Message.h"
+
+class MPing : public MessageInstance<MPing> {
+public:
+ friend factory;
+
+ MPing() : MessageInstance(CEPH_MSG_PING) {}
+private:
+ ~MPing() override {}
+
+public:
+ void decode_payload() override { }
+ void encode_payload(uint64_t features) override { }
+ std::string_view get_type_name() const override { return "ping"; }
+};
+
+#endif
diff --git a/src/messages/MPoolOp.h b/src/messages/MPoolOp.h
new file mode 100644
index 00000000..d13c8771
--- /dev/null
+++ b/src/messages/MPoolOp.h
@@ -0,0 +1,96 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MPOOLOP_H
+#define CEPH_MPOOLOP_H
+
+#include "messages/PaxosServiceMessage.h"
+
+
+class MPoolOp : public MessageInstance<MPoolOp, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ uuid_d fsid;
+ __u32 pool = 0;
+ string name;
+ __u32 op = 0;
+ snapid_t snapid;
+ __s16 crush_rule = 0;
+
+ MPoolOp()
+ : MessageInstance(CEPH_MSG_POOLOP, 0, HEAD_VERSION, COMPAT_VERSION) { }
+ MPoolOp(const uuid_d& f, ceph_tid_t t, int p, string& n, int o, version_t v)
+ : MessageInstance(CEPH_MSG_POOLOP, v, HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), pool(p), name(n), op(o),
+ snapid(0), crush_rule(0) {
+ set_tid(t);
+ }
+
+private:
+ ~MPoolOp() override {}
+
+public:
+ std::string_view get_type_name() const override { return "poolop"; }
+ void print(ostream& out) const override {
+ out << "pool_op(" << ceph_pool_op_name(op) << " pool " << pool
+ << " tid " << get_tid()
+ << " name " << name
+ << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(pool, payload);
+ encode(op, payload);
+ encode((uint64_t)0, payload);
+ encode(snapid, payload);
+ encode(name, payload);
+ __u8 pad = 0;
+ encode(pad, payload); /* for v3->v4 encoding change */
+ encode(crush_rule, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(pool, p);
+ if (header.version < 2)
+ decode(name, p);
+ decode(op, p);
+ uint64_t old_auid;
+ decode(old_auid, p);
+ decode(snapid, p);
+ if (header.version >= 2)
+ decode(name, p);
+
+ if (header.version >= 3) {
+ __u8 pad;
+ decode(pad, p);
+ if (header.version >= 4)
+ decode(crush_rule, p);
+ else
+ crush_rule = pad;
+ } else
+ crush_rule = -1;
+ }
+};
+
+#endif
diff --git a/src/messages/MPoolOpReply.h b/src/messages/MPoolOpReply.h
new file mode 100644
index 00000000..41a6dfbb
--- /dev/null
+++ b/src/messages/MPoolOpReply.h
@@ -0,0 +1,83 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MPOOLOPREPLY_H
+#define CEPH_MPOOLOPREPLY_H
+
+#include "common/errno.h"
+
+class MPoolOpReply : public MessageInstance<MPoolOpReply, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ uuid_d fsid;
+ __u32 replyCode = 0;
+ epoch_t epoch = 0;
+ bufferlist response_data;
+
+ MPoolOpReply() : MessageInstance(CEPH_MSG_POOLOP_REPLY, 0)
+ {}
+ MPoolOpReply( uuid_d& f, ceph_tid_t t, int rc, int e, version_t v) :
+ MessageInstance(CEPH_MSG_POOLOP_REPLY, v),
+ fsid(f),
+ replyCode(rc),
+ epoch(e) {
+ set_tid(t);
+ }
+ MPoolOpReply( uuid_d& f, ceph_tid_t t, int rc, int e, version_t v,
+ bufferlist *blp) :
+ MessageInstance(CEPH_MSG_POOLOP_REPLY, v),
+ fsid(f),
+ replyCode(rc),
+ epoch(e) {
+ set_tid(t);
+ if (blp)
+ response_data.claim(*blp);
+ }
+
+ std::string_view get_type_name() const override { return "poolopreply"; }
+
+ void print(ostream& out) const override {
+ out << "pool_op_reply(tid " << get_tid()
+ << " " << cpp_strerror(-replyCode)
+ << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(replyCode, payload);
+ encode(epoch, payload);
+ if (response_data.length()) {
+ encode(true, payload);
+ encode(response_data, payload);
+ } else
+ encode(false, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(replyCode, p);
+ decode(epoch, p);
+ bool has_response_data;
+ decode(has_response_data, p);
+ if (has_response_data) {
+ decode(response_data, p);
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MRecoveryReserve.h b/src/messages/MRecoveryReserve.h
new file mode 100644
index 00000000..2dc7d6c3
--- /dev/null
+++ b/src/messages/MRecoveryReserve.h
@@ -0,0 +1,130 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MRECOVERY_H
+#define CEPH_MRECOVERY_H
+
+#include "msg/Message.h"
+#include "messages/MOSDPeeringOp.h"
+
+class MRecoveryReserve : public MessageInstance<MRecoveryReserve, MOSDPeeringOp> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 2;
+public:
+ spg_t pgid;
+ epoch_t query_epoch;
+ enum {
+ REQUEST = 0, // primary->replica: please reserve slot
+ GRANT = 1, // replica->primary: ok, i reserved it
+ RELEASE = 2, // primary->replica: release the slot i reserved before
+ REVOKE = 3, // replica->primary: i'm taking back the slot i gave you
+ };
+ uint32_t type;
+ uint32_t priority = 0;
+
+ spg_t get_spg() const {
+ return pgid;
+ }
+ epoch_t get_map_epoch() const {
+ return query_epoch;
+ }
+ epoch_t get_min_epoch() const {
+ return query_epoch;
+ }
+
+ PGPeeringEvent *get_event() override {
+ switch (type) {
+ case REQUEST:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RequestRecoveryPrio(priority));
+ case GRANT:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RemoteRecoveryReserved());
+ case RELEASE:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ RecoveryDone());
+ case REVOKE:
+ return new PGPeeringEvent(
+ query_epoch,
+ query_epoch,
+ DeferRecovery(0.0));
+ default:
+ ceph_abort();
+ }
+ }
+
+ MRecoveryReserve()
+ : MessageInstance(MSG_OSD_RECOVERY_RESERVE, HEAD_VERSION, COMPAT_VERSION),
+ query_epoch(0), type(-1) {}
+ MRecoveryReserve(int type,
+ spg_t pgid,
+ epoch_t query_epoch,
+ unsigned prio = 0)
+ : MessageInstance(MSG_OSD_RECOVERY_RESERVE, HEAD_VERSION, COMPAT_VERSION),
+ pgid(pgid), query_epoch(query_epoch),
+ type(type), priority(prio) {}
+
+ std::string_view get_type_name() const override {
+ return "MRecoveryReserve";
+ }
+
+ void inner_print(ostream& out) const override {
+ switch (type) {
+ case REQUEST:
+ out << "REQUEST";
+ break;
+ case GRANT:
+ out << "GRANT";
+ break;
+ case RELEASE:
+ out << "RELEASE";
+ break;
+ case REVOKE:
+ out << "REVOKE";
+ break;
+ }
+ if (type == REQUEST) out << " prio: " << priority;
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(pgid.pgid, p);
+ decode(query_epoch, p);
+ decode(type, p);
+ decode(pgid.shard, p);
+ if (header.version >= 3) {
+ decode(priority, p);
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(pgid.pgid, payload);
+ encode(query_epoch, payload);
+ encode(type, payload);
+ encode(pgid.shard, payload);
+ encode(priority, payload);
+ }
+};
+
+#endif
diff --git a/src/messages/MRemoveSnaps.h b/src/messages/MRemoveSnaps.h
new file mode 100644
index 00000000..96f1f2df
--- /dev/null
+++ b/src/messages/MRemoveSnaps.h
@@ -0,0 +1,55 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MREMOVESNAPS_H
+#define CEPH_MREMOVESNAPS_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MRemoveSnaps : public MessageInstance<MRemoveSnaps, PaxosServiceMessage> {
+public:
+ friend factory;
+
+ map<int, vector<snapid_t> > snaps;
+
+protected:
+ MRemoveSnaps() :
+ MessageInstance(MSG_REMOVE_SNAPS, 0) { }
+ MRemoveSnaps(map<int, vector<snapid_t> >& s) :
+ MessageInstance(MSG_REMOVE_SNAPS, 0) {
+ snaps.swap(s);
+ }
+ ~MRemoveSnaps() override {}
+
+public:
+ std::string_view get_type_name() const override { return "remove_snaps"; }
+ void print(ostream& out) const override {
+ out << "remove_snaps(" << snaps << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(snaps, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(snaps, p);
+ ceph_assert(p.end());
+ }
+
+};
+
+#endif
diff --git a/src/messages/MRoute.h b/src/messages/MRoute.h
new file mode 100644
index 00000000..d0cf441e
--- /dev/null
+++ b/src/messages/MRoute.h
@@ -0,0 +1,88 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+
+#ifndef CEPH_MROUTE_H
+#define CEPH_MROUTE_H
+
+#include "msg/Message.h"
+#include "include/encoding.h"
+
+class MRoute : public MessageInstance<MRoute> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+
+ uint64_t session_mon_tid;
+ Message *msg;
+ epoch_t send_osdmap_first;
+
+ MRoute() : MessageInstance(MSG_ROUTE, HEAD_VERSION, COMPAT_VERSION),
+ session_mon_tid(0),
+ msg(NULL),
+ send_osdmap_first(0) {}
+ MRoute(uint64_t t, Message *m)
+ : MessageInstance(MSG_ROUTE, HEAD_VERSION, COMPAT_VERSION),
+ session_mon_tid(t),
+ msg(m),
+ send_osdmap_first(0) {}
+private:
+ ~MRoute() override {
+ if (msg)
+ msg->put();
+ }
+
+public:
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(session_mon_tid, p);
+ entity_inst_t dest_unused;
+ decode(dest_unused, p);
+ bool m;
+ decode(m, p);
+ if (m)
+ msg = decode_message(NULL, 0, p);
+ decode(send_osdmap_first, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(session_mon_tid, payload);
+ entity_inst_t dest_unused;
+ encode(dest_unused, payload, features);
+ bool m = msg ? true : false;
+ encode(m, payload);
+ if (msg)
+ encode_message(msg, features, payload);
+ encode(send_osdmap_first, payload);
+ }
+
+ std::string_view get_type_name() const override { return "route"; }
+ void print(ostream& o) const override {
+ if (msg)
+ o << "route(" << *msg;
+ else
+ o << "route(no-reply";
+ if (send_osdmap_first)
+ o << " send_osdmap_first " << send_osdmap_first;
+ if (session_mon_tid)
+ o << " tid " << session_mon_tid << ")";
+ else
+ o << " tid (none)";
+ }
+};
+
+#endif
diff --git a/src/messages/MServiceMap.h b/src/messages/MServiceMap.h
new file mode 100644
index 00000000..275acfcd
--- /dev/null
+++ b/src/messages/MServiceMap.h
@@ -0,0 +1,37 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "msg/Message.h"
+#include "mgr/ServiceMap.h"
+
+class MServiceMap : public MessageInstance<MServiceMap> {
+public:
+ friend factory;
+
+ ServiceMap service_map;
+
+ MServiceMap() : MessageInstance(MSG_SERVICE_MAP) { }
+ explicit MServiceMap(const ServiceMap& sm)
+ : MessageInstance(MSG_SERVICE_MAP),
+ service_map(sm) {
+ }
+private:
+ ~MServiceMap() override {}
+
+public:
+ std::string_view get_type_name() const override { return "service_map"; }
+ void print(ostream& out) const override {
+ out << "service_map(e" << service_map.epoch << " "
+ << service_map.services.size() << " svc)";
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(service_map, payload, features);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(service_map, p);
+ }
+};
diff --git a/src/messages/MStatfs.h b/src/messages/MStatfs.h
new file mode 100644
index 00000000..f68d6728
--- /dev/null
+++ b/src/messages/MStatfs.h
@@ -0,0 +1,69 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MSTATFS_H
+#define CEPH_MSTATFS_H
+
+#include <sys/statvfs.h> /* or <sys/statfs.h> */
+#include "messages/PaxosServiceMessage.h"
+
+class MStatfs : public MessageInstance<MStatfs, PaxosServiceMessage> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ uuid_d fsid;
+ boost::optional<int64_t> data_pool;
+
+ MStatfs() : MessageInstance(CEPH_MSG_STATFS, 0, HEAD_VERSION, COMPAT_VERSION) {}
+ MStatfs(const uuid_d& f, ceph_tid_t t, boost::optional<int64_t> _data_pool,
+ version_t v) : MessageInstance(CEPH_MSG_STATFS, v,
+ HEAD_VERSION, COMPAT_VERSION),
+ fsid(f), data_pool(_data_pool) {
+ set_tid(t);
+ }
+
+private:
+ ~MStatfs() override {}
+
+public:
+ std::string_view get_type_name() const override { return "statfs"; }
+ void print(ostream& out) const override {
+ out << "statfs(" << get_tid() << " pool "
+ << (data_pool ? *data_pool : -1) << " v" << version << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(fsid, payload);
+ encode(data_pool, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ if (header.version >= 2) {
+ decode(data_pool, p);
+ } else {
+ data_pool = boost::optional<int64_t> ();
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MStatfsReply.h b/src/messages/MStatfsReply.h
new file mode 100644
index 00000000..4dd6b40e
--- /dev/null
+++ b/src/messages/MStatfsReply.h
@@ -0,0 +1,47 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MSTATFSREPLY_H
+#define CEPH_MSTATFSREPLY_H
+
+class MStatfsReply : public MessageInstance<MStatfsReply> {
+public:
+ friend factory;
+
+ struct ceph_mon_statfs_reply h{};
+
+ MStatfsReply() : MessageInstance(CEPH_MSG_STATFS_REPLY) {}
+ MStatfsReply(uuid_d &f, ceph_tid_t t, epoch_t epoch) : MessageInstance(CEPH_MSG_STATFS_REPLY) {
+ memcpy(&h.fsid, f.bytes(), sizeof(h.fsid));
+ header.tid = t;
+ h.version = epoch;
+ }
+
+ std::string_view get_type_name() const override { return "statfs_reply"; }
+ void print(ostream& out) const override {
+ out << "statfs_reply(" << header.tid << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(h, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(h, p);
+ }
+};
+
+#endif
diff --git a/src/messages/MTimeCheck.h b/src/messages/MTimeCheck.h
new file mode 100644
index 00000000..994c6dd8
--- /dev/null
+++ b/src/messages/MTimeCheck.h
@@ -0,0 +1,90 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2012 Inktank, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MTIMECHECK_H
+#define CEPH_MTIMECHECK_H
+
+class MTimeCheck : public MessageInstance<MTimeCheck> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+
+ enum {
+ OP_PING = 1,
+ OP_PONG = 2,
+ OP_REPORT = 3,
+ };
+
+ int op = 0;
+ version_t epoch = 0;
+ version_t round = 0;
+
+ utime_t timestamp;
+ map<entity_inst_t, double> skews;
+ map<entity_inst_t, double> latencies;
+
+ MTimeCheck() : MessageInstance(MSG_TIMECHECK, HEAD_VERSION) { }
+ MTimeCheck(int op) :
+ MessageInstance(MSG_TIMECHECK, HEAD_VERSION),
+ op(op)
+ { }
+
+private:
+ ~MTimeCheck() override { }
+
+public:
+ std::string_view get_type_name() const override { return "time_check"; }
+ const char *get_op_name() const {
+ switch (op) {
+ case OP_PING: return "ping";
+ case OP_PONG: return "pong";
+ case OP_REPORT: return "report";
+ }
+ return "???";
+ }
+ void print(ostream &o) const override {
+ o << "time_check( " << get_op_name()
+ << " e " << epoch << " r " << round;
+ if (op == OP_PONG) {
+ o << " ts " << timestamp;
+ } else if (op == OP_REPORT) {
+ o << " #skews " << skews.size()
+ << " #latencies " << latencies.size();
+ }
+ o << " )";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(epoch, p);
+ decode(round, p);
+ decode(timestamp, p);
+ decode(skews, p);
+ decode(latencies, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(epoch, payload);
+ encode(round, payload);
+ encode(timestamp, payload);
+ encode(skews, payload, features);
+ encode(latencies, payload, features);
+ }
+};
+
+#endif /* CEPH_MTIMECHECK_H */
diff --git a/src/messages/MTimeCheck2.h b/src/messages/MTimeCheck2.h
new file mode 100644
index 00000000..1d93fcc9
--- /dev/null
+++ b/src/messages/MTimeCheck2.h
@@ -0,0 +1,88 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2012 Inktank, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#pragma once
+
+class MTimeCheck2 : public MessageInstance<MTimeCheck2> {
+public:
+ friend factory;
+
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ enum {
+ OP_PING = 1,
+ OP_PONG = 2,
+ OP_REPORT = 3,
+ };
+
+ int op = 0;
+ version_t epoch = 0;
+ version_t round = 0;
+
+ utime_t timestamp;
+ map<int, double> skews;
+ map<int, double> latencies;
+
+ MTimeCheck2() : MessageInstance(MSG_TIMECHECK2, HEAD_VERSION, COMPAT_VERSION) { }
+ MTimeCheck2(int op) :
+ MessageInstance(MSG_TIMECHECK2, HEAD_VERSION, COMPAT_VERSION),
+ op(op)
+ { }
+
+private:
+ ~MTimeCheck2() override { }
+
+public:
+ std::string_view get_type_name() const override { return "time_check2"; }
+ const char *get_op_name() const {
+ switch (op) {
+ case OP_PING: return "ping";
+ case OP_PONG: return "pong";
+ case OP_REPORT: return "report";
+ }
+ return "???";
+ }
+ void print(ostream &o) const override {
+ o << "time_check( " << get_op_name()
+ << " e " << epoch << " r " << round;
+ if (op == OP_PONG) {
+ o << " ts " << timestamp;
+ } else if (op == OP_REPORT) {
+ o << " #skews " << skews.size()
+ << " #latencies " << latencies.size();
+ }
+ o << " )";
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(epoch, p);
+ decode(round, p);
+ decode(timestamp, p);
+ decode(skews, p);
+ decode(latencies, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(epoch, payload);
+ encode(round, payload);
+ encode(timestamp, payload);
+ encode(skews, payload, features);
+ encode(latencies, payload, features);
+ }
+};
diff --git a/src/messages/MWatchNotify.h b/src/messages/MWatchNotify.h
new file mode 100644
index 00000000..b3a46d3e
--- /dev/null
+++ b/src/messages/MWatchNotify.h
@@ -0,0 +1,96 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MWATCHNOTIFY_H
+#define CEPH_MWATCHNOTIFY_H
+
+#include "msg/Message.h"
+
+
+class MWatchNotify : public MessageInstance<MWatchNotify> {
+public:
+ friend factory;
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+ public:
+ uint64_t cookie; ///< client unique id for this watch or notify
+ uint64_t ver; ///< unused
+ uint64_t notify_id; ///< osd unique id for a notify notification
+ uint8_t opcode; ///< CEPH_WATCH_EVENT_*
+ bufferlist bl; ///< notify payload (osd->client)
+ errorcode32_t return_code; ///< notify result (osd->client)
+ uint64_t notifier_gid; ///< who sent the notify
+
+ MWatchNotify()
+ : MessageInstance(CEPH_MSG_WATCH_NOTIFY, HEAD_VERSION, COMPAT_VERSION) { }
+ MWatchNotify(uint64_t c, uint64_t v, uint64_t i, uint8_t o, bufferlist b)
+ : MessageInstance(CEPH_MSG_WATCH_NOTIFY, HEAD_VERSION, COMPAT_VERSION),
+ cookie(c),
+ ver(v),
+ notify_id(i),
+ opcode(o),
+ bl(b),
+ return_code(0),
+ notifier_gid(0) { }
+private:
+ ~MWatchNotify() override {}
+
+public:
+ void decode_payload() override {
+ uint8_t msg_ver;
+ auto p = payload.cbegin();
+ decode(msg_ver, p);
+ decode(opcode, p);
+ decode(cookie, p);
+ decode(ver, p);
+ decode(notify_id, p);
+ if (msg_ver >= 1)
+ decode(bl, p);
+ if (header.version >= 2)
+ decode(return_code, p);
+ else
+ return_code = 0;
+ if (header.version >= 3)
+ decode(notifier_gid, p);
+ else
+ notifier_gid = 0;
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ uint8_t msg_ver = 1;
+ encode(msg_ver, payload);
+ encode(opcode, payload);
+ encode(cookie, payload);
+ encode(ver, payload);
+ encode(notify_id, payload);
+ encode(bl, payload);
+ encode(return_code, payload);
+ encode(notifier_gid, payload);
+ }
+
+ std::string_view get_type_name() const override { return "watch-notify"; }
+ void print(ostream& out) const override {
+ out << "watch-notify("
+ << ceph_watch_event_name(opcode) << " (" << (int)opcode << ")"
+ << " cookie " << cookie
+ << " notify " << notify_id
+ << " ret " << return_code
+ << ")";
+ }
+};
+
+#endif
diff --git a/src/messages/PaxosServiceMessage.h b/src/messages/PaxosServiceMessage.h
new file mode 100644
index 00000000..5b0b1bf5
--- /dev/null
+++ b/src/messages/PaxosServiceMessage.h
@@ -0,0 +1,56 @@
+#ifndef CEPH_PAXOSSERVICEMESSAGE_H
+#define CEPH_PAXOSSERVICEMESSAGE_H
+
+#include "msg/Message.h"
+#include "mon/Session.h"
+
+class PaxosServiceMessage : public MessageSubType<PaxosServiceMessage> {
+public:
+ version_t version;
+ __s16 deprecated_session_mon;
+ uint64_t deprecated_session_mon_tid;
+
+ // track which epoch the leader received a forwarded request in, so we can
+ // discard forwarded requests appropriately on election boundaries.
+ epoch_t rx_election_epoch;
+
+ PaxosServiceMessage()
+ : MessageSubType(MSG_PAXOS),
+ version(0), deprecated_session_mon(-1), deprecated_session_mon_tid(0),
+ rx_election_epoch(0) { }
+ PaxosServiceMessage(int type, version_t v, int enc_version=1, int compat_enc_version=0)
+ : MessageSubType(type, enc_version, compat_enc_version),
+ version(v), deprecated_session_mon(-1), deprecated_session_mon_tid(0),
+ rx_election_epoch(0) { }
+ protected:
+ virtual ~PaxosServiceMessage() override {}
+
+ public:
+ void paxos_encode() {
+ using ceph::encode;
+ encode(version, payload);
+ encode(deprecated_session_mon, payload);
+ encode(deprecated_session_mon_tid, payload);
+ }
+
+ void paxos_decode(bufferlist::const_iterator& p ) {
+ decode(version, p);
+ decode(deprecated_session_mon, p);
+ decode(deprecated_session_mon_tid, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ ceph_abort();
+ paxos_encode();
+ }
+
+ void decode_payload() override {
+ ceph_abort();
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ }
+
+ std::string_view get_type_name() const override { return "PaxosServiceMessage"; }
+};
+
+#endif