summaryrefslogtreecommitdiffstats
path: root/src/messages
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages')
-rw-r--r--src/messages/MAuth.h66
-rw-r--r--src/messages/MAuthReply.h68
-rw-r--r--src/messages/MBackfillReserve.h180
-rw-r--r--src/messages/MCacheExpire.h112
-rw-r--r--src/messages/MClientCapRelease.h67
-rw-r--r--src/messages/MClientCaps.h349
-rw-r--r--src/messages/MClientLease.h95
-rw-r--r--src/messages/MClientMetrics.h54
-rw-r--r--src/messages/MClientQuota.h54
-rw-r--r--src/messages/MClientReclaim.h66
-rw-r--r--src/messages/MClientReclaimReply.h72
-rw-r--r--src/messages/MClientReconnect.h176
-rw-r--r--src/messages/MClientReply.h405
-rw-r--r--src/messages/MClientRequest.h329
-rw-r--r--src/messages/MClientRequestForward.h72
-rw-r--r--src/messages/MClientSession.h106
-rw-r--r--src/messages/MClientSnap.h71
-rw-r--r--src/messages/MCommand.h60
-rw-r--r--src/messages/MCommandReply.h59
-rw-r--r--src/messages/MConfig.h42
-rw-r--r--src/messages/MDentryLink.h80
-rw-r--r--src/messages/MDentryUnlink.h117
-rw-r--r--src/messages/MDirUpdate.h98
-rw-r--r--src/messages/MDiscover.h100
-rw-r--r--src/messages/MDiscoverReply.h215
-rw-r--r--src/messages/MExportCaps.h64
-rw-r--r--src/messages/MExportCapsAck.h58
-rw-r--r--src/messages/MExportDir.h66
-rw-r--r--src/messages/MExportDirAck.h58
-rw-r--r--src/messages/MExportDirCancel.h58
-rw-r--r--src/messages/MExportDirDiscover.h73
-rw-r--r--src/messages/MExportDirDiscoverAck.h69
-rw-r--r--src/messages/MExportDirFinish.h63
-rw-r--r--src/messages/MExportDirNotify.h90
-rw-r--r--src/messages/MExportDirNotifyAck.h63
-rw-r--r--src/messages/MExportDirPrep.h93
-rw-r--r--src/messages/MExportDirPrepAck.h64
-rw-r--r--src/messages/MFSMap.h62
-rw-r--r--src/messages/MFSMapUser.h64
-rw-r--r--src/messages/MForward.h158
-rw-r--r--src/messages/MGatherCaps.h39
-rw-r--r--src/messages/MGenericMessage.h40
-rw-r--r--src/messages/MGetConfig.h48
-rw-r--r--src/messages/MGetPoolStats.h57
-rw-r--r--src/messages/MGetPoolStatsReply.h73
-rw-r--r--src/messages/MHeartbeat.h66
-rw-r--r--src/messages/MInodeFileCaps.h63
-rw-r--r--src/messages/MKVData.h48
-rw-r--r--src/messages/MLock.h106
-rw-r--r--src/messages/MLog.h60
-rw-r--r--src/messages/MLogAck.h62
-rw-r--r--src/messages/MMDSBeacon.h324
-rw-r--r--src/messages/MMDSCacheRejoin.h366
-rw-r--r--src/messages/MMDSFindIno.h55
-rw-r--r--src/messages/MMDSFindInoReply.h55
-rw-r--r--src/messages/MMDSFragmentNotify.h76
-rw-r--r--src/messages/MMDSFragmentNotifyAck.h62
-rw-r--r--src/messages/MMDSLoadTargets.h63
-rw-r--r--src/messages/MMDSMap.h89
-rw-r--r--src/messages/MMDSMetrics.h53
-rw-r--r--src/messages/MMDSOp.h15
-rw-r--r--src/messages/MMDSOpenIno.h59
-rw-r--r--src/messages/MMDSOpenInoReply.h64
-rw-r--r--src/messages/MMDSPeerRequest.h233
-rw-r--r--src/messages/MMDSPing.h50
-rw-r--r--src/messages/MMDSResolve.h160
-rw-r--r--src/messages/MMDSResolveAck.h65
-rw-r--r--src/messages/MMDSScrub.h138
-rw-r--r--src/messages/MMDSScrubStats.h80
-rw-r--r--src/messages/MMDSSnapUpdate.h63
-rw-r--r--src/messages/MMDSTableRequest.h70
-rw-r--r--src/messages/MMgrBeacon.h206
-rw-r--r--src/messages/MMgrClose.h51
-rw-r--r--src/messages/MMgrCommand.h46
-rw-r--r--src/messages/MMgrCommandReply.h45
-rw-r--r--src/messages/MMgrConfigure.h87
-rw-r--r--src/messages/MMgrDigest.h58
-rw-r--r--src/messages/MMgrMap.h58
-rw-r--r--src/messages/MMgrOpen.h98
-rw-r--r--src/messages/MMgrReport.h202
-rw-r--r--src/messages/MMgrUpdate.h84
-rw-r--r--src/messages/MMonCommand.h89
-rw-r--r--src/messages/MMonCommandAck.h83
-rw-r--r--src/messages/MMonElection.h144
-rw-r--r--src/messages/MMonGetMap.h39
-rw-r--r--src/messages/MMonGetOSDMap.h97
-rw-r--r--src/messages/MMonGetPurgedSnaps.h45
-rw-r--r--src/messages/MMonGetPurgedSnapsReply.h49
-rw-r--r--src/messages/MMonGetVersion.h60
-rw-r--r--src/messages/MMonGetVersionReply.h66
-rw-r--r--src/messages/MMonGlobalID.h50
-rw-r--r--src/messages/MMonHealth.h63
-rw-r--r--src/messages/MMonHealthChecks.h51
-rw-r--r--src/messages/MMonJoin.h93
-rw-r--r--src/messages/MMonMap.h62
-rw-r--r--src/messages/MMonMgrReport.h94
-rw-r--r--src/messages/MMonPaxos.h135
-rw-r--r--src/messages/MMonPing.h109
-rw-r--r--src/messages/MMonProbe.h153
-rw-r--r--src/messages/MMonQuorumService.h70
-rw-r--r--src/messages/MMonScrub.h92
-rw-r--r--src/messages/MMonSubscribe.h103
-rw-r--r--src/messages/MMonSubscribeAck.h55
-rw-r--r--src/messages/MMonSync.h116
-rw-r--r--src/messages/MOSDAlive.h53
-rw-r--r--src/messages/MOSDBackoff.h86
-rw-r--r--src/messages/MOSDBeacon.h64
-rw-r--r--src/messages/MOSDBoot.h122
-rw-r--r--src/messages/MOSDECSubOpRead.h84
-rw-r--r--src/messages/MOSDECSubOpReadReply.h84
-rw-r--r--src/messages/MOSDECSubOpWrite.h93
-rw-r--r--src/messages/MOSDECSubOpWriteReply.h84
-rw-r--r--src/messages/MOSDFailure.h130
-rw-r--r--src/messages/MOSDFastDispatchOp.h22
-rw-r--r--src/messages/MOSDForceRecovery.h114
-rw-r--r--src/messages/MOSDFull.h54
-rw-r--r--src/messages/MOSDMap.h166
-rw-r--r--src/messages/MOSDMarkMeDead.h63
-rw-r--r--src/messages/MOSDMarkMeDown.h116
-rw-r--r--src/messages/MOSDOp.h608
-rw-r--r--src/messages/MOSDOpReply.h353
-rw-r--r--src/messages/MOSDPGBackfill.h117
-rw-r--r--src/messages/MOSDPGBackfillRemove.h80
-rw-r--r--src/messages/MOSDPGCreate.h73
-rw-r--r--src/messages/MOSDPGCreate2.h56
-rw-r--r--src/messages/MOSDPGCreated.h37
-rw-r--r--src/messages/MOSDPGInfo.h104
-rw-r--r--src/messages/MOSDPGInfo2.h98
-rw-r--r--src/messages/MOSDPGLease.h68
-rw-r--r--src/messages/MOSDPGLeaseAck.h68
-rw-r--r--src/messages/MOSDPGLog.h135
-rw-r--r--src/messages/MOSDPGNotify.h111
-rw-r--r--src/messages/MOSDPGNotify2.h84
-rw-r--r--src/messages/MOSDPGPull.h106
-rw-r--r--src/messages/MOSDPGPush.h112
-rw-r--r--src/messages/MOSDPGPushReply.h94
-rw-r--r--src/messages/MOSDPGQuery.h82
-rw-r--r--src/messages/MOSDPGQuery2.h78
-rw-r--r--src/messages/MOSDPGReadyToMerge.h61
-rw-r--r--src/messages/MOSDPGRecoveryDelete.h94
-rw-r--r--src/messages/MOSDPGRecoveryDeleteReply.h67
-rw-r--r--src/messages/MOSDPGRemove.h71
-rw-r--r--src/messages/MOSDPGScan.h119
-rw-r--r--src/messages/MOSDPGTemp.h69
-rw-r--r--src/messages/MOSDPGTrim.h82
-rw-r--r--src/messages/MOSDPGUpdateLogMissing.h124
-rw-r--r--src/messages/MOSDPGUpdateLogMissingReply.h115
-rw-r--r--src/messages/MOSDPeeringOp.h28
-rw-r--r--src/messages/MOSDPing.h168
-rw-r--r--src/messages/MOSDRepOp.h199
-rw-r--r--src/messages/MOSDRepOpReply.h164
-rw-r--r--src/messages/MOSDRepScrub.h142
-rw-r--r--src/messages/MOSDRepScrubMap.h84
-rw-r--r--src/messages/MOSDScrub.h80
-rw-r--r--src/messages/MOSDScrub2.h61
-rw-r--r--src/messages/MOSDScrubReserve.h99
-rw-r--r--src/messages/MPGStats.h77
-rw-r--r--src/messages/MPGStatsAck.h49
-rw-r--r--src/messages/MPing.h33
-rw-r--r--src/messages/MPoolOp.h98
-rw-r--r--src/messages/MPoolOpReply.h85
-rw-r--r--src/messages/MRecoveryReserve.h133
-rw-r--r--src/messages/MRemoveSnaps.h56
-rw-r--r--src/messages/MRoute.h90
-rw-r--r--src/messages/MServiceMap.h39
-rw-r--r--src/messages/MStatfs.h71
-rw-r--r--src/messages/MStatfsReply.h49
-rw-r--r--src/messages/MTimeCheck.h92
-rw-r--r--src/messages/MTimeCheck2.h90
-rw-r--r--src/messages/MWatchNotify.h98
-rw-r--r--src/messages/PaxosServiceMessage.h59
171 files changed, 16616 insertions, 0 deletions
diff --git a/src/messages/MAuth.h b/src/messages/MAuth.h
new file mode 100644
index 000000000..8e066a3cf
--- /dev/null
+++ b/src/messages/MAuth.h
@@ -0,0 +1,66 @@
+// -*- 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 <string_view>
+
+#include "include/encoding.h"
+
+#include "msg/Message.h"
+#include "msg/MessageRef.h"
+#include "messages/PaxosServiceMessage.h"
+
+class MAuth final : public PaxosServiceMessage {
+public:
+ __u32 protocol;
+ ceph::buffer::list auth_payload;
+ epoch_t monmap_epoch;
+
+ /* if protocol == 0, then auth_payload is a set<__u32> listing protocols the client supports */
+
+ MAuth() : PaxosServiceMessage{CEPH_MSG_AUTH, 0}, protocol(0), monmap_epoch(0) { }
+private:
+ ~MAuth() final {}
+
+public:
+ std::string_view get_type_name() const override { return "auth"; }
+ void print(std::ostream& out) const override {
+ out << "auth(proto " << protocol << " " << auth_payload.length() << " bytes"
+ << " epoch " << monmap_epoch << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+ ceph::buffer::list& get_auth_payload() { return auth_payload; }
+};
+
+#endif
diff --git a/src/messages/MAuthReply.h b/src/messages/MAuthReply.h
new file mode 100644
index 000000000..1c7c5e506
--- /dev/null
+++ b/src/messages/MAuthReply.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_MAUTHREPLY_H
+#define CEPH_MAUTHREPLY_H
+
+#include "msg/Message.h"
+#include "common/errno.h"
+
+class MAuthReply final : public Message {
+public:
+ __u32 protocol;
+ errorcode32_t result;
+ uint64_t global_id; // if zero, meaningless
+ std::string result_msg;
+ ceph::buffer::list result_bl;
+
+ MAuthReply() : Message(CEPH_MSG_AUTH_REPLY), protocol(0), result(0), global_id(0) {}
+ MAuthReply(__u32 p, ceph::buffer::list *bl = NULL, int r = 0, uint64_t gid=0, const char *msg = "") :
+ Message(CEPH_MSG_AUTH_REPLY),
+ protocol(p), result(r), global_id(gid),
+ result_msg(msg) {
+ if (bl)
+ result_bl = *bl;
+ }
+private:
+ ~MAuthReply() final {}
+
+public:
+ std::string_view get_type_name() const override { return "auth_reply"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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 000000000..fbb262b83
--- /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"
+#include "osd/PGPeeringEvent.h"
+
+class MBackfillReserve : public MOSDPeeringOp {
+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()
+ : MOSDPeeringOp{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)
+ : MOSDPeeringOp{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(std::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();
+ using ceph::decode;
+ 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 000000000..1c9334ba0
--- /dev/null
+++ b/src/messages/MCacheExpire.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) 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 "mds/mdstypes.h"
+#include "messages/MMDSOp.h"
+
+class MCacheExpire final : public MMDSOp {
+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 {
+ std::map<vinodeno_t, uint32_t> inodes;
+ std::map<dirfrag_t, uint32_t> dirs;
+ std::map<dirfrag_t, std::map<std::pair<std::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(ceph::buffer::list &bl) const {
+ using ceph::encode;
+ encode(inodes, bl);
+ encode(dirs, bl);
+ encode(dentries, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &bl) {
+ using ceph::decode;
+ decode(inodes, bl);
+ decode(dirs, bl);
+ decode(dentries, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(realm)
+
+ std::map<dirfrag_t, realm> realms;
+
+ int get_from() const { return from; }
+
+protected:
+ MCacheExpire() : MMDSOp{MSG_MDS_CACHEEXPIRE}, from(-1) {}
+ MCacheExpire(int f) :
+ MMDSOp{MSG_MDS_CACHEEXPIRE},
+ from(f) { }
+ ~MCacheExpire() final {}
+
+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][std::pair<std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+WRITE_CLASS_ENCODER(MCacheExpire::realm)
+
+#endif
diff --git a/src/messages/MClientCapRelease.h b/src/messages/MClientCapRelease.h
new file mode 100644
index 000000000..1524dd25c
--- /dev/null
+++ b/src/messages/MClientCapRelease.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_MCLIENTCAPRELEASE_H
+#define CEPH_MCLIENTCAPRELEASE_H
+
+#include "msg/Message.h"
+
+
+class MClientCapRelease final : public SafeMessage {
+ public:
+ std::string_view get_type_name() const override { return "client_cap_release";}
+ void print(std::ostream& out) const override {
+ out << "client_cap_release(" << caps.size() << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(head, p);
+ ceph::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);
+ ceph::encode_nohead(caps, payload);
+ encode(osd_epoch_barrier, payload);
+ }
+
+ struct ceph_mds_cap_release head;
+ std::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 = 0;
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ MClientCapRelease() :
+ SafeMessage{CEPH_MSG_CLIENT_CAPRELEASE, HEAD_VERSION, COMPAT_VERSION}
+ {
+ memset(&head, 0, sizeof(head));
+ }
+ ~MClientCapRelease() final {}
+};
+
+#endif
diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h
new file mode 100644
index 000000000..d1a4817be
--- /dev/null
+++ b/src/messages/MClientCaps.h
@@ -0,0 +1,349 @@
+// -*- 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 final : public SafeMessage {
+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;
+
+ ceph::buffer::list snapbl;
+ ceph::buffer::list xattrbl;
+ ceph::buffer::list flockbl;
+ version_t inline_version = 0;
+ ceph::buffer::list 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()
+ : SafeMessage{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)
+ : SafeMessage{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)
+ : SafeMessage{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() final {}
+
+private:
+ file_layout_t layout;
+
+public:
+ std::string_view get_type_name() const override { return "Cfcap";}
+ void print(std::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
+ << " ctime " << ctime
+ << " change_attr " << change_attr;
+ 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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(head, p);
+ if (head.op == CEPH_CAP_OP_EXPORT) {
+ ceph_mds_caps_export_body body;
+ decode(body, p);
+ peer = body.peer;
+ p += (sizeof(ceph_mds_caps_non_export_body) -
+ sizeof(ceph_mds_caps_export_body));
+ } else {
+ ceph_mds_caps_non_export_body body;
+ decode(body, p);
+ 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;
+ }
+ ceph::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);
+ static_assert(sizeof(ceph_mds_caps_non_export_body) >
+ sizeof(ceph_mds_caps_export_body));
+ if (head.op == CEPH_CAP_OP_EXPORT) {
+ ceph_mds_caps_export_body body;
+ body.peer = peer;
+ encode(body, payload);
+ payload.append_zero(sizeof(ceph_mds_caps_non_export_body) -
+ sizeof(ceph_mds_caps_export_body));
+ } else {
+ ceph_mds_caps_non_export_body body;
+ 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);
+ }
+ ceph::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(ceph::buffer::list(), 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientLease.h b/src/messages/MClientLease.h
new file mode 100644
index 000000000..cad0f3f21
--- /dev/null
+++ b/src/messages/MClientLease.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) 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 final : public SafeMessage {
+public:
+ 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() : SafeMessage(CEPH_MSG_CLIENT_LEASE) {}
+ MClientLease(const MClientLease& m) :
+ SafeMessage(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) :
+ SafeMessage(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) :
+ SafeMessage(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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "client_lease"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientMetrics.h b/src/messages/MClientMetrics.h
new file mode 100644
index 000000000..5e4234c69
--- /dev/null
+++ b/src/messages/MClientMetrics.h
@@ -0,0 +1,54 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MDS_CLIENT_METRICS_H
+#define CEPH_MDS_CLIENT_METRICS_H
+
+#include <vector>
+
+#include "msg/Message.h"
+#include "include/cephfs/metrics/Types.h"
+
+class MClientMetrics final : public SafeMessage {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ std::vector<ClientMetricMessage> updates;
+
+protected:
+ MClientMetrics() : MClientMetrics(std::vector<ClientMetricMessage>{}) { }
+ MClientMetrics(std::vector<ClientMetricMessage> updates)
+ : SafeMessage(CEPH_MSG_CLIENT_METRICS, HEAD_VERSION, COMPAT_VERSION), updates(updates) {
+ }
+ ~MClientMetrics() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "client_metrics";
+ }
+
+ void print(ostream &out) const override {
+ out << "client_metrics ";
+ for (auto &i : updates) {
+ i.print(&out);
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(updates, payload);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto iter = payload.cbegin();
+ decode(updates, iter);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif // CEPH_MDS_CLIENT_METRICS_H
diff --git a/src/messages/MClientQuota.h b/src/messages/MClientQuota.h
new file mode 100644
index 000000000..4dad9f1d0
--- /dev/null
+++ b/src/messages/MClientQuota.h
@@ -0,0 +1,54 @@
+#ifndef CEPH_MCLIENTQUOTA_H
+#define CEPH_MCLIENTQUOTA_H
+
+#include "msg/Message.h"
+
+class MClientQuota final : public SafeMessage {
+public:
+ inodeno_t ino;
+ nest_info_t rstat;
+ quota_info_t quota;
+
+protected:
+ MClientQuota() :
+ SafeMessage{CEPH_MSG_CLIENT_QUOTA},
+ ino(0)
+ {}
+ ~MClientQuota() final {}
+
+public:
+ std::string_view get_type_name() const override { return "client_quota"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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());
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientReclaim.h b/src/messages/MClientReclaim.h
new file mode 100644
index 000000000..f3f0ff09e
--- /dev/null
+++ b/src/messages/MClientReclaim.h
@@ -0,0 +1,66 @@
+// -*- 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 final : public SafeMessage {
+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(std::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:
+ MClientReclaim() :
+ SafeMessage{CEPH_MSG_CLIENT_RECLAIM, HEAD_VERSION, COMPAT_VERSION} {}
+ MClientReclaim(std::string_view _uuid, uint32_t _flags) :
+ SafeMessage{CEPH_MSG_CLIENT_RECLAIM, HEAD_VERSION, COMPAT_VERSION},
+ uuid(_uuid), flags(_flags) {}
+private:
+ ~MClientReclaim() final {}
+
+ std::string uuid;
+ uint32_t flags = 0;
+
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientReclaimReply.h b/src/messages/MClientReclaimReply.h
new file mode 100644
index 000000000..354906cd4
--- /dev/null
+++ b/src/messages/MClientReclaimReply.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_MCLIENTRECLAIMREPLY_H
+#define CEPH_MCLIENTRECLAIMREPLY_H
+
+#include "msg/Message.h"
+
+class MClientReclaimReply final : public SafeMessage {
+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(std::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:
+ MClientReclaimReply() :
+ MClientReclaimReply{0, 0}
+ {}
+ MClientReclaimReply(int r, epoch_t e=0) :
+ SafeMessage{CEPH_MSG_CLIENT_RECLAIM_REPLY, HEAD_VERSION, COMPAT_VERSION},
+ result(r), epoch(e) {}
+
+private:
+ ~MClientReclaimReply() final {}
+
+ int32_t result;
+ epoch_t epoch;
+ entity_addrvec_t addrs;
+
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientReconnect.h b/src/messages/MClientReconnect.h
new file mode 100644
index 000000000..43c5a4076
--- /dev/null
+++ b/src/messages/MClientReconnect.h
@@ -0,0 +1,176 @@
+// -*- 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 final : public SafeMessage {
+private:
+ static constexpr int HEAD_VERSION = 5;
+ static constexpr int COMPAT_VERSION = 4;
+
+public:
+ std::map<inodeno_t, cap_reconnect_t> caps; // only head inodes
+ std::vector<snaprealm_reconnect_t> realms;
+ bool more = false;
+
+private:
+ MClientReconnect() :
+ SafeMessage{CEPH_MSG_CLIENT_RECONNECT, HEAD_VERSION, COMPAT_VERSION} {}
+ ~MClientReconnect() final {}
+
+ 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;
+ {
+ ceph::buffer::list bl;
+ inodeno_t ino;
+ cap_reconnect_t cr;
+ encode(ino, bl);
+ encode(cr, bl);
+ cap_size = bl.length();
+ }
+ {
+ ceph::buffer::list 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(std::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 std::string& path,
+ int wanted, int issued, inodeno_t sr, snapid_t sf, ceph::buffer::list& 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 {
+ std::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 {
+ using ceph::decode;
+ 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 {
+ std::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);
+ }
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+
+#endif
diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h
new file mode 100644
index 000000000..bd58e0883
--- /dev/null
+++ b/src/messages/MClientReply.h
@@ -0,0 +1,405 @@
+// -*- 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 "include/mempool.h"
+#include "MClientRequest.h"
+
+#include "msg/Message.h"
+#include "include/ceph_features.h"
+#include "common/errno.h"
+#include "common/strescape.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 = 0;
+ __u32 duration_ms = 0;
+ __u32 seq = 0;
+ std::string alternate_name;
+
+ LeaseStat() = default;
+ LeaseStat(__u16 msk, __u32 dur, __u32 sq) : mask{msk}, duration_ms{dur}, seq{sq} {}
+
+ void decode(ceph::buffer::list::const_iterator &bl, const uint64_t features) {
+ using ceph::decode;
+ if (features == (uint64_t)-1) {
+ DECODE_START(2, bl);
+ decode(mask, bl);
+ decode(duration_ms, bl);
+ decode(seq, bl);
+ if (struct_v >= 2)
+ decode(alternate_name, bl);
+ DECODE_FINISH(bl);
+ }
+ else {
+ decode(mask, bl);
+ decode(duration_ms, bl);
+ decode(seq, bl);
+ }
+ }
+};
+
+inline std::ostream& operator<<(std::ostream& out, const LeaseStat& l) {
+ out << "lease(mask " << l.mask << " dur " << l.duration_ms;
+ if (l.alternate_name.size()) {
+ out << " altn " << binstrprint(l.alternate_name, 128) << ")";
+ }
+ return out << ")";
+}
+
+struct DirStat {
+ // mds distribution hints
+ frag_t frag;
+ __s32 auth;
+ std::set<__s32> dist;
+
+ DirStat() : auth(CDIR_AUTH_PARENT) {}
+ DirStat(ceph::buffer::list::const_iterator& p, const uint64_t features) {
+ decode(p, features);
+ }
+
+ void decode(ceph::buffer::list::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;
+ std::string symlink; // symlink content (if symlink)
+
+ ceph_dir_layout dir_layout;
+
+ ceph::buffer::list xattrbl;
+
+ ceph::buffer::list inline_data;
+ version_t inline_version;
+
+ quota_info_t quota;
+
+ mds_rank_t dir_pin;
+ std::map<std::string,std::string> snap_metadata;
+
+ bool fscrypt = false; // fscrypt enabled ?
+
+ public:
+ InodeStat() {}
+ InodeStat(ceph::buffer::list::const_iterator& p, const uint64_t features) {
+ decode(p, features);
+ }
+
+ void decode(ceph::buffer::list::const_iterator &p, const uint64_t features) {
+ using ceph::decode;
+ if (features == (uint64_t)-1) {
+ DECODE_START(6, 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
+ if (struct_v >= 4) {
+ decode(rstat.rsnaps, p);
+ } // else remains zero
+ if (struct_v >= 5) {
+ decode(snap_metadata, p);
+ }
+ if (struct_v >= 6) {
+ decode(fscrypt, p);
+ }
+ 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.
+};
+
+struct openc_response_t {
+ _inodeno_t created_ino;
+ interval_set<inodeno_t> delegated_inos;
+
+public:
+ void encode(ceph::buffer::list& bl) const {
+ using ceph::encode;
+ ENCODE_START(1, 1, bl);
+ encode(created_ino, bl);
+ encode(delegated_inos, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &p) {
+ using ceph::decode;
+ DECODE_START(1, p);
+ decode(created_ino, p);
+ decode(delegated_inos, p);
+ DECODE_FINISH(p);
+ }
+} __attribute__ ((__may_alias__));
+WRITE_CLASS_ENCODER(openc_response_t)
+
+class MClientReply final : public SafeMessage {
+public:
+ // reply data
+ struct ceph_mds_reply_head head {};
+ ceph::buffer::list trace_bl;
+ ceph::buffer::list extra_bl;
+ ceph::buffer::list 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() : SafeMessage{CEPH_MSG_CLIENT_REPLY} {}
+ MClientReply(const MClientRequest &req, int result = 0) :
+ SafeMessage{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "creply"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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(ceph::buffer::list& bl) {
+ extra_bl = std::move(bl);
+ }
+ ceph::buffer::list& get_extra_bl() {
+ return extra_bl;
+ }
+ const ceph::buffer::list& get_extra_bl() const {
+ return extra_bl;
+ }
+
+ // trace
+ void set_trace(ceph::buffer::list& bl) {
+ trace_bl = std::move(bl);
+ }
+ ceph::buffer::list& get_trace_bl() {
+ return trace_bl;
+ }
+ const ceph::buffer::list& get_trace_bl() const {
+ return trace_bl;
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientRequest.h b/src/messages/MClientRequest.h
new file mode 100644
index 000000000..c51f1149e
--- /dev/null
+++ b/src/messages/MClientRequest.h
@@ -0,0 +1,329 @@
+// -*- 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 "include/filepath.h"
+#include "mds/mdstypes.h"
+#include "include/ceph_features.h"
+#include "messages/MMDSOp.h"
+
+#include <sys/types.h>
+#include <utime.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+struct SnapPayload {
+ std::map<std::string, std::string> metadata;
+
+ void encode(ceph::buffer::list &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(metadata, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(ceph::buffer::list::const_iterator &iter) {
+ DECODE_START(1, iter);
+ decode(metadata, iter);
+ DECODE_FINISH(iter);
+ }
+};
+
+WRITE_CLASS_ENCODER(SnapPayload)
+
+// metadata ops.
+
+class MClientRequest final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 5;
+ 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;
+ std::string dname;
+
+ Release() : item(), dname() {}
+ Release(const ceph_mds_request_release& rel, std::string name) :
+ item(rel), dname(name) {}
+
+ void encode(ceph::buffer::list& bl) const {
+ using ceph::encode;
+ item.dname_len = dname.length();
+ encode(item, bl);
+ ceph::encode_nohead(dname, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ using ceph::decode;
+ decode(item, bl);
+ ceph::decode_nohead(item.dname_len, dname, bl);
+ }
+ };
+ mutable std::vector<Release> releases; /* XXX HACK! */
+
+ // path arguments
+ filepath path, path2;
+ std::string alternate_name;
+ std::vector<uint64_t> gid_list;
+
+ /* XXX HACK */
+ mutable bool queued_for_replay = false;
+
+protected:
+ // cons
+ MClientRequest()
+ : MMDSOp(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {}
+ MClientRequest(int op)
+ : MMDSOp(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {
+ memset(&head, 0, sizeof(head));
+ head.op = op;
+ }
+ ~MClientRequest() final {}
+
+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;
+ }
+ bool is_async() const {
+ return get_flags() & CEPH_MDS_FLAG_ASYNC;
+ }
+
+ // 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;
+ }
+ void set_async_op() {
+ head.flags = head.flags | CEPH_MDS_FLAG_ASYNC;
+ }
+
+ void set_alternate_name(std::string _alternate_name) {
+ alternate_name = std::move(_alternate_name);
+ }
+ void set_alternate_name(bufferptr&& cipher) {
+ alternate_name = std::move(cipher.c_str());
+ }
+
+ 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 std::vector<uint64_t>& get_caller_gid_list() const { return gid_list; }
+
+ const std::string& get_path() const { return path.get_path(); }
+ const filepath& get_filepath() const { return path; }
+ const std::string& get_path2() const { return path2.get_path(); }
+ const filepath& get_filepath2() const { return path2; }
+ std::string_view get_alternate_name() const { return std::string_view(alternate_name); }
+
+ 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 {
+ using ceph::decode;
+ 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 = { init_le32(0), init_le32(0) };
+ head.args.setattr.mask = localmask;
+ }
+ }
+
+ decode(path, p);
+ decode(path2, p);
+ ceph::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);
+ if (header.version >= 5)
+ decode(alternate_name, 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);
+ ceph::encode_nohead(releases, payload);
+ encode(stamp, payload);
+ encode(gid_list, payload);
+ encode(alternate_name, payload);
+ }
+
+ std::string_view get_type_name() const override { return "creq"; }
+ void print(std::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 (alternate_name.size())
+ out << " (" << alternate_name << ") ";
+ if (!get_filepath2().empty())
+ out << " " << get_filepath2();
+ if (stamp != utime_t())
+ out << " " << stamp;
+ if (head.num_retry)
+ out << " RETRY=" << (int)head.num_retry;
+ if (is_async())
+ out << " ASYNC";
+ if (is_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 << '}'
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+WRITE_CLASS_ENCODER(MClientRequest::Release)
+
+#endif
diff --git a/src/messages/MClientRequestForward.h b/src/messages/MClientRequestForward.h
new file mode 100644
index 000000000..5c1eebd4b
--- /dev/null
+++ b/src/messages/MClientRequestForward.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_MCLIENTREQUESTFORWARD_H
+#define CEPH_MCLIENTREQUESTFORWARD_H
+
+#include "msg/Message.h"
+
+class MClientRequestForward final : public SafeMessage {
+private:
+ int32_t dest_mds;
+ int32_t num_fwd;
+ bool client_must_resend;
+
+protected:
+ MClientRequestForward()
+ : SafeMessage{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) :
+ SafeMessage{CEPH_MSG_CLIENT_REQUEST_FORWARD},
+ dest_mds(dm), num_fwd(nf), client_must_resend(cmr) {
+ ceph_assert(client_must_resend);
+ header.tid = t;
+ }
+ ~MClientRequestForward() final {}
+
+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(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dest_mds, p);
+ decode(num_fwd, p);
+ decode(client_must_resend, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientSession.h b/src/messages/MClientSession.h
new file mode 100644
index 000000000..f6927a49c
--- /dev/null
+++ b/src/messages/MClientSession.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) 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 final : public SafeMessage {
+private:
+ static constexpr int HEAD_VERSION = 5;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ ceph_mds_session_head head;
+ static constexpr unsigned SESSION_BLOCKLISTED = (1<<0);
+
+ unsigned flags = 0;
+ std::map<std::string, std::string> metadata;
+ feature_bitset_t supported_features;
+ metric_spec_t metric_spec;
+
+ 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() : SafeMessage{CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION} { }
+ MClientSession(int o, version_t s=0, unsigned msg_flags=0) :
+ SafeMessage{CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION},
+ flags(msg_flags) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ head.seq = s;
+ }
+ MClientSession(int o, utime_t st) :
+ SafeMessage{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "client_session"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(head, p);
+ if (header.version >= 2)
+ decode(metadata, p);
+ if (header.version >= 3)
+ decode(supported_features, p);
+ if (header.version >= 4) {
+ decode(metric_spec, p);
+ }
+ if (header.version >= 5) {
+ decode(flags, 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);
+ encode(metric_spec, payload);
+ encode(flags, payload);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MClientSnap.h b/src/messages/MClientSnap.h
new file mode 100644
index 000000000..75178bffa
--- /dev/null
+++ b/src/messages/MClientSnap.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_MCLIENTSNAP_H
+#define CEPH_MCLIENTSNAP_H
+
+#include "msg/Message.h"
+
+class MClientSnap final : public SafeMessage {
+public:
+ ceph_mds_snap_head head;
+ ceph::buffer::list bl;
+
+ // (for split only)
+ std::vector<inodeno_t> split_inos;
+ std::vector<inodeno_t> split_realms;
+
+protected:
+ MClientSnap(int o=0) :
+ SafeMessage{CEPH_MSG_CLIENT_SNAP} {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ }
+ ~MClientSnap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "client_snap"; }
+ void print(std::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);
+ ceph::encode_nohead(split_inos, payload);
+ ceph::encode_nohead(split_realms, payload);
+ ceph::encode_nohead(bl, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(head, p);
+ ceph::decode_nohead(head.num_split_inos, split_inos, p);
+ ceph::decode_nohead(head.num_split_realms, split_realms, p);
+ ceph::decode_nohead(head.trace_len, bl, p);
+ ceph_assert(p.end());
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MCommand.h b/src/messages/MCommand.h
new file mode 100644
index 000000000..cd912cd28
--- /dev/null
+++ b/src/messages/MCommand.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_MCOMMAND_H
+#define CEPH_MCOMMAND_H
+
+#include <vector>
+
+#include "msg/Message.h"
+
+class MCommand final : public Message {
+public:
+ uuid_d fsid;
+ std::vector<std::string> cmd;
+
+ MCommand()
+ : Message{MSG_COMMAND} {}
+ MCommand(const uuid_d &f)
+ : Message{MSG_COMMAND},
+ fsid(f) { }
+
+private:
+ ~MCommand() final {}
+
+public:
+ std::string_view get_type_name() const override { return "command"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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 000000000..ed627c85c
--- /dev/null
+++ b/src/messages/MCommandReply.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_MCOMMANDREPLY_H
+#define CEPH_MCOMMANDREPLY_H
+
+#include <string_view>
+
+#include "msg/Message.h"
+#include "MCommand.h"
+
+class MCommandReply final : public Message {
+public:
+ errorcode32_t r;
+ std::string rs;
+
+ MCommandReply()
+ : Message{MSG_COMMAND_REPLY} {}
+ MCommandReply(MCommand *m, int _r)
+ : Message{MSG_COMMAND_REPLY}, r(_r) {
+ header.tid = m->get_tid();
+ }
+ MCommandReply(int _r, std::string_view s)
+ : Message{MSG_COMMAND_REPLY},
+ r(_r), rs(s) { }
+private:
+ ~MCommandReply() final {}
+
+public:
+ std::string_view get_type_name() const override { return "command_reply"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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 000000000..c97c70640
--- /dev/null
+++ b/src/messages/MConfig.h
@@ -0,0 +1,42 @@
+// -*- 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 Message {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ // use transparent comparator so we can lookup in it by std::string_view keys
+ std::map<std::string,std::string,std::less<>> config;
+
+ MConfig() : Message{MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION} { }
+ MConfig(const std::map<std::string,std::string,std::less<>>& c)
+ : Message{MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION},
+ config{c} {}
+ MConfig(std::map<std::string,std::string,std::less<>>&& c)
+ : Message{MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION},
+ config{std::move(c)} {}
+
+ std::string_view get_type_name() const override {
+ return "config";
+ }
+ void print(std::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/MDentryLink.h b/src/messages/MDentryLink.h
new file mode 100644
index 000000000..c461105bc
--- /dev/null
+++ b/src/messages/MDentryLink.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_MDENTRYLINK_H
+#define CEPH_MDENTRYLINK_H
+
+#include <string_view>
+
+#include "messages/MMDSOp.h"
+
+class MDentryLink final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t subtree;
+ dirfrag_t dirfrag;
+ std::string dn;
+ bool is_primary = false;
+
+ public:
+ dirfrag_t get_subtree() const { return subtree; }
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const std::string& get_dn() const { return dn; }
+ bool get_is_primary() const { return is_primary; }
+
+ ceph::buffer::list bl;
+
+protected:
+ MDentryLink() :
+ MMDSOp(MSG_MDS_DENTRYLINK, HEAD_VERSION, COMPAT_VERSION) { }
+ MDentryLink(dirfrag_t r, dirfrag_t df, std::string_view n, bool p) :
+ MMDSOp(MSG_MDS_DENTRYLINK, HEAD_VERSION, COMPAT_VERSION),
+ subtree(r),
+ dirfrag(df),
+ dn(n),
+ is_primary(p) {}
+ ~MDentryLink() final {}
+
+public:
+ std::string_view get_type_name() const override { return "dentry_link";}
+ void print(std::ostream& o) const override {
+ o << "dentry_link(" << dirfrag << " " << dn << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MDentryUnlink.h b/src/messages/MDentryUnlink.h
new file mode 100644
index 000000000..01240f5dc
--- /dev/null
+++ b/src/messages/MDentryUnlink.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_MDENTRYUNLINK_H
+#define CEPH_MDENTRYUNLINK_H
+
+#include <string_view>
+
+#include "messages/MMDSOp.h"
+
+class MDentryUnlink final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t dirfrag;
+ std::string dn;
+ bool unlinking = false;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const std::string& get_dn() const { return dn; }
+ bool is_unlinking() const { return unlinking; }
+
+ ceph::buffer::list straybl;
+ ceph::buffer::list snapbl;
+
+protected:
+ MDentryUnlink() :
+ MMDSOp(MSG_MDS_DENTRYUNLINK, HEAD_VERSION, COMPAT_VERSION) { }
+ MDentryUnlink(dirfrag_t df, std::string_view n, bool u=false) :
+ MMDSOp(MSG_MDS_DENTRYUNLINK, HEAD_VERSION, COMPAT_VERSION),
+ dirfrag(df), dn(n), unlinking(u) {}
+ ~MDentryUnlink() final {}
+
+public:
+ std::string_view get_type_name() const override { return "dentry_unlink";}
+ void print(std::ostream& o) const override {
+ o << "dentry_unlink(" << dirfrag << " " << dn << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(dn, p);
+ decode(straybl, p);
+ if (header.version >= 2)
+ decode(unlinking, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(dn, payload);
+ encode(straybl, payload);
+ encode(unlinking, payload);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+class MDentryUnlinkAck final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t dirfrag;
+ std::string dn;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const std::string& get_dn() const { return dn; }
+
+protected:
+ MDentryUnlinkAck() :
+ MMDSOp(MSG_MDS_DENTRYUNLINK_ACK, HEAD_VERSION, COMPAT_VERSION) { }
+ MDentryUnlinkAck(dirfrag_t df, std::string_view n) :
+ MMDSOp(MSG_MDS_DENTRYUNLINK_ACK, HEAD_VERSION, COMPAT_VERSION),
+ dirfrag(df), dn(n) {}
+ ~MDentryUnlinkAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "dentry_unlink_ack";}
+ void print(std::ostream& o) const override {
+ o << "dentry_unlink_ack(" << dirfrag << " " << dn << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(dn, p);
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(dirfrag, payload);
+ encode(dn, payload);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MDirUpdate.h b/src/messages/MDirUpdate.h
new file mode 100644
index 000000000..47ea3a7f4
--- /dev/null
+++ b/src/messages/MDirUpdate.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) 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 "messages/MMDSOp.h"
+
+class MDirUpdate final : public MMDSOp {
+public:
+ 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(std::ostream& out) const override {
+ out << "dir_update(" << get_dirfrag() << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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() final {}
+ MDirUpdate() : MMDSOp(MSG_MDS_DIRUPDATE, HEAD_VERSION, COMPAT_VERSION) {}
+ MDirUpdate(mds_rank_t f,
+ dirfrag_t dirfrag,
+ int dir_rep,
+ const std::set<int32_t>& dir_rep_by,
+ filepath& path,
+ bool discover = false) :
+ MMDSOp(MSG_MDS_DIRUPDATE, HEAD_VERSION, COMPAT_VERSION), 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)
+ : MMDSOp{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
+
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MDiscover.h b/src/messages/MDiscover.h
new file mode 100644
index 000000000..7b69981b4
--- /dev/null
+++ b/src/messages/MDiscover.h
@@ -0,0 +1,100 @@
+// -*- 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 "include/filepath.h"
+#include "messages/MMDSOp.h"
+
+#include <string>
+
+
+class MDiscover final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ 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 path_locked = 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 is_path_locked() const { return path_locked; }
+
+ void set_base_dir_frag(frag_t f) { base_dir_frag = f; }
+
+protected:
+ MDiscover() : MMDSOp(MSG_MDS_DISCOVER, HEAD_VERSION, COMPAT_VERSION) { }
+ MDiscover(inodeno_t base_ino_,
+ frag_t base_frag_,
+ snapid_t s,
+ filepath& want_path_,
+ bool want_base_dir_ = true,
+ bool path_locked_ = false) :
+ MMDSOp{MSG_MDS_DISCOVER},
+ base_ino(base_ino_),
+ base_dir_frag(base_frag_),
+ snapid(s),
+ want(want_path_),
+ want_base_dir(want_base_dir_),
+ path_locked(path_locked_) { }
+ ~MDiscover() final {}
+
+public:
+ std::string_view get_type_name() const override { return "Dis"; }
+ void print(std::ostream &out) const override {
+ out << "discover(" << header.tid << " " << base_ino << "." << base_dir_frag
+ << " " << want << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(path_locked, 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(path_locked, payload);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MDiscoverReply.h b/src/messages/MDiscoverReply.h
new file mode 100644
index 000000000..e2d11d0fb
--- /dev/null
+++ b/src/messages/MDiscoverReply.h
@@ -0,0 +1,215 @@
+// -*- 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 "include/filepath.h"
+#include "messages/MMDSOp.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 final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+ // info about original request
+ inodeno_t base_ino;
+ frag_t base_dir_frag;
+ bool wanted_base_dir = false;
+ bool path_locked = 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;
+ ceph::buffer::list 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 is_path_locked() const { return path_locked; }
+ 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() : MMDSOp{MSG_MDS_DISCOVERREPLY, HEAD_VERSION, COMPAT_VERSION} { }
+ MDiscoverReply(const MDiscover &dis) :
+ MMDSOp{MSG_MDS_DISCOVERREPLY, HEAD_VERSION, COMPAT_VERSION},
+ base_ino(dis.get_base_ino()),
+ base_dir_frag(dis.get_base_dir_frag()),
+ wanted_base_dir(dis.wants_base_dir()),
+ path_locked(dis.is_path_locked()),
+ 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) :
+ MMDSOp{MSG_MDS_DISCOVERREPLY, HEAD_VERSION, COMPAT_VERSION},
+ base_ino(df.ino),
+ base_dir_frag(df.frag),
+ wanted_base_dir(false),
+ path_locked(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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "discover_reply"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(base_ino, p);
+ decode(base_dir_frag, p);
+ decode(wanted_base_dir, p);
+ decode(path_locked, 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(path_locked, 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportCaps.h b/src/messages/MExportCaps.h
new file mode 100644
index 000000000..63cf927e8
--- /dev/null
+++ b/src/messages/MExportCaps.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_MEXPORTCAPS_H
+#define CEPH_MEXPORTCAPS_H
+
+#include "messages/MMDSOp.h"
+
+class MExportCaps final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ inodeno_t ino;
+ ceph::buffer::list cap_bl;
+ std::map<client_t,entity_inst_t> client_map;
+ std::map<client_t,client_metadata_t> client_metadata_map;
+
+protected:
+ MExportCaps() :
+ MMDSOp{MSG_MDS_EXPORTCAPS, HEAD_VERSION, COMPAT_VERSION} {}
+ ~MExportCaps() final {}
+
+public:
+ std::string_view get_type_name() const override { return "export_caps"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(cap_bl, p);
+ decode(client_map, p);
+ if (header.version >= 2)
+ decode(client_metadata_map, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportCapsAck.h b/src/messages/MExportCapsAck.h
new file mode 100644
index 000000000..1ac62fdd4
--- /dev/null
+++ b/src/messages/MExportCapsAck.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_MEXPORTCAPSACK_H
+#define CEPH_MEXPORTCAPSACK_H
+
+#include "messages/MMDSOp.h"
+
+class MExportCapsAck final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ inodeno_t ino;
+ ceph::buffer::list cap_bl;
+
+protected:
+ MExportCapsAck() :
+ MMDSOp{MSG_MDS_EXPORTCAPSACK, HEAD_VERSION, COMPAT_VERSION} {}
+ MExportCapsAck(inodeno_t i) :
+ MMDSOp{MSG_MDS_EXPORTCAPSACK, HEAD_VERSION, COMPAT_VERSION}, ino(i) {}
+ ~MExportCapsAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "export_caps_ack"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(cap_bl, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDir.h b/src/messages/MExportDir.h
new file mode 100644
index 000000000..882aecfca
--- /dev/null
+++ b/src/messages/MExportDir.h
@@ -0,0 +1,66 @@
+// -*- 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 "messages/MMDSOp.h"
+
+class MExportDir final : public MMDSOp {
+public:
+ dirfrag_t dirfrag;
+ ceph::buffer::list export_data;
+ std::vector<dirfrag_t> bounds;
+ ceph::buffer::list client_map;
+
+protected:
+ MExportDir() : MMDSOp{MSG_MDS_EXPORTDIR} {}
+ MExportDir(dirfrag_t df, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIR}, dirfrag(df) {
+ set_tid(tid);
+ }
+ ~MExportDir() final {}
+
+public:
+ std::string_view get_type_name() const override { return "Ex"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(bounds, p);
+ decode(export_data, p);
+ decode(client_map, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirAck.h b/src/messages/MExportDirAck.h
new file mode 100644
index 000000000..4728cc3ab
--- /dev/null
+++ b/src/messages/MExportDirAck.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_MEXPORTDIRACK_H
+#define CEPH_MEXPORTDIRACK_H
+
+#include "MExportDir.h"
+#include "messages/MMDSOp.h"
+
+class MExportDirAck final : public MMDSOp {
+public:
+ dirfrag_t dirfrag;
+ ceph::buffer::list imported_caps;
+
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+
+protected:
+ MExportDirAck() : MMDSOp{MSG_MDS_EXPORTDIRACK} {}
+ MExportDirAck(dirfrag_t df, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIRACK}, dirfrag(df) {
+ set_tid(tid);
+ }
+ ~MExportDirAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExAck"; }
+ void print(std::ostream& o) const override {
+ o << "export_ack(" << dirfrag << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirCancel.h b/src/messages/MExportDirCancel.h
new file mode 100644
index 000000000..50bba2679
--- /dev/null
+++ b/src/messages/MExportDirCancel.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_MEXPORTDIRCANCEL_H
+#define CEPH_MEXPORTDIRCANCEL_H
+
+#include "include/types.h"
+#include "messages/MMDSOp.h"
+
+class MExportDirCancel final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+ dirfrag_t dirfrag;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+
+protected:
+ MExportDirCancel() : MMDSOp{MSG_MDS_EXPORTDIRCANCEL, HEAD_VERSION, COMPAT_VERSION} {}
+ MExportDirCancel(dirfrag_t df, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIRCANCEL, HEAD_VERSION, COMPAT_VERSION}, dirfrag(df) {
+ set_tid(tid);
+ }
+ ~MExportDirCancel() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExCancel"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirDiscover.h b/src/messages/MExportDirDiscover.h
new file mode 100644
index 000000000..91d62a49b
--- /dev/null
+++ b/src/messages/MExportDirDiscover.h
@@ -0,0 +1,73 @@
+// -*- 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 "include/types.h"
+#include "messages/MMDSOp.h"
+
+class MExportDirDiscover final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+ 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() :
+ MMDSOp{MSG_MDS_EXPORTDIRDISCOVER, HEAD_VERSION, COMPAT_VERSION},
+ started(false) { }
+ MExportDirDiscover(dirfrag_t df, filepath& p, mds_rank_t f, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIRDISCOVER, HEAD_VERSION, COMPAT_VERSION},
+ from(f), dirfrag(df), path(p), started(false) {
+ set_tid(tid);
+ }
+ ~MExportDirDiscover() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExDis"; }
+ void print(std::ostream& o) const override {
+ o << "export_discover(" << dirfrag << " " << path << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirDiscoverAck.h b/src/messages/MExportDirDiscoverAck.h
new file mode 100644
index 000000000..b33ed07a5
--- /dev/null
+++ b/src/messages/MExportDirDiscoverAck.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_MEXPORTDIRDISCOVERACK_H
+#define CEPH_MEXPORTDIRDISCOVERACK_H
+
+#include "include/types.h"
+#include "messages/MMDSOp.h"
+
+class MExportDirDiscoverAck final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ 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() : MMDSOp{MSG_MDS_EXPORTDIRDISCOVERACK, HEAD_VERSION, COMPAT_VERSION} {}
+ MExportDirDiscoverAck(dirfrag_t df, uint64_t tid, bool s=true) :
+ MMDSOp{MSG_MDS_EXPORTDIRDISCOVERACK, HEAD_VERSION, COMPAT_VERSION},
+ dirfrag(df), success(s) {
+ set_tid(tid);
+ }
+ ~MExportDirDiscoverAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExDisA"; }
+ void print(std::ostream& o) const override {
+ o << "export_discover_ack(" << dirfrag;
+ if (success)
+ o << " success)";
+ else
+ o << " failure)";
+ }
+
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirFinish.h b/src/messages/MExportDirFinish.h
new file mode 100644
index 000000000..5cbf9ae29
--- /dev/null
+++ b/src/messages/MExportDirFinish.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_MEXPORTDIRFINISH_H
+#define CEPH_MEXPORTDIRFINISH_H
+
+#include "messages/MMDSOp.h"
+
+class MExportDirFinish final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t dirfrag;
+ bool last;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ bool is_last() const { return last; }
+
+protected:
+ MExportDirFinish() :
+ MMDSOp{MSG_MDS_EXPORTDIRFINISH, HEAD_VERSION, COMPAT_VERSION}, last(false) {}
+ MExportDirFinish(dirfrag_t df, bool l, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIRFINISH, HEAD_VERSION, COMPAT_VERSION}, dirfrag(df), last(l) {
+ set_tid(tid);
+ }
+ ~MExportDirFinish() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExFin"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(dirfrag, p);
+ decode(last, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirNotify.h b/src/messages/MExportDirNotify.h
new file mode 100644
index 000000000..bad8f82a0
--- /dev/null
+++ b/src/messages/MExportDirNotify.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_MEXPORTDIRNOTIFY_H
+#define CEPH_MEXPORTDIRNOTIFY_H
+
+#include "messages/MMDSOp.h"
+
+class MExportDirNotify final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t base;
+ bool ack;
+ std::pair<__s32,__s32> old_auth, new_auth;
+ std::list<dirfrag_t> bounds; // bounds; these dirs are _not_ included (tho the dirfragdes are)
+
+ public:
+ dirfrag_t get_dirfrag() const { return base; }
+ std::pair<__s32,__s32> get_old_auth() const { return old_auth; }
+ std::pair<__s32,__s32> get_new_auth() const { return new_auth; }
+ bool wants_ack() const { return ack; }
+ const std::list<dirfrag_t>& get_bounds() const { return bounds; }
+ std::list<dirfrag_t>& get_bounds() { return bounds; }
+
+protected:
+ MExportDirNotify() :
+ MMDSOp{MSG_MDS_EXPORTDIRNOTIFY, HEAD_VERSION, COMPAT_VERSION} {}
+ MExportDirNotify(dirfrag_t i, uint64_t tid, bool a, std::pair<__s32,__s32> oa,
+ std::pair<__s32,__s32> na) :
+ MMDSOp{MSG_MDS_EXPORTDIRNOTIFY, HEAD_VERSION, COMPAT_VERSION},
+ base(i), ack(a), old_auth(oa), new_auth(na) {
+ set_tid(tid);
+ }
+ ~MExportDirNotify() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExNot"; }
+ void print(std::ostream& o) const override {
+ o << "export_notify(" << base;
+ o << " " << old_auth << " -> " << new_auth;
+ if (ack)
+ o << " ack)";
+ else
+ o << " no ack)";
+ }
+
+ void copy_bounds(std::list<dirfrag_t>& ex) {
+ this->bounds = ex;
+ }
+ void copy_bounds(std::set<dirfrag_t>& ex) {
+ for (auto 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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(base, p);
+ decode(ack, p);
+ decode(old_auth, p);
+ decode(new_auth, p);
+ decode(bounds, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirNotifyAck.h b/src/messages/MExportDirNotifyAck.h
new file mode 100644
index 000000000..71ffafc14
--- /dev/null
+++ b/src/messages/MExportDirNotifyAck.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_MEXPORTDIRNOTIFYACK_H
+#define CEPH_MEXPORTDIRNOTIFYACK_H
+
+#include "messages/MMDSOp.h"
+
+class MExportDirNotifyAck final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t dirfrag;
+ std::pair<__s32,__s32> new_auth;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ std::pair<__s32,__s32> get_new_auth() const { return new_auth; }
+
+protected:
+ MExportDirNotifyAck() :
+ MMDSOp{MSG_MDS_EXPORTDIRNOTIFYACK, HEAD_VERSION, COMPAT_VERSION} {}
+ MExportDirNotifyAck(dirfrag_t df, uint64_t tid, std::pair<__s32,__s32> na) :
+ MMDSOp{MSG_MDS_EXPORTDIRNOTIFYACK, HEAD_VERSION, COMPAT_VERSION}, dirfrag(df), new_auth(na) {
+ set_tid(tid);
+ }
+ ~MExportDirNotifyAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExNotA"; }
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirPrep.h b/src/messages/MExportDirPrep.h
new file mode 100644
index 000000000..4a456d517
--- /dev/null
+++ b/src/messages/MExportDirPrep.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_MEXPORTDIRPREP_H
+#define CEPH_MEXPORTDIRPREP_H
+
+#include "include/types.h"
+#include "messages/MMDSOp.h"
+
+class MExportDirPrep final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t dirfrag;
+public:
+ ceph::buffer::list basedir;
+ std::list<dirfrag_t> bounds;
+ std::list<ceph::buffer::list> traces;
+private:
+ std::set<mds_rank_t> bystanders;
+ bool b_did_assim = false;
+
+public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+ const std::list<dirfrag_t>& get_bounds() const { return bounds; }
+ const std::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() = default;
+ MExportDirPrep(dirfrag_t df, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIRPREP, HEAD_VERSION, COMPAT_VERSION},
+ dirfrag(df)
+ {
+ set_tid(tid);
+ }
+ ~MExportDirPrep() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ExP"; }
+ void print(std::ostream& o) const override {
+ o << "export_prep(" << dirfrag << ")";
+ }
+
+ void add_bound(dirfrag_t df) {
+ bounds.push_back( df );
+ }
+ void add_trace(ceph::buffer::list& 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MExportDirPrepAck.h b/src/messages/MExportDirPrepAck.h
new file mode 100644
index 000000000..1d5456ac8
--- /dev/null
+++ b/src/messages/MExportDirPrepAck.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_MEXPORTDIRPREPACK_H
+#define CEPH_MEXPORTDIRPREPACK_H
+
+#include "include/types.h"
+#include "messages/MMDSOp.h"
+
+class MExportDirPrepAck final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ dirfrag_t dirfrag;
+ bool success = false;
+
+ public:
+ dirfrag_t get_dirfrag() const { return dirfrag; }
+
+protected:
+ MExportDirPrepAck() :
+ MMDSOp{MSG_MDS_EXPORTDIRPREPACK, HEAD_VERSION, COMPAT_VERSION} {}
+ MExportDirPrepAck(dirfrag_t df, bool s, uint64_t tid) :
+ MMDSOp{MSG_MDS_EXPORTDIRPREPACK, HEAD_VERSION, COMPAT_VERSION}, dirfrag(df), success(s) {
+ set_tid(tid);
+ }
+ ~MExportDirPrepAck() final {}
+
+public:
+ bool is_success() const { return success; }
+ std::string_view get_type_name() const override { return "ExPAck"; }
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MFSMap.h b/src/messages/MFSMap.h
new file mode 100644
index 000000000..fff7529d3
--- /dev/null
+++ b/src/messages/MFSMap.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_MFSMAP_H
+#define CEPH_MFSMAP_H
+
+#include "msg/Message.h"
+#include "mds/FSMap.h"
+#include "include/ceph_features.h"
+
+class MFSMap final : public Message {
+public:
+ epoch_t epoch;
+
+ version_t get_epoch() const { return epoch; }
+ const FSMap& get_fsmap() const {return fsmap;}
+
+ MFSMap() :
+ Message{CEPH_MSG_FS_MAP}, epoch(0) {}
+ MFSMap(const uuid_d &f, const FSMap &fsmap_) :
+ Message{CEPH_MSG_FS_MAP},
+ epoch(fsmap_.get_epoch()),
+ fsmap{fsmap_}
+ {}
+private:
+ FSMap fsmap;
+
+ ~MFSMap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "fsmap"; }
+ void print(std::ostream& out) const override {
+ out << "fsmap(e " << epoch << ")";
+ }
+
+ // marshalling
+ void decode_payload() override {
+ using ceph::decode;
+ 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 000000000..2d4192841
--- /dev/null
+++ b/src/messages/MFSMapUser.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_MFSMAPCOMPACT_H
+#define CEPH_MFSMAPCOMPACT_H
+
+#include "msg/Message.h"
+#include "mds/FSMapUser.h"
+#include "include/ceph_features.h"
+
+class MFSMapUser final : public Message {
+public:
+ epoch_t epoch;
+
+ version_t get_epoch() const { return epoch; }
+ const FSMapUser& get_fsmap() const { return fsmap; }
+
+ MFSMapUser() :
+ Message{CEPH_MSG_FS_MAP_USER}, epoch(0) {}
+ MFSMapUser(const uuid_d &f, const FSMapUser &fsmap_) :
+ Message{CEPH_MSG_FS_MAP_USER},
+ epoch(fsmap_.epoch),
+ fsmap{fsmap_}
+ {}
+private:
+ FSMapUser fsmap;
+
+ ~MFSMapUser() final {}
+
+public:
+ std::string_view get_type_name() const override { return "fsmap.user"; }
+ void print(std::ostream& out) const override {
+ out << "fsmap.user(e " << epoch << ")";
+ }
+
+ // marshalling
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MForward.h b/src/messages/MForward.h
new file mode 100644
index 000000000..f47de8fc2
--- /dev/null
+++ b/src/messages/MForward.h
@@ -0,0 +1,158 @@
+// -*- 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 final : public Message {
+public:
+ 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
+
+ std::string msg_desc; // for operator<< only
+
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 4;
+
+ MForward() : Message{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) :
+ Message{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() final {
+ 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 {
+ using ceph::decode;
+ 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(std::ostream& o) const override {
+ o << "forward(";
+ if (msg) {
+ o << *msg;
+ } else {
+ o << msg_desc;
+ }
+ o << " caps " << client_caps
+ << " tid " << tid
+ << " con_features " << con_features << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MGatherCaps.h b/src/messages/MGatherCaps.h
new file mode 100644
index 000000000..f3f05b94e
--- /dev/null
+++ b/src/messages/MGatherCaps.h
@@ -0,0 +1,39 @@
+#ifndef CEPH_MGATHERCAPS_H
+#define CEPH_MGATHERCAPS_H
+
+#include "messages/MMDSOp.h"
+
+
+class MGatherCaps final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ inodeno_t ino;
+
+protected:
+ MGatherCaps() :
+ MMDSOp{MSG_MDS_GATHERCAPS, HEAD_VERSION, COMPAT_VERSION} {}
+ ~MGatherCaps() final {}
+
+public:
+ std::string_view get_type_name() const override { return "gather_caps"; }
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MGenericMessage.h b/src/messages/MGenericMessage.h
new file mode 100644
index 000000000..32699728a
--- /dev/null
+++ b/src/messages/MGenericMessage.h
@@ -0,0 +1,40 @@
+// -*- 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 Message {
+private:
+ char tname[20];
+ //long pcid;
+
+ public:
+ MGenericMessage(int t=0) : Message{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 000000000..2575aa4bc
--- /dev/null
+++ b/src/messages/MGetConfig.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 MGetConfig : public Message {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ EntityName name; ///< e.g., mon.a, client.foo
+ std::string host; ///< our hostname
+ std::string device_class;
+
+ MGetConfig() : Message{MSG_GET_CONFIG, HEAD_VERSION, COMPAT_VERSION} { }
+ MGetConfig(const EntityName& n, const std::string& h)
+ : Message{MSG_GET_CONFIG, HEAD_VERSION, COMPAT_VERSION},
+ name(n),
+ host(h) {}
+
+ std::string_view get_type_name() const override {
+ return "get_config";
+ }
+ void print(std::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 000000000..82d1fcd2d
--- /dev/null
+++ b/src/messages/MGetPoolStats.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_MGETPOOLSTATS_H
+#define CEPH_MGETPOOLSTATS_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MGetPoolStats final : public PaxosServiceMessage {
+public:
+ uuid_d fsid;
+ std::vector<std::string> pools;
+
+ MGetPoolStats() : PaxosServiceMessage{MSG_GETPOOLSTATS, 0} {}
+ MGetPoolStats(const uuid_d& f, ceph_tid_t t, std::vector<std::string>& ls, version_t l) :
+ PaxosServiceMessage{MSG_GETPOOLSTATS, l},
+ fsid(f), pools(ls) {
+ set_tid(t);
+ }
+
+private:
+ ~MGetPoolStats() final {}
+
+public:
+ std::string_view get_type_name() const override { return "getpoolstats"; }
+ void print(std::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 000000000..eaf95d4a0
--- /dev/null
+++ b/src/messages/MGetPoolStatsReply.h
@@ -0,0 +1,73 @@
+// -*- 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 final : public PaxosServiceMessage {
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ uuid_d fsid;
+ boost::container::flat_map<std::string, pool_stat_t> pool_stats;
+ bool per_pool = false;
+
+ MGetPoolStatsReply() : PaxosServiceMessage{MSG_GETPOOLSTATSREPLY, 0,
+ HEAD_VERSION, COMPAT_VERSION} {}
+ MGetPoolStatsReply(uuid_d& f, ceph_tid_t t, version_t v) :
+ PaxosServiceMessage{MSG_GETPOOLSTATSREPLY, v,
+ HEAD_VERSION, COMPAT_VERSION},
+ fsid(f) {
+ set_tid(t);
+ }
+
+private:
+ ~MGetPoolStatsReply() final {}
+
+public:
+ std::string_view get_type_name() const override { return "getpoolstats"; }
+ void print(std::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;
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MHeartbeat.h b/src/messages/MHeartbeat.h
new file mode 100644
index 000000000..40c1042b6
--- /dev/null
+++ b/src/messages/MHeartbeat.h
@@ -0,0 +1,66 @@
+// -*- 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 "common/DecayCounter.h"
+#include "messages/MMDSOp.h"
+
+class MHeartbeat final : public MMDSOp {
+private:
+ mds_load_t load;
+ __s32 beat = 0;
+ std::map<mds_rank_t, float> import_map;
+
+ public:
+ const mds_load_t& get_load() const { return load; }
+ int get_beat() const { return beat; }
+
+ const std::map<mds_rank_t, float>& get_import_map() const { return import_map; }
+ std::map<mds_rank_t, float>& get_import_map() { return import_map; }
+
+protected:
+ MHeartbeat() : MMDSOp(MSG_MDS_HEARTBEAT), load(DecayRate()) {}
+ MHeartbeat(mds_load_t& load, int beat)
+ : MMDSOp(MSG_MDS_HEARTBEAT),
+ load(load),
+ beat(beat)
+ {}
+ ~MHeartbeat() final {}
+
+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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(load, p);
+ decode(beat, p);
+ decode(import_map, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MInodeFileCaps.h b/src/messages/MInodeFileCaps.h
new file mode 100644
index 000000000..e2a189ec4
--- /dev/null
+++ b/src/messages/MInodeFileCaps.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_MINODEFILECAPS_H
+#define CEPH_MINODEFILECAPS_H
+
+#include "messages/MMDSOp.h"
+
+class MInodeFileCaps final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+ inodeno_t ino;
+ __u32 caps = 0;
+
+public:
+ inodeno_t get_ino() const { return ino; }
+ int get_caps() const { return caps; }
+
+protected:
+ MInodeFileCaps() : MMDSOp(MSG_MDS_INODEFILECAPS, HEAD_VERSION, COMPAT_VERSION) {}
+ MInodeFileCaps(inodeno_t ino, int caps) :
+ MMDSOp(MSG_MDS_INODEFILECAPS, HEAD_VERSION, COMPAT_VERSION) {
+ this->ino = ino;
+ this->caps = caps;
+ }
+ ~MInodeFileCaps() final {}
+
+public:
+ std::string_view get_type_name() const override { return "inode_file_caps";}
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MKVData.h b/src/messages/MKVData.h
new file mode 100644
index 000000000..f735f79d7
--- /dev/null
+++ b/src/messages/MKVData.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 MKVData : public Message {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ version_t version;
+ std::string prefix;
+ bool incremental = false;
+
+ // use transparent comparator so we can lookup in it by std::string_view keys
+ std::map<std::string,boost::optional<bufferlist>,std::less<>> data;
+
+ MKVData() : Message{MSG_KV_DATA, HEAD_VERSION, COMPAT_VERSION} { }
+
+ std::string_view get_type_name() const override {
+ return "kv_data";
+ }
+ void print(std::ostream& o) const override {
+ o << "kv_data(v" << version
+ << " prefix " << prefix << ", "
+ << (incremental ? "incremental, " : "full, ")
+ << data.size() << " keys" << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(version, p);
+ decode(prefix, p);
+ decode(incremental, p);
+ decode(data, p);
+ }
+
+ void encode_payload(uint64_t) override {
+ using ceph::encode;
+ encode(version, payload);
+ encode(prefix, payload);
+ encode(incremental, payload);
+ encode(data, payload);
+ }
+};
diff --git a/src/messages/MLock.h b/src/messages/MLock.h
new file mode 100644
index 000000000..25dd718f8
--- /dev/null
+++ b/src/messages/MLock.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) 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 "mds/locks.h"
+#include "mds/SimpleLock.h"
+#include "messages/MMDSOp.h"
+
+class MLock final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ 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;
+
+ ceph::buffer::list lockdata; // and possibly some data
+
+public:
+ ceph::buffer::list& get_data() { return lockdata; }
+ const ceph::buffer::list& 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() : MMDSOp{MSG_MDS_LOCK, HEAD_VERSION, COMPAT_VERSION} {}
+ MLock(int ac, mds_rank_t as) :
+ MMDSOp{MSG_MDS_LOCK, HEAD_VERSION, COMPAT_VERSION},
+ action(ac), asker(as),
+ lock_type(0) { }
+ MLock(SimpleLock *lock, int ac, mds_rank_t as) :
+ MMDSOp{MSG_MDS_LOCK, HEAD_VERSION, COMPAT_VERSION},
+ 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, ceph::buffer::list& bl) :
+ MMDSOp{MSG_MDS_LOCK, HEAD_VERSION, COMPAT_VERSION},
+ action(ac), asker(as), lock_type(lock->get_type()) {
+ lock->get_parent()->set_object_info(object_info);
+ lockdata = std::move(bl);
+ }
+ ~MLock() final {}
+
+public:
+ std::string_view get_type_name() const override { return "ILock"; }
+ void print(std::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 ceph::buffer::list& 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MLog.h b/src/messages/MLog.h
new file mode 100644
index 000000000..e38aab904
--- /dev/null
+++ b/src/messages/MLog.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_MLOG_H
+#define CEPH_MLOG_H
+
+#include "common/LogEntry.h"
+#include "messages/PaxosServiceMessage.h"
+
+#include <deque>
+
+class MLog final : public PaxosServiceMessage {
+public:
+ uuid_d fsid;
+ std::deque<LogEntry> entries;
+
+ MLog() : PaxosServiceMessage{MSG_LOG, 0} {}
+ MLog(const uuid_d& f, std::deque<LogEntry>&& e)
+ : PaxosServiceMessage{MSG_LOG, 0}, fsid(f), entries{std::move(e)} { }
+ MLog(const uuid_d& f) : PaxosServiceMessage(MSG_LOG, 0), fsid(f) { }
+private:
+ ~MLog() final {}
+
+public:
+ std::string_view get_type_name() const override { return "log"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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 000000000..5949157e2
--- /dev/null
+++ b/src/messages/MLogAck.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_MLOGACK_H
+#define CEPH_MLOGACK_H
+
+#include <iostream>
+#include <string>
+#include <string_view>
+
+#include "include/uuid.h"
+
+#include "msg/Message.h"
+
+class MLogAck final : public Message {
+public:
+ uuid_d fsid;
+ version_t last = 0;
+ std::string channel;
+
+ MLogAck() : Message{MSG_LOGACK} {}
+ MLogAck(uuid_d& f, version_t l) : Message{MSG_LOGACK}, fsid(f), last(l) {}
+private:
+ ~MLogAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "log_ack"; }
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSBeacon.h b/src/messages/MMDSBeacon.h
new file mode 100644
index 000000000..bd46926e4
--- /dev/null
+++ b/src/messages/MMDSBeacon.h
@@ -0,0 +1,324 @@
+// -*- 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,
+ MDS_HEALTH_DUMMY, // not a real health warning, for testing
+};
+
+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";
+ case MDS_HEALTH_DUMMY: return "MDS_DUMMY";
+ 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(ceph::buffer::list& 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(ceph::buffer::list::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::vector<MDSHealthMetric> metrics;
+
+ void encode(ceph::buffer::list& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(metrics, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(ceph::buffer::list::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 final : public PaxosServiceMessage {
+private:
+
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 6;
+
+ uuid_d fsid;
+ mds_gid_t global_id = MDS_GID_NONE;
+ std::string name;
+
+ MDSMap::DaemonState state = MDSMap::STATE_NULL;
+ version_t seq = 0;
+
+ CompatSet compat;
+
+ MDSHealth health;
+
+ std::map<std::string, std::string> sys_info;
+
+ uint64_t mds_features = 0;
+
+ std::string fs;
+
+protected:
+ MMDSBeacon() : PaxosServiceMessage(MSG_MDS_BEACON, 0, HEAD_VERSION, COMPAT_VERSION)
+ {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MMDSBeacon(const uuid_d &f, mds_gid_t g, const std::string& n, epoch_t les,
+ MDSMap::DaemonState st, version_t se, uint64_t feat) :
+ PaxosServiceMessage(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() final {}
+
+public:
+ const uuid_d& get_fsid() const { return fsid; }
+ mds_gid_t get_global_id() const { return global_id; }
+ const std::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 std::string& get_fs() const { return fs; }
+ void set_fs(std::string_view s) { fs = s; }
+
+ const std::map<std::string, std::string>& get_sys_info() const { return sys_info; }
+ void set_sys_info(const std::map<std::string, std::string>& i) { sys_info = i; }
+
+ void print(std::ostream& out) const override {
+ out << "mdsbeacon(" << global_id << "/" << name
+ << " " << ceph_mds_state_name(state);
+ if (fs.size()) {
+ out << " fs=" << fs;
+ }
+ out << " 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);
+ encode(fs, 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;
+ }
+ if (header.version >= 8) {
+ decode(fs, p);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSCacheRejoin.h b/src/messages/MMDSCacheRejoin.h
new file mode 100644
index 000000000..6f13ccd10
--- /dev/null
+++ b/src/messages/MMDSCacheRejoin.h
@@ -0,0 +1,366 @@
+// -*- 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 "include/types.h"
+#include "mds/CInode.h"
+#include "mds/CDir.h"
+#include "mds/mdstypes.h"
+#include "messages/MMDSOp.h"
+
+// sent from replica to auth
+
+class MMDSCacheRejoin final : public MMDSOp {
+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(ceph::buffer::list &bl) const {
+ using ceph::encode;
+ encode(nonce, bl);
+ encode(caps_wanted, bl);
+ encode(filelock, bl);
+ encode(nestlock, bl);
+ encode(dftlock, bl);
+ }
+ void decode(ceph::buffer::list::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(ceph::buffer::list &bl) const {
+ using ceph::encode;
+ encode(nonce, bl);
+ encode(dir_rep, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &bl) {
+ using ceph::decode;
+ decode(nonce, bl);
+ decode(dir_rep, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(dirfrag_strong)
+
+ struct dn_strong {
+ snapid_t first;
+ std::string alternate_name;
+ inodeno_t ino = 0;
+ inodeno_t remote_ino = 0;
+ unsigned char remote_d_type = 0;
+ uint32_t nonce = 0;
+ int32_t lock = 0;
+ dn_strong() = default;
+ dn_strong(snapid_t f, std::string_view altn, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int l) :
+ first(f), alternate_name(altn), 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(ceph::buffer::list &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);
+ encode(alternate_name, bl);
+ }
+ void decode(ceph::buffer::list::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);
+ decode(alternate_name, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(dn_strong)
+
+ struct dn_weak {
+ snapid_t first;
+ inodeno_t ino = 0;
+ dn_weak() = default;
+ dn_weak(snapid_t f, inodeno_t pi) : first(f), ino(pi) {}
+ void encode(ceph::buffer::list &bl) const {
+ using ceph::encode;
+ encode(first, bl);
+ encode(ino, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &bl) {
+ using ceph::decode;
+ decode(first, bl);
+ decode(ino, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(dn_weak)
+
+ struct lock_bls {
+ ceph::buffer::list file, nest, dft;
+ void encode(ceph::buffer::list& bl) const {
+ using ceph::encode;
+ encode(file, bl);
+ encode(nest, bl);
+ encode(dft, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ using ceph::decode;
+ decode(file, bl);
+ decode(nest, bl);
+ decode(dft, bl);
+ }
+ };
+ WRITE_CLASS_ENCODER(lock_bls)
+
+ // authpins, xlocks
+ struct peer_reqid {
+ metareqid_t reqid;
+ __u32 attempt;
+ peer_reqid() : attempt(0) {}
+ peer_reqid(const metareqid_t& r, __u32 a)
+ : reqid(r), attempt(a) {}
+ void encode(ceph::buffer::list& bl) const {
+ using ceph::encode;
+ encode(reqid, bl);
+ encode(attempt, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ using ceph::decode;
+ decode(reqid, bl);
+ decode(attempt, bl);
+ }
+ };
+
+ std::string_view get_type_name() const override { return "cache_rejoin"; }
+ void print(std::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, ceph::buffer::list& bl) {
+ using ceph::encode;
+ encode(in->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->ino(), inode_base);
+ encode(in->last, inode_base);
+ ceph::buffer::list 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(peer_reqid(ri, attempt));
+ }
+ void add_inode_frozen_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) {
+ frozen_authpin_inodes[ino] = peer_reqid(ri, attempt);
+ }
+ void add_inode_xlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) {
+ xlocked_inodes[ino][lt] = peer_reqid(ri, attempt);
+ }
+ void add_inode_wrlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) {
+ wrlocked_inodes[ino][lt].push_back(peer_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) {
+ ceph::buffer::list& 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, std::string_view altn, snapid_t first, snapid_t last, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int ls) {
+ auto& m = strong_dentries[df];
+ m.insert_or_assign(string_snap_t(dname, last), dn_strong(first, altn, 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(peer_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)] = peer_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);
+ }
+
+ // -- data --
+ int32_t op = 0;
+
+ // weak
+ std::map<inodeno_t, std::map<string_snap_t, dn_weak> > weak;
+ std::set<dirfrag_t> weak_dirfrags;
+ std::set<vinodeno_t> weak_inodes;
+ std::map<inodeno_t, lock_bls> inode_scatterlocks;
+
+ // strong
+ std::map<dirfrag_t, dirfrag_strong> strong_dirfrags;
+ std::map<dirfrag_t, std::map<string_snap_t, dn_strong> > strong_dentries;
+ std::map<vinodeno_t, inode_strong> strong_inodes;
+
+ // open
+ std::map<inodeno_t,std::map<client_t, cap_reconnect_t> > cap_exports;
+ std::map<client_t, entity_inst_t> client_map;
+ std::map<client_t,client_metadata_t> client_metadata_map;
+ ceph::buffer::list imported_caps;
+
+ // full
+ ceph::buffer::list inode_base;
+ ceph::buffer::list inode_locks;
+ std::map<dirfrag_t, ceph::buffer::list> dirfrag_bases;
+
+ std::map<vinodeno_t, std::list<peer_reqid> > authpinned_inodes;
+ std::map<vinodeno_t, peer_reqid> frozen_authpin_inodes;
+ std::map<vinodeno_t, std::map<__s32, peer_reqid> > xlocked_inodes;
+ std::map<vinodeno_t, std::map<__s32, std::list<peer_reqid> > > wrlocked_inodes;
+ std::map<dirfrag_t, std::map<string_snap_t, std::list<peer_reqid> > > authpinned_dentries;
+ std::map<dirfrag_t, std::map<string_snap_t, peer_reqid> > xlocked_dentries;
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ MMDSCacheRejoin(int o) : MMDSCacheRejoin() { op = o; }
+ MMDSCacheRejoin() : MMDSOp{MSG_MDS_CACHEREJOIN, HEAD_VERSION, COMPAT_VERSION} {}
+ ~MMDSCacheRejoin() final {}
+};
+
+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::peer_reqid)
+
+inline std::ostream& operator<<(std::ostream& out, const MMDSCacheRejoin::peer_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 000000000..09f8e72ff
--- /dev/null
+++ b/src/messages/MMDSFindIno.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_MDSFINDINO_H
+#define CEPH_MDSFINDINO_H
+
+#include "include/filepath.h"
+#include "messages/MMDSOp.h"
+
+class MMDSFindIno final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ ceph_tid_t tid {0};
+ inodeno_t ino;
+
+protected:
+ MMDSFindIno() : MMDSOp{MSG_MDS_FINDINO, HEAD_VERSION, COMPAT_VERSION} {}
+ MMDSFindIno(ceph_tid_t t, inodeno_t i) : MMDSOp{MSG_MDS_FINDINO, HEAD_VERSION, COMPAT_VERSION}, tid(t), ino(i) {}
+ ~MMDSFindIno() final {}
+
+public:
+ std::string_view get_type_name() const override { return "findino"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(tid, p);
+ decode(ino, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSFindInoReply.h b/src/messages/MMDSFindInoReply.h
new file mode 100644
index 000000000..eef8e6926
--- /dev/null
+++ b/src/messages/MMDSFindInoReply.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_MDSFINDINOREPLY_H
+#define CEPH_MDSFINDINOREPLY_H
+
+#include "include/filepath.h"
+#include "messages/MMDSOp.h"
+
+class MMDSFindInoReply final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ ceph_tid_t tid = 0;
+ filepath path;
+
+protected:
+ MMDSFindInoReply() : MMDSOp{MSG_MDS_FINDINOREPLY, HEAD_VERSION, COMPAT_VERSION} {}
+ MMDSFindInoReply(ceph_tid_t t) : MMDSOp{MSG_MDS_FINDINOREPLY, HEAD_VERSION, COMPAT_VERSION}, tid(t) {}
+ ~MMDSFindInoReply() final {}
+
+public:
+ std::string_view get_type_name() const override { return "findinoreply"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(tid, p);
+ decode(path, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSFragmentNotify.h b/src/messages/MMDSFragmentNotify.h
new file mode 100644
index 000000000..7ae5829f9
--- /dev/null
+++ b/src/messages/MMDSFragmentNotify.h
@@ -0,0 +1,76 @@
+// -*- 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 "messages/MMDSOp.h"
+
+class MMDSFragmentNotify final : public MMDSOp {
+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; }
+
+ ceph::buffer::list basebl;
+
+protected:
+ MMDSFragmentNotify() :
+ MMDSOp{MSG_MDS_FRAGMENTNOTIFY, HEAD_VERSION, COMPAT_VERSION} {}
+ MMDSFragmentNotify(dirfrag_t df, int b, uint64_t tid) :
+ MMDSOp{MSG_MDS_FRAGMENTNOTIFY, HEAD_VERSION, COMPAT_VERSION},
+ base_dirfrag(df), bits(b) {
+ set_tid(tid);
+ }
+ ~MMDSFragmentNotify() final {}
+
+public:
+ std::string_view get_type_name() const override { return "fragment_notify"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(base_dirfrag, p);
+ decode(bits, p);
+ decode(basebl, p);
+ if (header.version >= 2)
+ decode(ack_wanted, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSFragmentNotifyAck.h b/src/messages/MMDSFragmentNotifyAck.h
new file mode 100644
index 000000000..4d60a732e
--- /dev/null
+++ b/src/messages/MMDSFragmentNotifyAck.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_MMDSFRAGMENTNOTIFYAck_H
+#define CEPH_MMDSFRAGMENTNOTIFYAck_H
+
+#include "messages/MMDSOp.h"
+
+class MMDSFragmentNotifyAck final : public MMDSOp {
+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; }
+
+ ceph::buffer::list basebl;
+
+protected:
+ MMDSFragmentNotifyAck() : MMDSOp{MSG_MDS_FRAGMENTNOTIFYACK} {}
+ MMDSFragmentNotifyAck(dirfrag_t df, int b, uint64_t tid) :
+ MMDSOp{MSG_MDS_FRAGMENTNOTIFYACK},
+ base_dirfrag(df), bits(b) {
+ set_tid(tid);
+ }
+ ~MMDSFragmentNotifyAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "fragment_notify_ack"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(base_dirfrag, p);
+ decode(bits, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSLoadTargets.h b/src/messages/MMDSLoadTargets.h
new file mode 100644
index 000000000..bab923db0
--- /dev/null
+++ b/src/messages/MMDSLoadTargets.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) 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 final : public PaxosServiceMessage {
+public:
+ mds_gid_t global_id;
+ std::set<mds_rank_t> targets;
+
+protected:
+ MMDSLoadTargets() : PaxosServiceMessage(MSG_MDS_OFFLOAD_TARGETS, 0) {}
+ MMDSLoadTargets(mds_gid_t g, std::set<mds_rank_t>& mds_targets) :
+ PaxosServiceMessage(MSG_MDS_OFFLOAD_TARGETS, 0),
+ global_id(g), targets(mds_targets) {}
+ ~MMDSLoadTargets() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mds_load_targets"; }
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSMap.h b/src/messages/MMDSMap.h
new file mode 100644
index 000000000..c3bf2bc5a
--- /dev/null
+++ b/src/messages/MMDSMap.h
@@ -0,0 +1,89 @@
+// -*- 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 final : public SafeMessage {
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ uuid_d fsid;
+ epoch_t epoch = 0;
+ ceph::buffer::list encoded;
+ std::string map_fs_name;
+
+ version_t get_epoch() const { return epoch; }
+ const ceph::buffer::list& get_encoded() const { return encoded; }
+
+protected:
+ MMDSMap() :
+ SafeMessage{CEPH_MSG_MDS_MAP, HEAD_VERSION, COMPAT_VERSION} {}
+
+ MMDSMap(const uuid_d &f, const MDSMap &mm,
+ const std::string mf = std::string()) :
+ SafeMessage{CEPH_MSG_MDS_MAP, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), map_fs_name(mf) {
+ epoch = mm.get_epoch();
+ mm.encode(encoded, -1); // we will reencode with fewer features as necessary
+ }
+
+ ~MMDSMap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mdsmap"; }
+ void print(std::ostream& out) const override {
+ out << "mdsmap(e " << epoch << ")";
+ }
+
+ // marshalling
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(epoch, p);
+ decode(encoded, p);
+ if (header.version >= 2) {
+ decode(map_fs_name, 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);
+ encode(map_fs_name, payload);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSMetrics.h b/src/messages/MMDSMetrics.h
new file mode 100644
index 000000000..1cb741880
--- /dev/null
+++ b/src/messages/MMDSMetrics.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_MDS_METRICS_H
+#define CEPH_MDS_METRICS_H
+
+#include "messages/MMDSOp.h"
+#include "mds/MDSPerfMetricTypes.h"
+
+class MMDSMetrics final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ // metrics messsage (client -> metrics map, rank, etc..)
+ metrics_message_t metrics_message;
+
+protected:
+ MMDSMetrics() : MMDSOp(MSG_MDS_METRICS, HEAD_VERSION, COMPAT_VERSION) {
+ }
+ MMDSMetrics(metrics_message_t metrics_message)
+ : MMDSOp(MSG_MDS_METRICS, HEAD_VERSION, COMPAT_VERSION),
+ metrics_message(metrics_message) {
+ }
+ ~MMDSMetrics() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "mds_metrics";
+ }
+
+ void print(ostream &out) const override {
+ out << "mds_metrics from rank=" << metrics_message.rank << " carrying "
+ << metrics_message.client_metrics_map.size() << " metric updates";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(metrics_message, payload, features);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto iter = payload.cbegin();
+ decode(metrics_message, iter);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif // CEPH_MDS_METRICS_H
diff --git a/src/messages/MMDSOp.h b/src/messages/MMDSOp.h
new file mode 100644
index 000000000..53a67ea85
--- /dev/null
+++ b/src/messages/MMDSOp.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "msg/Message.h"
+
+/*
+ * MMDSOp is used to ensure that all incoming MDS-MDS
+ * messages in MDSRankDispatcher are versioned. Therefore
+ * all MDS-MDS messages must be of type MMDSOp.
+ */
+class MMDSOp : public SafeMessage {
+public:
+ template<typename... Types>
+ MMDSOp(Types&&... args)
+ : SafeMessage(std::forward<Types>(args)...) {}
+};
diff --git a/src/messages/MMDSOpenIno.h b/src/messages/MMDSOpenIno.h
new file mode 100644
index 000000000..b51795338
--- /dev/null
+++ b/src/messages/MMDSOpenIno.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) 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 "messages/MMDSOp.h"
+
+class MMDSOpenIno final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ inodeno_t ino;
+ std::vector<inode_backpointer_t> ancestors;
+
+protected:
+ MMDSOpenIno() : MMDSOp{MSG_MDS_OPENINO, HEAD_VERSION, COMPAT_VERSION} {}
+ MMDSOpenIno(ceph_tid_t t, inodeno_t i, std::vector<inode_backpointer_t>* pa) :
+ MMDSOp{MSG_MDS_OPENINO, HEAD_VERSION, COMPAT_VERSION}, ino(i) {
+ header.tid = t;
+ if (pa)
+ ancestors = *pa;
+ }
+ ~MMDSOpenIno() final {}
+
+public:
+ std::string_view get_type_name() const override { return "openino"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(ancestors, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSOpenInoReply.h b/src/messages/MMDSOpenInoReply.h
new file mode 100644
index 000000000..a331b5f8b
--- /dev/null
+++ b/src/messages/MMDSOpenInoReply.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) 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 "messages/MMDSOp.h"
+
+class MMDSOpenInoReply final : public MMDSOp {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+ inodeno_t ino;
+ std::vector<inode_backpointer_t> ancestors;
+ mds_rank_t hint;
+ int32_t error;
+
+protected:
+ MMDSOpenInoReply() : MMDSOp{MSG_MDS_OPENINOREPLY, HEAD_VERSION, COMPAT_VERSION}, error(0) {}
+ MMDSOpenInoReply(ceph_tid_t t, inodeno_t i, mds_rank_t h=MDS_RANK_NONE, int e=0) :
+ MMDSOp{MSG_MDS_OPENINOREPLY, HEAD_VERSION, COMPAT_VERSION}, ino(i), hint(h), error(e) {
+ header.tid = t;
+ }
+
+
+public:
+ std::string_view get_type_name() const override { return "openinoreply"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(ino, p);
+ decode(ancestors, p);
+ decode(hint, p);
+ decode(error, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSPeerRequest.h b/src/messages/MMDSPeerRequest.h
new file mode 100644
index 000000000..389f8b96b
--- /dev/null
+++ b/src/messages/MMDSPeerRequest.h
@@ -0,0 +1,233 @@
+// -*- 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_MMDSPEERREQUEST_H
+#define CEPH_MMDSPEERREQUEST_H
+
+#include "mds/mdstypes.h"
+#include "messages/MMDSOp.h"
+
+class MMDSPeerRequest final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ 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_NONBLOCKING = 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;
+ static constexpr unsigned FLAG_NOTIFYBLOCKING = 1<<6;
+ static constexpr unsigned FLAG_REQBLOCKED = 1<<7;
+
+ // for locking
+ __u16 lock_type; // lock object type
+ MDSCacheObjectInfo object_info;
+
+ // for authpins
+ std::vector<MDSCacheObjectInfo> authpins;
+
+ public:
+ // for rename prep
+ filepath srcdnpath;
+ filepath destdnpath;
+ std::string alternate_name;
+ std::set<mds_rank_t> witnesses;
+ ceph::buffer::list inode_export;
+ version_t inode_export_v;
+ mds_rank_t srcdn_auth;
+ utime_t op_stamp;
+
+ mutable ceph::buffer::list straybl; // stray dir + dentry
+ ceph::buffer::list srci_snapbl;
+ ceph::buffer::list 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 std::vector<MDSCacheObjectInfo>& get_authpins() const { return authpins; }
+ std::vector<MDSCacheObjectInfo>& get_authpins() { return authpins; }
+ void mark_nonblocking() { flags |= FLAG_NONBLOCKING; }
+ bool is_nonblocking() const { return (flags & FLAG_NONBLOCKING); }
+ 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; }
+ bool should_notify_blocking() const { return (flags & FLAG_NOTIFYBLOCKING); }
+ void mark_notify_blocking() { flags |= FLAG_NOTIFYBLOCKING; }
+ void clear_notify_blocking() const { flags &= ~FLAG_NOTIFYBLOCKING; }
+ bool is_req_blocked() const { return (flags & FLAG_REQBLOCKED); }
+ void mark_req_blocked() { flags |= FLAG_REQBLOCKED; }
+
+ void set_lock_type(int t) { lock_type = t; }
+ const ceph::buffer::list& get_lock_data() const { return inode_export; }
+ ceph::buffer::list& get_lock_data() { return inode_export; }
+
+protected:
+ MMDSPeerRequest() : MMDSOp{MSG_MDS_PEER_REQUEST, HEAD_VERSION, COMPAT_VERSION} { }
+ MMDSPeerRequest(metareqid_t ri, __u32 att, int o) :
+ MMDSOp{MSG_MDS_PEER_REQUEST, HEAD_VERSION, COMPAT_VERSION},
+ reqid(ri), attempt(att), op(o), flags(0), lock_type(0),
+ inode_export_v(0), srcdn_auth(MDS_RANK_NONE) { }
+ ~MMDSPeerRequest() final {}
+
+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);
+ encode(alternate_name, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ decode(alternate_name, p);
+ }
+
+ std::string_view get_type_name() const override { return "peer_request"; }
+ void print(std::ostream& out) const override {
+ out << "peer_request(" << reqid
+ << "." << attempt
+ << " " << get_opname(op)
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSPing.h b/src/messages/MMDSPing.h
new file mode 100644
index 000000000..6c1f2f20e
--- /dev/null
+++ b/src/messages/MMDSPing.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_MESSAGES_MMDSPING_H
+#define CEPH_MESSAGES_MMDSPING_H
+
+#include "include/types.h"
+#include "messages/MMDSOp.h"
+
+class MMDSPing final : public MMDSOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ version_t seq;
+
+protected:
+ MMDSPing() : MMDSOp(MSG_MDS_PING, HEAD_VERSION, COMPAT_VERSION) {
+ }
+ MMDSPing(version_t seq)
+ : MMDSOp(MSG_MDS_PING, HEAD_VERSION, COMPAT_VERSION), seq(seq) {
+ }
+ ~MMDSPing() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "mdsping";
+ }
+
+ void print(ostream &out) const override {
+ out << "mdsping";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(seq, payload);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto iter = payload.cbegin();
+ decode(seq, iter);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif // CEPH_MESSAGES_MMDSPING_H
diff --git a/src/messages/MMDSResolve.h b/src/messages/MMDSResolve.h
new file mode 100644
index 000000000..d636bdcd5
--- /dev/null
+++ b/src/messages/MMDSResolve.h
@@ -0,0 +1,160 @@
+// -*- 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 "include/types.h"
+#include "mds/Capability.h"
+#include "messages/MMDSOp.h"
+
+class MMDSResolve final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ std::map<dirfrag_t, std::vector<dirfrag_t>> subtrees;
+ std::map<dirfrag_t, std::vector<dirfrag_t>> ambiguous_imports;
+
+ class peer_inode_cap {
+ public:
+ inodeno_t ino;
+ std::map<client_t,Capability::Export> cap_exports;
+ peer_inode_cap() {}
+ peer_inode_cap(inodeno_t a, map<client_t, Capability::Export> b) : ino(a), cap_exports(b) {}
+ void encode(ceph::buffer::list &bl) const
+ {
+ ENCODE_START(1, 1, bl);
+ encode(ino, bl);
+ encode(cap_exports, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &blp)
+ {
+ DECODE_START(1, blp);
+ decode(ino, blp);
+ decode(cap_exports, blp);
+ DECODE_FINISH(blp);
+ }
+ };
+ WRITE_CLASS_ENCODER(peer_inode_cap)
+
+ struct peer_request {
+ ceph::buffer::list inode_caps;
+ bool committing;
+ peer_request() : committing(false) {}
+ void encode(ceph::buffer::list &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(inode_caps, bl);
+ encode(committing, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(ceph::buffer::list::const_iterator &blp) {
+ DECODE_START(1, blp);
+ decode(inode_caps, blp);
+ decode(committing, blp);
+ DECODE_FINISH(blp);
+ }
+ };
+
+ std::map<metareqid_t, peer_request> peer_requests;
+
+ // table client information
+ struct table_client {
+ __u8 type;
+ std::set<version_t> pending_commits;
+
+ table_client() : type(0) {}
+ table_client(int _type, const std::set<version_t>& commits)
+ : type(_type), pending_commits(commits) {}
+
+ void encode(ceph::buffer::list& bl) const {
+ using ceph::encode;
+ encode(type, bl);
+ encode(pending_commits, bl);
+ }
+ void decode(ceph::buffer::list::const_iterator& bl) {
+ using ceph::decode;
+ decode(type, bl);
+ decode(pending_commits, bl);
+ }
+ };
+
+ std::list<table_client> table_clients;
+
+protected:
+ MMDSResolve() : MMDSOp{MSG_MDS_RESOLVE, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ ~MMDSResolve() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mds_resolve"; }
+
+ void print(std::ostream& out) const override {
+ out << "mds_resolve(" << subtrees.size()
+ << "+" << ambiguous_imports.size()
+ << " subtrees +" << peer_requests.size() << " peer 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 std::vector<dirfrag_t>& m) {
+ ambiguous_imports[im] = m;
+ }
+
+ void add_peer_request(metareqid_t reqid, bool committing) {
+ peer_requests[reqid].committing = committing;
+ }
+
+ void add_peer_request(metareqid_t reqid, ceph::buffer::list& bl) {
+ peer_requests[reqid].inode_caps = std::move(bl);
+ }
+
+ void add_table_commits(int table, const std::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(peer_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(peer_requests, p);
+ decode(table_clients, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+inline std::ostream& operator<<(std::ostream& out, const MMDSResolve::peer_request&) {
+ return out;
+}
+
+WRITE_CLASS_ENCODER(MMDSResolve::peer_request)
+WRITE_CLASS_ENCODER(MMDSResolve::table_client)
+WRITE_CLASS_ENCODER(MMDSResolve::peer_inode_cap)
+#endif
diff --git a/src/messages/MMDSResolveAck.h b/src/messages/MMDSResolveAck.h
new file mode 100644
index 000000000..727f83f45
--- /dev/null
+++ b/src/messages/MMDSResolveAck.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_MMDSRESOLVEACK_H
+#define CEPH_MMDSRESOLVEACK_H
+
+#include "include/types.h"
+#include "messages/MMDSOp.h"
+
+
+class MMDSResolveAck final : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ std::map<metareqid_t, ceph::buffer::list> commit;
+ std::vector<metareqid_t> abort;
+
+protected:
+ MMDSResolveAck() : MMDSOp{MSG_MDS_RESOLVEACK, HEAD_VERSION, COMPAT_VERSION} {}
+ ~MMDSResolveAck() final {}
+
+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 +" << peer_requests.size() << " peer 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSScrub.h b/src/messages/MMDSScrub.h
new file mode 100644
index 000000000..b4f4ce55b
--- /dev/null
+++ b/src/messages/MMDSScrub.h
@@ -0,0 +1,138 @@
+// -*- 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_MMDSSCRUB_H
+#define CEPH_MMDSSCRUB_H
+
+#include "messages/MMDSOp.h"
+
+#include "include/types.h"
+#include "include/frag.h"
+
+class MMDSScrub : public MMDSOp {
+public:
+ static constexpr int OP_QUEUEDIR = 1;
+ static constexpr int OP_QUEUEDIR_ACK = -1;
+ static constexpr int OP_QUEUEINO = 2;
+ static constexpr int OP_QUEUEINO_ACK = -2;
+ static constexpr int OP_ABORT = 3;
+ static constexpr int OP_PAUSE = 4;
+ static constexpr int OP_RESUME = 5;
+
+ static const char *get_opname(int o) {
+ switch (o) {
+ case OP_QUEUEDIR: return "queue_dir";
+ case OP_QUEUEDIR_ACK: return "queue_dir_ack";
+ case OP_QUEUEINO: return "queue_ino";
+ case OP_QUEUEINO_ACK: return "queue_ino_ack";
+ case OP_ABORT: return "abort";
+ case OP_PAUSE: return "pause";
+ case OP_RESUME: return "resume";
+ default: ceph_abort(); return nullptr;
+ }
+ }
+
+ std::string_view get_type_name() const override { return "mds_scrub"; }
+
+ void print(std::ostream& out) const override {
+ out << "mds_scrub(" << get_opname(op) << " "
+ << ino << " " << frags << " " << tag;
+ if (is_force()) out << " force";
+ if (is_recursive()) out << " recursive";
+ if (is_repair()) out << " repair";
+ out << ")";
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(ino, payload);
+ encode(frags, payload);
+ encode(tag, payload);
+ encode(origin, payload);
+ encode(flags, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(ino, p);
+ decode(frags, p);
+ decode(tag, p);
+ decode(origin, p);
+ decode(flags, p);
+ }
+ inodeno_t get_ino() const {
+ return ino;
+ }
+ const fragset_t& get_frags() const {
+ return frags;
+ }
+ const std::string& get_tag() const {
+ return tag;
+ }
+ inodeno_t get_origin() const {
+ return origin;
+ }
+ int get_op() const {
+ return op;
+ }
+ bool is_internal_tag() const {
+ return flags & FLAG_INTERNAL_TAG;
+ }
+ bool is_force() const {
+ return flags & FLAG_FORCE;
+ }
+ bool is_recursive() const {
+ return flags & FLAG_RECURSIVE;
+ }
+ bool is_repair() const {
+ return flags & FLAG_REPAIR;
+ }
+
+protected:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ MMDSScrub() : MMDSOp(MSG_MDS_SCRUB, HEAD_VERSION, COMPAT_VERSION) {}
+ MMDSScrub(int o)
+ : MMDSOp(MSG_MDS_SCRUB, HEAD_VERSION, COMPAT_VERSION), op(o) {}
+ MMDSScrub(int o, inodeno_t i, fragset_t&& _frags, std::string_view _tag,
+ inodeno_t _origin=inodeno_t(), bool internal_tag=false,
+ bool force=false, bool recursive=false, bool repair=false)
+ : MMDSOp(MSG_MDS_SCRUB, HEAD_VERSION, COMPAT_VERSION),
+ op(o), ino(i), frags(std::move(_frags)), tag(_tag), origin(_origin) {
+ if (internal_tag) flags |= FLAG_INTERNAL_TAG;
+ if (force) flags |= FLAG_FORCE;
+ if (recursive) flags |= FLAG_RECURSIVE;
+ if (repair) flags |= FLAG_REPAIR;
+ }
+
+ ~MMDSScrub() override {}
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+
+ static constexpr unsigned FLAG_INTERNAL_TAG = 1<<0;
+ static constexpr unsigned FLAG_FORCE = 1<<1;
+ static constexpr unsigned FLAG_RECURSIVE = 1<<2;
+ static constexpr unsigned FLAG_REPAIR = 1<<3;
+
+ int op;
+ inodeno_t ino;
+ fragset_t frags;
+ std::string tag;
+ inodeno_t origin;
+ unsigned flags = 0;
+};
+#endif // CEPH_MMDSSCRUB_H
diff --git a/src/messages/MMDSScrubStats.h b/src/messages/MMDSScrubStats.h
new file mode 100644
index 000000000..41c403ade
--- /dev/null
+++ b/src/messages/MMDSScrubStats.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_MMDSSCRUBSTATS_H
+#define CEPH_MMDSSCRUBSTATS_H
+
+#include "messages/MMDSOp.h"
+
+class MMDSScrubStats : public MMDSOp {
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ std::string_view get_type_name() const override { return "mds_scrub_stats"; }
+ void print(ostream& o) const override {
+ o << "mds_scrub_stats(e" << epoch;
+ if (update_scrubbing)
+ o << " [" << scrubbing_tags << "]";
+ if (aborting)
+ o << " aborting";
+ o << ")";
+ }
+
+ unsigned get_epoch() const { return epoch; }
+ const auto& get_scrubbing_tags() const { return scrubbing_tags; }
+ bool is_aborting() const { return aborting; }
+ bool is_finished(const std::string& tag) const {
+ return update_scrubbing && !scrubbing_tags.count(tag);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(scrubbing_tags, payload);
+ encode(update_scrubbing, payload);
+ encode(aborting, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(scrubbing_tags, p);
+ decode(update_scrubbing, p);
+ decode(aborting, p);
+ }
+
+protected:
+ MMDSScrubStats(unsigned e=0) :
+ MMDSOp(MSG_MDS_SCRUB_STATS, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e) {}
+ MMDSScrubStats(unsigned e, std::set<std::string>&& tags, bool abrt=false) :
+ MMDSOp(MSG_MDS_SCRUB_STATS, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e), scrubbing_tags(std::move(tags)), update_scrubbing(true), aborting(abrt) {}
+ MMDSScrubStats(unsigned e, const std::set<std::string>& tags, bool abrt=false) :
+ MMDSOp(MSG_MDS_SCRUB_STATS, HEAD_VERSION, COMPAT_VERSION),
+ epoch(e), scrubbing_tags(tags), update_scrubbing(true), aborting(abrt) {}
+ ~MMDSScrubStats() override {}
+
+private:
+ unsigned epoch;
+ std::set<std::string> scrubbing_tags;
+ bool update_scrubbing = false;
+ bool aborting = false;
+
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSSnapUpdate.h b/src/messages/MMDSSnapUpdate.h
new file mode 100644
index 000000000..51b976024
--- /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 "messages/MMDSOp.h"
+
+class MMDSSnapUpdate final : public MMDSOp {
+private:
+ inodeno_t ino;
+ __s16 snap_op;
+
+public:
+ inodeno_t get_ino() const { return ino; }
+ int get_snap_op() const { return snap_op; }
+
+ ceph::buffer::list snap_blob;
+
+protected:
+ MMDSSnapUpdate() : MMDSOp{MSG_MDS_SNAPUPDATE} {}
+ MMDSSnapUpdate(inodeno_t i, version_t tid, int op) :
+ MMDSOp{MSG_MDS_SNAPUPDATE}, ino(i), snap_op(op) {
+ set_tid(tid);
+ }
+ ~MMDSSnapUpdate() final {}
+
+public:
+ std::string_view get_type_name() const override { return "snap_update"; }
+ void print(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMDSTableRequest.h b/src/messages/MMDSTableRequest.h
new file mode 100644
index 000000000..365d5fb59
--- /dev/null
+++ b/src/messages/MMDSTableRequest.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_MMDSTABLEREQUEST_H
+#define CEPH_MMDSTABLEREQUEST_H
+
+#include "mds/mds_table_types.h"
+#include "messages/MMDSOp.h"
+
+class MMDSTableRequest final : public MMDSOp {
+public:
+ __u16 table = 0;
+ __s16 op = 0;
+ uint64_t reqid = 0;
+ ceph::buffer::list bl;
+
+protected:
+ MMDSTableRequest() : MMDSOp{MSG_MDS_TABLE_REQUEST} {}
+ MMDSTableRequest(int tab, int o, uint64_t r, version_t v=0) :
+ MMDSOp{MSG_MDS_TABLE_REQUEST},
+ table(tab), op(o), reqid(r) {
+ set_tid(v);
+ }
+ ~MMDSTableRequest() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mds_table_request"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMgrBeacon.h b/src/messages/MMgrBeacon.h
new file mode 100644
index 000000000..5b6ca3b60
--- /dev/null
+++ b/src/messages/MMgrBeacon.h
@@ -0,0 +1,206 @@
+// -*- 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 final : public PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 10;
+ 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;
+
+ std::map<std::string,std::string> metadata; ///< misc metadata about this osd
+
+ std::vector<entity_addrvec_t> clients;
+
+ uint64_t mgr_features = 0; ///< reporting mgr's features
+
+public:
+ MMgrBeacon()
+ : PaxosServiceMessage{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_,
+ std::map<std::string,std::string>&& metadata_,
+ std::vector<entity_addrvec_t> clients,
+ uint64_t feat)
+ : PaxosServiceMessage{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_)),
+ clients(std::move(clients)),
+ mgr_features(feat)
+ {
+ }
+
+ 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;
+ }
+ uint64_t get_mgr_features() const { return mgr_features; }
+
+ 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;
+ }
+
+ const auto& get_clients() const
+ {
+ return clients;
+ }
+
+private:
+ ~MMgrBeacon() final {}
+
+public:
+
+ std::string_view get_type_name() const override { return "mgrbeacon"; }
+
+ void print(std::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);
+ encode(mgr_features, payload);
+ encode(clients, payload, features);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+ if (header.version >= 9) {
+ decode(mgr_features, p);
+ }
+ if (header.version >= 10) {
+ decode(clients, p);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+
+#endif
diff --git a/src/messages/MMgrClose.h b/src/messages/MMgrClose.h
new file mode 100644
index 000000000..680ce273c
--- /dev/null
+++ b/src/messages/MMgrClose.h
@@ -0,0 +1,51 @@
+// -*- 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 Message {
+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
+ {
+ using ceph::decode;
+ 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(std::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()
+ : Message{MSG_MGR_CLOSE, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MMgrCommand.h b/src/messages/MMgrCommand.h
new file mode 100644
index 000000000..83ee618c5
--- /dev/null
+++ b/src/messages/MMgrCommand.h
@@ -0,0 +1,46 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <vector>
+
+#include "msg/Message.h"
+
+class MMgrCommand final : public Message {
+public:
+ uuid_d fsid;
+ std::vector<std::string> cmd;
+
+ MMgrCommand()
+ : Message{MSG_MGR_COMMAND} {}
+ MMgrCommand(const uuid_d &f)
+ : Message{MSG_MGR_COMMAND},
+ fsid(f) { }
+
+private:
+ ~MMgrCommand() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mgr_command"; }
+ void print(std::ostream& o) const override {
+ o << "mgr_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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(cmd, p);
+ }
+};
diff --git a/src/messages/MMgrCommandReply.h b/src/messages/MMgrCommandReply.h
new file mode 100644
index 000000000..40b8fd34d
--- /dev/null
+++ b/src/messages/MMgrCommandReply.h
@@ -0,0 +1,45 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <string_view>
+
+#include "msg/Message.h"
+#include "MMgrCommand.h"
+
+class MMgrCommandReply final : public Message {
+public:
+ errorcode32_t r;
+ std::string rs;
+
+ MMgrCommandReply()
+ : Message{MSG_MGR_COMMAND_REPLY} {}
+ MMgrCommandReply(MMgrCommand *m, int _r)
+ : Message{MSG_MGR_COMMAND_REPLY}, r(_r) {
+ header.tid = m->get_tid();
+ }
+ MMgrCommandReply(int _r, std::string_view s)
+ : Message{MSG_MGR_COMMAND_REPLY},
+ r(_r), rs(s) { }
+private:
+ ~MMgrCommandReply() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mgr_command_reply"; }
+ void print(std::ostream& o) const override {
+ o << "mgr_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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(r, p);
+ decode(rs, p);
+ }
+};
diff --git a/src/messages/MMgrConfigure.h b/src/messages/MMgrConfigure.h
new file mode 100644
index 000000000..7b27c9064
--- /dev/null
+++ b/src/messages/MMgrConfigure.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) 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/MetricTypes.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 Message {
+private:
+ static constexpr int HEAD_VERSION = 4;
+ 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;
+
+ boost::optional<MetricConfigMessage> metric_config_message;
+
+ void decode_payload() override
+ {
+ using ceph::decode;
+ 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);
+ }
+ if (header.version >= 4) {
+ decode(metric_config_message, 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);
+ if (metric_config_message && metric_config_message->should_encode(features)) {
+ encode(metric_config_message, payload);
+ } else {
+ boost::optional<MetricConfigMessage> empty;
+ encode(empty, payload);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "mgrconfigure"; }
+ void print(std::ostream& out) const override {
+ out << get_type_name() << "(period=" << stats_period
+ << ", threshold=" << stats_threshold << ")";
+ }
+
+private:
+ MMgrConfigure()
+ : Message{MSG_MGR_CONFIGURE, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
+
diff --git a/src/messages/MMgrDigest.h b/src/messages/MMgrDigest.h
new file mode 100644
index 000000000..69f336868
--- /dev/null
+++ b/src/messages/MMgrDigest.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_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 final : public Message {
+public:
+ ceph::buffer::list mon_status_json;
+ ceph::buffer::list health_json;
+
+ std::string_view get_type_name() const override { return "mgrdigest"; }
+ void print(std::ostream& out) const override {
+ out << get_type_name();
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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() :
+ Message{MSG_MGR_DIGEST} {}
+ ~MMgrDigest() final {}
+
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMgrMap.h b/src/messages/MMgrMap.h
new file mode 100644
index 000000000..9f16130be
--- /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 final : public Message {
+protected:
+ MgrMap map;
+
+public:
+ const MgrMap & get_map() {return map;}
+
+private:
+ MMgrMap() :
+ Message{MSG_MGR_MAP} {}
+ MMgrMap(const MgrMap &map_) :
+ Message{MSG_MGR_MAP}, map(map_)
+ {}
+ ~MMgrMap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mgrmap"; }
+ void print(std::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);
+ }
+private:
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMgrOpen.h b/src/messages/MMgrOpen.h
new file mode 100644
index 000000000..c5061a281
--- /dev/null
+++ b/src/messages/MMgrOpen.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) 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 Message {
+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
+ ceph::buffer::list config_bl;
+
+ // encode map<string,string> of compiled-in defaults
+ ceph::buffer::list config_defaults_bl;
+
+ void decode_payload() override
+ {
+ using ceph::decode;
+ 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(std::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 << ")";
+ }
+
+private:
+ MMgrOpen()
+ : Message{MSG_MGR_OPEN, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
+
diff --git a/src/messages/MMgrReport.h b/src/messages/MMgrReport.h
new file mode 100644
index 000000000..5cd5f3d54
--- /dev/null
+++ b/src/messages/MMgrReport.h
@@ -0,0 +1,202 @@
+// -*- 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/MetricTypes.h"
+#include "mgr/OSDPerfMetricTypes.h"
+
+#include "common/perf_counters.h"
+#include "include/common_fwd.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(ceph::buffer::list &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(ceph::buffer::list::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 Message {
+private:
+ static constexpr int HEAD_VERSION = 9;
+ 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 ceph::buffer::list.
+ ceph::buffer::list 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
+ ceph::buffer::list config_bl;
+
+ std::map<OSDPerfMetricQuery, OSDPerfMetricReport> osd_perf_metric_reports;
+
+ boost::optional<MetricReportMessage> metric_report_message;
+
+ void decode_payload() override
+ {
+ using ceph::decode;
+ 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);
+ }
+ if (header.version >= 9) {
+ decode(metric_report_message, 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);
+ if (metric_report_message && metric_report_message->should_encode(features)) {
+ encode(metric_report_message, payload);
+ } else {
+ boost::optional<MetricReportMessage> empty;
+ encode(empty, payload);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "mgrreport"; }
+ void print(std::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 << ")";
+ }
+
+private:
+ MMgrReport()
+ : Message{MSG_MGR_REPORT, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMgrUpdate.h b/src/messages/MMgrUpdate.h
new file mode 100644
index 000000000..5e1f27b5f
--- /dev/null
+++ b/src/messages/MMgrUpdate.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) 2022 Prashant D <pdhange@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_MMGRUPDATE_H_
+#define CEPH_MMGRUPDATE_H_
+
+#include "msg/Message.h"
+
+class MMgrUpdate : public Message {
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+
+ std::string daemon_name;
+ std::string service_name; // optional; otherwise infer from entity type
+
+ std::map<std::string,std::string> daemon_metadata;
+ std::map<std::string,std::string> daemon_status;
+
+ bool need_metadata_update = false;
+
+ void decode_payload() override
+ {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(daemon_name, p);
+ if (header.version >= 2) {
+ decode(service_name, p);
+ decode(need_metadata_update, p);
+ if (need_metadata_update) {
+ decode(daemon_metadata, p);
+ decode(daemon_status, p);
+ }
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(daemon_name, payload);
+ encode(service_name, payload);
+ encode(need_metadata_update, payload);
+ if (need_metadata_update) {
+ encode(daemon_metadata, payload);
+ encode(daemon_status, payload);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "mgrupdate"; }
+ void print(std::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 << ")";
+ }
+
+private:
+ MMgrUpdate()
+ : Message{MSG_MGR_UPDATE, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
+
diff --git a/src/messages/MMonCommand.h b/src/messages/MMonCommand.h
new file mode 100644
index 000000000..494d5cf56
--- /dev/null
+++ b/src/messages/MMonCommand.h
@@ -0,0 +1,89 @@
+// -*- 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 "messages/PaxosServiceMessage.h"
+
+#include <vector>
+#include <string>
+
+using TOPNSPC::common::cmdmap_from_json;
+using TOPNSPC::common::cmd_getval;
+
+class MMonCommand final : public PaxosServiceMessage {
+public:
+ // weird note: prior to octopus, MgrClient would leave fsid blank when
+ // sending commands to the mgr. Starting with octopus, this is either
+ // populated with a valid fsid (tell command) or an MMgrCommand is sent
+ // instead.
+ uuid_d fsid;
+ std::vector<std::string> cmd;
+
+ MMonCommand() : PaxosServiceMessage{MSG_MON_COMMAND, 0} {}
+ MMonCommand(const uuid_d &f)
+ : PaxosServiceMessage{MSG_MON_COMMAND, 0},
+ fsid(f)
+ { }
+
+private:
+ ~MMonCommand() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_command"; }
+ void print(std::ostream& o) const override {
+ cmdmap_t cmdmap;
+ std::ostringstream ss;
+ string prefix;
+ cmdmap_from_json(cmd, &cmdmap, ss);
+ cmd_getval(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(cmdmap, "name", name);
+ o << "[{prefix=" << prefix << ", name=" << name << "}]";
+ } else if (prefix == "config-key set") {
+ string key;
+ cmd_getval(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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(cmd, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonCommandAck.h b/src/messages/MMonCommandAck.h
new file mode 100644
index 000000000..b49e8bcff
--- /dev/null
+++ b/src/messages/MMonCommandAck.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_MMONCOMMANDACK_H
+#define CEPH_MMONCOMMANDACK_H
+
+#include "messages/PaxosServiceMessage.h"
+
+using TOPNSPC::common::cmdmap_from_json;
+using TOPNSPC::common::cmd_getval;
+
+class MMonCommandAck final : public PaxosServiceMessage {
+public:
+ std::vector<std::string> cmd;
+ errorcode32_t r;
+ std::string rs;
+
+ MMonCommandAck() : PaxosServiceMessage{MSG_MON_COMMAND_ACK, 0} {}
+ MMonCommandAck(const std::vector<std::string>& c, int _r, std::string s, version_t v) :
+ PaxosServiceMessage{MSG_MON_COMMAND_ACK, v},
+ cmd(c), r(_r), rs(s) { }
+private:
+ ~MMonCommandAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_command"; }
+ void print(std::ostream& o) const override {
+ cmdmap_t cmdmap;
+ std::ostringstream ss;
+ string prefix;
+ cmdmap_from_json(cmd, &cmdmap, ss);
+ cmd_getval(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(cmdmap, "name", name);
+ o << "[{prefix=" << prefix
+ << ", name=" << name << "}]"
+ << "=" << r << " " << rs << " v" << version << ")";
+ } else if (prefix == "config-key set") {
+ string key;
+ cmd_getval(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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(r, p);
+ decode(rs, p);
+ decode(cmd, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonElection.h b/src/messages/MMonElection.h
new file mode 100644
index 000000000..d50a5c0ff
--- /dev/null
+++ b/src/messages/MMonElection.h
@@ -0,0 +1,144 @@
+// -*- 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 "common/ceph_releases.h"
+#include "msg/Message.h"
+#include "mon/MonMap.h"
+#include "mon/mon_types.h"
+
+class MMonElection final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 9;
+ 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;
+ ceph::buffer::list monmap_bl;
+ std::set<int32_t> quorum;
+ uint64_t quorum_features;
+ mon_feature_t mon_features;
+ ceph_release_t mon_release{ceph_release_t::unknown};
+ ceph::buffer::list sharing_bl;
+ ceph::buffer::list scoring_bl;
+ uint8_t strategy;
+ std::map<std::string,std::string> metadata;
+
+ MMonElection() : Message{MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION},
+ op(0), epoch(0),
+ quorum_features(0),
+ mon_features(0),
+ strategy(0)
+ { }
+
+ MMonElection(int o, epoch_t e, const bufferlist& bl, uint8_t s, MonMap *m)
+ : Message{MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION},
+ fsid(m->fsid), op(o), epoch(e),
+ quorum_features(0),
+ mon_features(0), scoring_bl(bl), strategy(s)
+ {
+ // encode using full feature set; we will reencode for dest later,
+ // if necessary
+ m->encode(monmap_bl, CEPH_FEATURES_ALL);
+ }
+private:
+ ~MMonElection() final {}
+
+public:
+ std::string_view get_type_name() const override { return "election"; }
+ void print(std::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);
+ encode(scoring_bl, payload);
+ encode(strategy, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ if (header.version >= 9) {
+ decode(scoring_bl, p);
+ decode(strategy, p);
+ } else {
+ strategy = MonMap::election_strategy::CLASSIC;
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonGetMap.h b/src/messages/MMonGetMap.h
new file mode 100644
index 000000000..9192da077
--- /dev/null
+++ b/src/messages/MMonGetMap.h
@@ -0,0 +1,39 @@
+// -*- 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 final : public Message {
+public:
+ MMonGetMap() : Message{CEPH_MSG_MON_GET_MAP} { }
+private:
+ ~MMonGetMap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_getmap"; }
+
+ void encode_payload(uint64_t features) override { }
+ void decode_payload() override { }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonGetOSDMap.h b/src/messages/MMonGetOSDMap.h
new file mode 100644
index 000000000..c70938b7e
--- /dev/null
+++ b/src/messages/MMonGetOSDMap.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) 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 <iostream>
+#include <string>
+#include <string_view>
+
+#include "msg/Message.h"
+
+#include "include/types.h"
+
+class MMonGetOSDMap final : public PaxosServiceMessage {
+private:
+ epoch_t full_first, full_last;
+ epoch_t inc_first, inc_last;
+
+public:
+ MMonGetOSDMap()
+ : PaxosServiceMessage{CEPH_MSG_MON_GET_OSDMAP, 0},
+ full_first(0),
+ full_last(0),
+ inc_first(0),
+ inc_last(0) { }
+private:
+ ~MMonGetOSDMap() final {}
+
+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(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonGetPurgedSnaps.h b/src/messages/MMonGetPurgedSnaps.h
new file mode 100644
index 000000000..9b1977e37
--- /dev/null
+++ b/src/messages/MMonGetPurgedSnaps.h
@@ -0,0 +1,45 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "PaxosServiceMessage.h"
+#include "include/types.h"
+
+class MMonGetPurgedSnaps final : public PaxosServiceMessage {
+public:
+ epoch_t start, last;
+
+ MMonGetPurgedSnaps(epoch_t s=0, epoch_t l=0)
+ : PaxosServiceMessage{MSG_MON_GET_PURGED_SNAPS, 0},
+ start(s),
+ last(l) {}
+private:
+ ~MMonGetPurgedSnaps() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "mon_get_purged_snaps";
+ }
+ void print(std::ostream& out) const override {
+ out << "mon_get_purged_snaps([" << start << "," << last << "])";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(start, payload);
+ encode(last, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(start, p);
+ decode(last, p);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MMonGetPurgedSnapsReply.h b/src/messages/MMonGetPurgedSnapsReply.h
new file mode 100644
index 000000000..7810ab6d7
--- /dev/null
+++ b/src/messages/MMonGetPurgedSnapsReply.h
@@ -0,0 +1,49 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "PaxosServiceMessage.h"
+#include "osd/osd_types.h"
+#include "include/types.h"
+
+class MMonGetPurgedSnapsReply final : public PaxosServiceMessage {
+public:
+ epoch_t start, last;
+ std::map<epoch_t,mempool::osdmap::map<int64_t,snap_interval_set_t>> purged_snaps;
+
+ MMonGetPurgedSnapsReply(epoch_t s=0, epoch_t l=0)
+ : PaxosServiceMessage{MSG_MON_GET_PURGED_SNAPS_REPLY, 0},
+ start(s),
+ last(l) {}
+private:
+ ~MMonGetPurgedSnapsReply() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "mon_get_purged_snaps_reply";
+ }
+ void print(std::ostream& out) const override {
+ out << "mon_get_purged_snaps_reply([" << start << "," << last << "])";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(start, payload);
+ encode(last, payload);
+ encode(purged_snaps, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(start, p);
+ decode(last, p);
+ decode(purged_snaps, p);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MMonGetVersion.h b/src/messages/MMonGetVersion.h
new file mode 100644
index 000000000..ad91cd155
--- /dev/null
+++ b/src/messages/MMonGetVersion.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_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 final : public Message {
+public:
+ MMonGetVersion() : Message{CEPH_MSG_MON_GET_VERSION} {}
+
+ std::string_view get_type_name() const override {
+ return "mon_get_version";
+ }
+
+ void print(std::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();
+ using ceph::decode;
+ decode(handle, p);
+ decode(what, p);
+ }
+
+ ceph_tid_t handle = 0;
+ std::string what;
+
+private:
+ ~MMonGetVersion() final {}
+};
+
+#endif
diff --git a/src/messages/MMonGetVersionReply.h b/src/messages/MMonGetVersionReply.h
new file mode 100644
index 000000000..407b449a0
--- /dev/null
+++ b/src/messages/MMonGetVersionReply.h
@@ -0,0 +1,66 @@
+// -*- 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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 2;
+
+public:
+ MMonGetVersionReply() : Message{CEPH_MSG_MON_GET_VERSION_REPLY, HEAD_VERSION} { }
+
+ std::string_view get_type_name() const override {
+ return "mon_get_version_reply";
+ }
+
+ void print(std::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 {
+ using ceph::decode;
+ 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() final {}
+};
+
+#endif
diff --git a/src/messages/MMonGlobalID.h b/src/messages/MMonGlobalID.h
new file mode 100644
index 000000000..4330974e0
--- /dev/null
+++ b/src/messages/MMonGlobalID.h
@@ -0,0 +1,50 @@
+// -*- 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 final : public PaxosServiceMessage {
+public:
+ uint64_t old_max_id = 0;
+ MMonGlobalID() : PaxosServiceMessage{MSG_MON_GLOBAL_ID, 0}
+ {}
+private:
+ ~MMonGlobalID() final {}
+
+public:
+ std::string_view get_type_name() const override { return "global_id"; }
+ void print(std::ostream& out) const override {
+ out << "global_id (" << old_max_id << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonHealth.h b/src/messages/MMonHealth.h
new file mode 100644
index 000000000..9f5d4084c
--- /dev/null
+++ b/src/messages/MMonHealth.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) 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 final : public MMonQuorumService {
+public:
+ static constexpr int HEAD_VERSION = 1;
+
+ int service_type = 0;
+ int service_op = 0;
+
+ // service specific data
+ DataStats data_stats;
+
+ MMonHealth() : MMonQuorumService{MSG_MON_HEALTH, HEAD_VERSION} { }
+
+private:
+ ~MMonHealth() final { }
+
+public:
+ std::string_view get_type_name() const override { return "mon_health"; }
+ void print(std::ostream &o) const override {
+ o << "mon_health("
+ << " e " << get_epoch()
+ << " r " << get_round()
+ << " )";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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 000000000..9dd726fd4
--- /dev/null
+++ b/src/messages/MMonHealthChecks.h
@@ -0,0 +1,51 @@
+// -*- 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 final : public PaxosServiceMessage {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ health_check_map_t health_checks;
+
+ MMonHealthChecks()
+ : PaxosServiceMessage{MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION} {
+ }
+ MMonHealthChecks(health_check_map_t& m)
+ : PaxosServiceMessage{MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION},
+ health_checks(m)
+ {}
+
+private:
+ ~MMonHealthChecks() final { }
+
+public:
+ std::string_view get_type_name() const override { return "mon_health_checks"; }
+ void print(std::ostream &o) const override {
+ o << "mon_health_checks(" << health_checks.checks.size() << " checks)";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonJoin.h b/src/messages/MMonJoin.h
new file mode 100644
index 000000000..cf662f514
--- /dev/null
+++ b/src/messages/MMonJoin.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_MMONJOIN_H
+#define CEPH_MMONJOIN_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MMonJoin final : public PaxosServiceMessage {
+public:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 2;
+
+ uuid_d fsid;
+ std::string name;
+ entity_addrvec_t addrs;
+ /* The location members are for stretch mode. crush_loc is the location
+ * (generally just a "datacenter=<foo>" statement) of the monitor. The
+ * force_loc is whether the mon cluster should replace a previously-known
+ * location. Generally the monitor will force an update if it's given a
+ * location from the CLI on boot-up, and then never force again (so that it
+ * can be moved/updated via the ceph tool from elsewhere). */
+ map<string,string> crush_loc;
+ bool force_loc{false};
+
+ MMonJoin() : PaxosServiceMessage{MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION} {}
+ MMonJoin(uuid_d &f, std::string n, const entity_addrvec_t& av)
+ : PaxosServiceMessage{MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), name(n), addrs(av)
+ { }
+ MMonJoin(uuid_d &f, std::string n, const entity_addrvec_t& av, const map<string,string>& cloc, bool force)
+ : PaxosServiceMessage{MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), name(n), addrs(av), crush_loc(cloc), force_loc(force)
+ { }
+
+private:
+ ~MMonJoin() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_join"; }
+ void print(std::ostream& o) const override {
+ o << "mon_join(" << name << " " << addrs << " " << crush_loc << ")";
+ }
+
+ 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);
+ encode(crush_loc, payload);
+ encode(force_loc, payload);
+ } else {
+ header.version = 1;
+ header.compat_version = 1;
+ encode(addrs.legacy_addr(), payload, features);
+ }
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ if (header.version >= 3) {
+ decode(crush_loc, p);
+ decode(force_loc, p);
+ }
+ }
+ }
+};
+
+#endif
diff --git a/src/messages/MMonMap.h b/src/messages/MMonMap.h
new file mode 100644
index 000000000..e72c115f6
--- /dev/null
+++ b/src/messages/MMonMap.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_MMONMAP_H
+#define CEPH_MMONMAP_H
+
+#include "include/encoding.h"
+#include "include/ceph_features.h"
+#include "msg/Message.h"
+#include "msg/MessageRef.h"
+#include "mon/MonMap.h"
+
+class MMonMap final : public Message {
+public:
+ ceph::buffer::list monmapbl;
+
+ MMonMap() : Message{CEPH_MSG_MON_MAP} { }
+ explicit MMonMap(ceph::buffer::list &bl) : Message{CEPH_MSG_MON_MAP} {
+ monmapbl = std::move(bl);
+ }
+private:
+ ~MMonMap() final {}
+
+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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(monmapbl, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonMgrReport.h b/src/messages/MMonMgrReport.h
new file mode 100644
index 000000000..f5a68c7d3
--- /dev/null
+++ b/src/messages/MMonMgrReport.h
@@ -0,0 +1,94 @@
+// -*- 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 final : public PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ // PGMapDigest is in data payload
+ health_check_map_t health_checks;
+ ceph::buffer::list service_map_bl; // encoded ServiceMap
+ std::map<std::string,ProgressEvent> progress_events;
+ uint64_t gid = 0;
+
+ MMonMgrReport()
+ : PaxosServiceMessage{MSG_MON_MGR_REPORT, 0, HEAD_VERSION, COMPAT_VERSION}
+ {}
+private:
+ ~MMonMgrReport() final {}
+
+public:
+ std::string_view get_type_name() const override { return "monmgrreport"; }
+
+ void print(std::ostream& out) const override {
+ out << get_type_name() << "(gid " << gid
+ << ", " << 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);
+ encode(gid, 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);
+ ceph::buffer::list bl;
+ encode(digest, bl, features);
+ set_data(bl);
+ }
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(health_checks, p);
+ decode(service_map_bl, p);
+ if (header.version >= 2) {
+ decode(progress_events, p);
+ }
+ if (header.version >= 3) {
+ decode(gid, p);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonPaxos.h b/src/messages/MMonPaxos.h
new file mode 100644
index 000000000..e1aabc64c
--- /dev/null
+++ b/src/messages/MMonPaxos.h
@@ -0,0 +1,135 @@
+// -*- 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 final : public Message {
+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;
+ ceph::buffer::list latest_value;
+
+ std::map<version_t,ceph::buffer::list> values;
+
+ ceph::buffer::list feature_map;
+
+ MMonPaxos() : Message{MSG_MON_PAXOS, HEAD_VERSION, COMPAT_VERSION} { }
+ MMonPaxos(epoch_t e, int o, utime_t now) :
+ Message{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "paxos"; }
+
+ void print(std::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 {
+ using ceph::decode;
+ 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);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonPing.h b/src/messages/MMonPing.h
new file mode 100644
index 000000000..682094958
--- /dev/null
+++ b/src/messages/MMonPing.h
@@ -0,0 +1,109 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/**
+ * This is used to send pings between monitors 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_MMONPING_H
+#define CEPH_MMONPING_H
+
+#include "common/Clock.h"
+
+#include "msg/Message.h"
+#include "mon/ConnectionTracker.h"
+
+class MMonPing final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ public:
+ enum {
+ PING = 1,
+ PING_REPLY = 2,
+ };
+ const char *get_op_name(int op) const {
+ switch (op) {
+ case PING: return "ping";
+ case PING_REPLY: return "ping_reply";
+ default: return "???";
+ }
+ }
+
+ __u8 op = 0;
+ utime_t stamp;
+ bufferlist tracker_bl;
+ uint32_t min_message_size = 0;
+
+ MMonPing(__u8 o, utime_t s, const bufferlist& tbl,
+ uint32_t min_message)
+ : Message{MSG_MON_PING, HEAD_VERSION, COMPAT_VERSION},
+ op(o), stamp(s), tracker_bl(tbl), min_message_size(min_message)
+ {}
+ MMonPing(__u8 o, utime_t s, const bufferlist& tbl)
+ : Message{MSG_MON_PING, HEAD_VERSION, COMPAT_VERSION},
+ op(o), stamp(s), tracker_bl(tbl) {}
+ MMonPing()
+ : Message{MSG_MON_PING, HEAD_VERSION, COMPAT_VERSION}
+ {}
+private:
+ ~MMonPing() final {}
+
+public:
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ decode(op, p);
+ decode(stamp, p);
+ decode(tracker_bl, p);
+
+ int payload_mid_length = p.get_off();
+ uint32_t size;
+ decode(size, p);
+ p += size;
+ min_message_size = size + payload_mid_length;
+ }
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(op, payload);
+ encode(stamp, payload);
+ encode(tracker_bl, 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 "mon_ping"; }
+ void print(ostream& out) const override {
+ out << "mon_ping(" << get_op_name(op)
+ << " stamp " << stamp
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonProbe.h b/src/messages/MMonProbe.h
new file mode 100644
index 000000000..ae5fc3028
--- /dev/null
+++ b/src/messages/MMonProbe.h
@@ -0,0 +1,153 @@
+// -*- 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 "common/ceph_releases.h"
+#include "msg/Message.h"
+#include "mon/MonMap.h"
+
+class MMonProbe final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 8;
+ 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;
+ std::string name;
+ std::set<int32_t> quorum;
+ int leader = -1;
+ ceph::buffer::list monmap_bl;
+ version_t paxos_first_version = 0;
+ version_t paxos_last_version = 0;
+ bool has_ever_joined = 0;
+ uint64_t required_features = 0;
+ ceph_release_t mon_release{ceph_release_t::unknown};
+
+ MMonProbe()
+ : Message{MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION} {}
+ MMonProbe(const uuid_d& f, int o, const std::string& n, bool hej, ceph_release_t mr)
+ : Message{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_probe"; }
+ void print(std::ostream& out) const override {
+ out << "mon_probe(" << get_opname(op) << " " << fsid << " name " << name;
+ if (quorum.size())
+ out << " quorum " << quorum;
+ out << " leader " << leader;
+ 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 != ceph_release_t::unknown)
+ out << " mon_release " << 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);
+ encode(leader, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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 = ceph_release_t::unknown;
+ if (header.version >= 8) {
+ decode(leader, p);
+ } else if (quorum.size()) {
+ leader = *quorum.begin();
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonQuorumService.h b/src/messages/MMonQuorumService.h
new file mode 100644
index 000000000..23de9af51
--- /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 Message {
+public:
+ epoch_t epoch = 0;
+ version_t round = 0;
+
+protected:
+ MMonQuorumService(int type, int head)
+ : Message{type, head, 1}
+ {}
+ ~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(ceph::buffer::list::const_iterator &p) {
+ using ceph::decode;
+ 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 000000000..b3b99b43f
--- /dev/null
+++ b/src/messages/MMonScrub.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) 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 Message {
+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;
+ std::pair<std::string,std::string> key;
+
+ MMonScrub()
+ : Message{MSG_MON_SCRUB, HEAD_VERSION, COMPAT_VERSION},
+ num_keys(-1)
+ { }
+
+ MMonScrub(op_type_t op, version_t v, int32_t num_keys)
+ : Message{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(std::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 {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif /* CEPH_MMONSCRUB_H */
diff --git a/src/messages/MMonSubscribe.h b/src/messages/MMonSubscribe.h
new file mode 100644
index 000000000..55220b0ce
--- /dev/null
+++ b/src/messages/MMonSubscribe.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_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 final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+ std::string hostname;
+ std::map<std::string, ceph_mon_subscribe_item> what;
+
+ MMonSubscribe() : Message{CEPH_MSG_MON_SUBSCRIBE, HEAD_VERSION, COMPAT_VERSION} { }
+private:
+ ~MMonSubscribe() final {}
+
+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(std::ostream& o) const override {
+ o << "mon_subscribe(" << what << ")";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ if (header.version < 2) {
+ std::map<std::string, ceph_mon_subscribe_item_old> oldwhat;
+ decode(oldwhat, p);
+ what.clear();
+ for (auto 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;
+ std::map<std::string, ceph_mon_subscribe_item_old> oldwhat;
+ for (auto 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonSubscribeAck.h b/src/messages/MMonSubscribeAck.h
new file mode 100644
index 000000000..2f6e2eddb
--- /dev/null
+++ b/src/messages/MMonSubscribeAck.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_MMONSUBSCRIBEACK_H
+#define CEPH_MMONSUBSCRIBEACK_H
+
+#include "msg/Message.h"
+
+class MMonSubscribeAck final : public Message {
+public:
+ __u32 interval;
+ uuid_d fsid;
+
+ MMonSubscribeAck() : Message{CEPH_MSG_MON_SUBSCRIBE_ACK},
+ interval(0) {
+ }
+ MMonSubscribeAck(uuid_d& f, int i) : Message{CEPH_MSG_MON_SUBSCRIBE_ACK},
+ interval(i), fsid(f) { }
+private:
+ ~MMonSubscribeAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "mon_subscribe_ack"; }
+ void print(std::ostream& o) const override {
+ o << "mon_subscribe_ack(" << interval << "s)";
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MMonSync.h b/src/messages/MMonSync.h
new file mode 100644
index 000000000..a9e6184be
--- /dev/null
+++ b/src/messages/MMonSync.h
@@ -0,0 +1,116 @@
+// -*- 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 Message {
+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;
+ std::pair<std::string,std::string> last_key;
+ ceph::buffer::list chunk_bl;
+ entity_inst_t reply_to;
+
+ MMonSync()
+ : Message{MSG_MON_SYNC, HEAD_VERSION, COMPAT_VERSION}
+ { }
+
+ MMonSync(uint32_t op, uint64_t c = 0)
+ : Message{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(std::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 {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif /* CEPH_MMONSYNC_H */
diff --git a/src/messages/MOSDAlive.h b/src/messages/MOSDAlive.h
new file mode 100644
index 000000000..f43e9e266
--- /dev/null
+++ b/src/messages/MOSDAlive.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_MOSDALIVE_H
+#define CEPH_MOSDALIVE_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDAlive final : public PaxosServiceMessage {
+public:
+ epoch_t want = 0;
+
+ MOSDAlive(epoch_t h, epoch_t w) : PaxosServiceMessage{MSG_OSD_ALIVE, h}, want(w) {}
+ MOSDAlive() : MOSDAlive{0, 0} {}
+private:
+ ~MOSDAlive() final {}
+
+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);
+ using ceph::decode;
+ decode(want, p);
+ }
+
+ std::string_view get_type_name() const override { return "osd_alive"; }
+ void print(std::ostream &out) const override {
+ out << "osd_alive(want up_thru " << want << " have " << version << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDBackoff.h b/src/messages/MOSDBackoff.h
new file mode 100644
index 000000000..82218d2fa
--- /dev/null
+++ b/src/messages/MOSDBackoff.h
@@ -0,0 +1,86 @@
+// -*- 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 MOSDFastDispatchOp {
+public:
+ 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()
+ : MOSDFastDispatchOp{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_)
+ : MOSDFastDispatchOp{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 {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "osd_backoff(" << pgid << " " << ceph_osd_backoff_op_name(op)
+ << " id " << id
+ << " [" << begin << "," << end << ")"
+ << " e" << map_epoch << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDBeacon.h b/src/messages/MOSDBeacon.h
new file mode 100644
index 000000000..998d6e638
--- /dev/null
+++ b/src/messages/MOSDBeacon.h
@@ -0,0 +1,64 @@
+// -*- 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 PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+public:
+ std::vector<pg_t> pgs;
+ epoch_t min_last_epoch_clean = 0;
+ utime_t last_purged_snaps_scrub;
+ int osd_beacon_report_interval = 0;
+
+ MOSDBeacon()
+ : PaxosServiceMessage{MSG_OSD_BEACON, 0,
+ HEAD_VERSION, COMPAT_VERSION}
+ {}
+ MOSDBeacon(epoch_t e, epoch_t min_lec, utime_t ls, int interval)
+ : PaxosServiceMessage{MSG_OSD_BEACON, e,
+ HEAD_VERSION, COMPAT_VERSION},
+ min_last_epoch_clean(min_lec),
+ last_purged_snaps_scrub(ls),
+ osd_beacon_report_interval(interval)
+ {}
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ encode(pgs, payload);
+ encode(min_last_epoch_clean, payload);
+ encode(last_purged_snaps_scrub, payload);
+ encode(osd_beacon_report_interval, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ using ceph::decode;
+ paxos_decode(p);
+ decode(pgs, p);
+ decode(min_last_epoch_clean, p);
+ if (header.version >= 2) {
+ decode(last_purged_snaps_scrub, p);
+ }
+ if (header.version >= 3) {
+ decode(osd_beacon_report_interval, p);
+ } else {
+ osd_beacon_report_interval = 0;
+ }
+ }
+ std::string_view get_type_name() const override { return "osd_beacon"; }
+ void print(std::ostream &out) const {
+ out << get_type_name()
+ << "(pgs " << pgs
+ << " lec " << min_last_epoch_clean
+ << " last_purged_snaps_scrub " << last_purged_snaps_scrub
+ << " osd_beacon_report_interval " << osd_beacon_report_interval
+ << " v" << version << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDBoot.h b/src/messages/MOSDBoot.h
new file mode 100644
index 000000000..d40324f4a
--- /dev/null
+++ b/src/messages/MOSDBoot.h
@@ -0,0 +1,122 @@
+// -*- 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 final : public PaxosServiceMessage {
+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)
+ std::map<std::string,std::string> metadata; ///< misc metadata about this osd
+ uint64_t osd_features;
+
+ MOSDBoot()
+ : PaxosServiceMessage{MSG_OSD_BOOT, 0, HEAD_VERSION, COMPAT_VERSION},
+ boot_epoch(0), osd_features(0)
+ { }
+ MOSDBoot(const 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)
+ : PaxosServiceMessage{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() final { }
+
+public:
+ std::string_view get_type_name() const override { return "osd_boot"; }
+ void print(std::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();
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpRead.h b/src/messages/MOSDECSubOpRead.h
new file mode 100644
index 000000000..254357f13
--- /dev/null
+++ b/src/messages/MOSDECSubOpRead.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) 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 MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{MSG_OSD_EC_READ, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "MOSDECSubOpRead(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpReadReply.h b/src/messages/MOSDECSubOpReadReply.h
new file mode 100644
index 000000000..b71c22db4
--- /dev/null
+++ b/src/messages/MOSDECSubOpReadReply.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) 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 MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{MSG_OSD_EC_READ_REPLY, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "MOSDECSubOpReadReply(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpWrite.h b/src/messages/MOSDECSubOpWrite.h
new file mode 100644
index 000000000..e1e37d096
--- /dev/null
+++ b/src/messages/MOSDECSubOpWrite.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) 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 MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{MSG_OSD_EC_WRITE, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ MOSDECSubOpWrite(ECSubWrite &in_op)
+ : MOSDFastDispatchOp{MSG_OSD_EC_WRITE, HEAD_VERSION, COMPAT_VERSION} {
+ op.claim(in_op);
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::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();
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDECSubOpWriteReply.h b/src/messages/MOSDECSubOpWriteReply.h
new file mode 100644
index 000000000..7a813d283
--- /dev/null
+++ b/src/messages/MOSDECSubOpWriteReply.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) 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 MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{MSG_OSD_EC_WRITE_REPLY, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "MOSDECSubOpWriteReply(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << op;
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDFailure.h b/src/messages/MOSDFailure.h
new file mode 100644
index 000000000..72aa644ed
--- /dev/null
+++ b/src/messages/MOSDFailure.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_MOSDFAILURE_H
+#define CEPH_MOSDFAILURE_H
+
+#include "messages/PaxosServiceMessage.h"
+
+
+class MOSDFailure final : public PaxosServiceMessage {
+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() : PaxosServiceMessage(MSG_OSD_FAILURE, 0, HEAD_VERSION) { }
+ MOSDFailure(const uuid_d &fs, int osd, const entity_addrvec_t& av,
+ int duration, epoch_t e)
+ : PaxosServiceMessage(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)
+ : PaxosServiceMessage(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() final {}
+
+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 {
+ using ceph::decode;
+ 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(std::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 << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDFastDispatchOp.h b/src/messages/MOSDFastDispatchOp.h
new file mode 100644
index 000000000..d1103fb88
--- /dev/null
+++ b/src/messages/MOSDFastDispatchOp.h
@@ -0,0 +1,22 @@
+// -*- 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 Message {
+public:
+ MOSDFastDispatchOp(int t, int version, int compat_version)
+ : Message{t, version, compat_version}
+ {}
+ 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 000000000..2d9ccc0e0
--- /dev/null
+++ b/src/messages/MOSDForceRecovery.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) 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 final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+ uuid_d fsid;
+ std::vector<spg_t> forced_pgs;
+ uint8_t options = 0;
+
+ MOSDForceRecovery() : Message{MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDForceRecovery(const uuid_d& f, char opts) :
+ Message{MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), options(opts) {}
+ MOSDForceRecovery(const uuid_d& f, std::vector<spg_t>& pgs, char opts) :
+ Message{MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), forced_pgs(pgs), options(opts) {}
+private:
+ ~MOSDForceRecovery() final {}
+
+public:
+ std::string_view get_type_name() const { return "force_recovery"; }
+ void print(std::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;
+ std::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() {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ if (header.version == 1) {
+ std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif /* CEPH_MOSDFORCERECOVERY_H_ */
diff --git a/src/messages/MOSDFull.h b/src/messages/MOSDFull.h
new file mode 100644
index 000000000..89f5b8402
--- /dev/null
+++ b/src/messages/MOSDFull.h
@@ -0,0 +1,54 @@
+// -*- 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 final : public PaxosServiceMessage {
+public:
+ epoch_t map_epoch = 0;
+ uint32_t state = 0;
+
+private:
+ ~MOSDFull() final {}
+
+public:
+ MOSDFull(epoch_t e, unsigned s)
+ : PaxosServiceMessage{MSG_OSD_FULL, e}, map_epoch(e), state(s) { }
+ MOSDFull()
+ : PaxosServiceMessage{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() {
+ using ceph::decode;
+ 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(std::ostream &out) const {
+ std::set<std::string> states;
+ OSDMap::calc_state_set(state, states);
+ out << "osd_full(e" << map_epoch << " " << states << " v" << version << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDMap.h b/src/messages/MOSDMap.h
new file mode 100644
index 000000000..4a57011c4
--- /dev/null
+++ b/src/messages/MOSDMap.h
@@ -0,0 +1,166 @@
+// -*- 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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 3;
+
+public:
+ uuid_d fsid;
+ uint64_t encode_features = 0;
+ std::map<epoch_t, ceph::buffer::list> maps;
+ std::map<epoch_t, ceph::buffer::list> incremental_maps;
+ epoch_t oldest_map =0, newest_map = 0;
+
+ epoch_t get_first() const {
+ epoch_t e = 0;
+ auto i = maps.cbegin();
+ if (i != maps.cend()) 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;
+ auto i = maps.crbegin();
+ if (i != maps.crend()) 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() : Message{CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION} { }
+ MOSDMap(const uuid_d &f, const uint64_t features)
+ : Message{CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), encode_features(features),
+ oldest_map(0), newest_map(0) { }
+private:
+ ~MOSDMap() final {}
+public:
+ // marshalling
+ void decode_payload() override {
+ using ceph::decode;
+ 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) {
+ // removed in octopus
+ mempool::osdmap::map<int64_t,snap_interval_set_t> gap_removed_snaps;
+ 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 (auto 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 std::map?
+ OSDMap m;
+ m.decode(inc.fullmap);
+ inc.fullmap.clear();
+ m.encode(inc.fullmap, f | CEPH_FEATURE_RESERVED);
+ }
+ if (inc.crush.length()) {
+ // embedded crush std::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 (auto 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((uint32_t)0, payload);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "osdmap"; }
+ void print(std::ostream& out) const override {
+ out << "osd_map(" << get_first() << ".." << get_last();
+ if (oldest_map || newest_map)
+ out << " src has " << oldest_map << ".." << newest_map;
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDMarkMeDead.h b/src/messages/MOSDMarkMeDead.h
new file mode 100644
index 000000000..35f988055
--- /dev/null
+++ b/src/messages/MOSDMarkMeDead.h
@@ -0,0 +1,63 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDMarkMeDead final : public PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ public:
+ uuid_d fsid;
+ int32_t target_osd;
+ epoch_t epoch = 0;
+
+ MOSDMarkMeDead()
+ : PaxosServiceMessage{MSG_OSD_MARK_ME_DEAD, 0,
+ HEAD_VERSION, COMPAT_VERSION} { }
+ MOSDMarkMeDead(const uuid_d &fs, int osd,
+ epoch_t e)
+ : PaxosServiceMessage{MSG_OSD_MARK_ME_DEAD, e,
+ HEAD_VERSION, COMPAT_VERSION},
+ fsid(fs), target_osd(osd),
+ epoch(e) {}
+ private:
+ ~MOSDMarkMeDead() final {}
+
+public:
+ epoch_t get_epoch() const { return epoch; }
+
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(fsid, p);
+ decode(target_osd, p);
+ decode(epoch, p);
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ paxos_encode();
+ header.version = HEAD_VERSION;
+ header.compat_version = COMPAT_VERSION;
+ encode(fsid, payload);
+ encode(target_osd, payload, features);
+ encode(epoch, payload);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDMarkMeDead"; }
+ void print(std::ostream& out) const override {
+ out << "MOSDMarkMeDead("
+ << "osd." << target_osd
+ << ", epoch " << epoch
+ << ", fsid=" << fsid
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDMarkMeDown.h b/src/messages/MOSDMarkMeDown.h
new file mode 100644
index 000000000..44d57395f
--- /dev/null
+++ b/src/messages/MOSDMarkMeDown.h
@@ -0,0 +1,116 @@
+// -*- 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 final : public PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 4;
+ 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
+ bool down_and_dead = false; // mark down and dead
+
+ MOSDMarkMeDown()
+ : PaxosServiceMessage{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)
+ : PaxosServiceMessage{MSG_OSD_MARK_ME_DOWN, e,
+ HEAD_VERSION, COMPAT_VERSION},
+ fsid(fs), target_osd(osd), target_addrs(av),
+ epoch(e), request_ack(request_ack) {}
+ MOSDMarkMeDown(const uuid_d &fs, int osd, const entity_addrvec_t& av,
+ epoch_t e, bool request_ack, bool down_and_dead)
+ : PaxosServiceMessage{MSG_OSD_MARK_ME_DOWN, e,
+ HEAD_VERSION, COMPAT_VERSION},
+ fsid(fs), target_osd(osd), target_addrs(av),
+ epoch(e), request_ack(request_ack), down_and_dead(down_and_dead) {}
+ private:
+ ~MOSDMarkMeDown() final {}
+
+public:
+ epoch_t get_epoch() const { return epoch; }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ if(header.version >= 4)
+ decode(down_and_dead, 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);
+ encode(down_and_dead, payload);
+ }
+
+ std::string_view get_type_name() const override { return "MOSDMarkMeDown"; }
+ void print(std::ostream& out) const override {
+ out << "MOSDMarkMeDown("
+ << "request_ack=" << request_ack
+ << ", down_and_dead=" << down_and_dead
+ << ", osd." << target_osd
+ << ", " << target_addrs
+ << ", fsid=" << fsid
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDOp.h b/src/messages/MOSDOp.h
new file mode 100644
index 000000000..2275c4588
--- /dev/null
+++ b/src/messages/MOSDOp.h
@@ -0,0 +1,608 @@
+// -*- 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 <atomic>
+
+#include "MOSDFastDispatchOp.h"
+#include "include/ceph_features.h"
+#include "common/hobject.h"
+
+/*
+ * OSD op
+ *
+ * oid - object id
+ * op - OSD_OP_DELETE, etc.
+ *
+ */
+
+class MOSDOpReply;
+
+namespace _mosdop {
+template<typename V>
+class MOSDOp final : public MOSDFastDispatchOp {
+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;
+ ceph::buffer::list::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
+ std::atomic<bool> partial_decode_needed;
+ std::atomic<bool> final_decode_needed;
+ //
+public:
+ V ops;
+private:
+ snapid_t snap_seq;
+ std::vector<snapid_t> snaps;
+
+ uint64_t features;
+ bool bdata_encode;
+ osd_reqid_t reqid; // reqid explicitly set by sender
+
+public:
+ friend MOSDOpReply;
+
+ ceph_tid_t get_client_tid() { return header.tid; }
+ void set_snapid(const snapid_t& s) {
+ hobj.snap = s;
+ }
+ void set_snaps(const std::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 std::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()
+ : MOSDFastDispatchOp(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)
+ : MOSDFastDispatchOp(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() final {}
+
+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, ceph::buffer::list& bl) {
+ add_simple_op(CEPH_OSD_OP_WRITE, off, len);
+ data = std::move(bl);
+ header.data_off = off;
+ }
+ void writefull(ceph::buffer::list& bl) {
+ add_simple_op(CEPH_OSD_OP_WRITEFULL, 0, bl.length());
+ data = std::move(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 {
+ ceph_le32 client_inc; /* client incarnation */
+ struct ceph_object_layout layout; /* pgid */
+ ceph_le32 osdmap_epoch; /* client's osdmap epoch */
+
+ ceph_le32 flags;
+
+ struct ceph_timespec mtime; /* for mutations only */
+ struct ceph_eversion reassert_version; /* if we are replaying op */
+
+ ceph_le32 object_len; /* length of object name */
+
+ ceph_le64 snapid; /* snapid to read */
+ ceph_le64 snap_seq; /* writer's snap context */
+ ceph_le32 num_snaps;
+
+ ceph_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);
+
+ ceph::encode_nohead(hobj.oid.name, payload);
+ ceph::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 {
+ using ceph::decode;
+ 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;
+ ceph::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);
+
+ ceph::decode_nohead(oid_len, hobj.oid.name, p);
+ ceph::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;
+ ceph::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() {
+ using ceph::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(std::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 << ")";
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+}
+
+using MOSDOp = _mosdop::MOSDOp<std::vector<OSDOp>>;
+
+
+#endif
diff --git a/src/messages/MOSDOpReply.h b/src/messages/MOSDOpReply.h
new file mode 100644
index 000000000..54c5157c2
--- /dev/null
+++ b/src/messages/MOSDOpReply.h
@@ -0,0 +1,353 @@
+// -*- 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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 8;
+ static constexpr int COMPAT_VERSION = 2;
+
+ object_t oid;
+ pg_t pgid;
+ std::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(std::vector<OSDOp>& o) {
+ ceph_assert(ops.size() == o.size());
+ for (unsigned i = 0; i < o.size(); i++) {
+ ops[i].outdata = std::move(o[i].outdata);
+ }
+ }
+ void claim_ops(std::vector<OSDOp>& o) {
+ o.swap(ops);
+ bdata_encode = false;
+ }
+ void set_op_returns(const std::vector<pg_log_op_return_item_t>& op_returns) {
+ if (op_returns.size()) {
+ ceph_assert(ops.empty() || ops.size() == op_returns.size());
+ ops.resize(op_returns.size());
+ for (unsigned i = 0; i < op_returns.size(); ++i) {
+ ops[i].rval = op_returns[i].rval;
+ ops[i].outdata = op_returns[i].bl;
+ }
+ }
+ }
+
+ /**
+ * 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()
+ : Message{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)
+ : Message{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;
+
+ for (unsigned i = 0; i < ops.size(); i++) {
+ // zero out input data
+ ops[i].indata.clear();
+ if (ignore_out_data) {
+ // original request didn't set the RETURNVEC flag
+ ops[i].outdata.clear();
+ }
+ }
+ }
+private:
+ ~MOSDOpReply() final {}
+
+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);
+ }
+ ceph::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);
+ }
+ ceph::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(std::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 << ")";
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+
+#endif
diff --git a/src/messages/MOSDPGBackfill.h b/src/messages/MOSDPGBackfill.h
new file mode 100644
index 000000000..eccb4e696
--- /dev/null
+++ b/src/messages/MOSDPGBackfill.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_MOSDPGBACKFILL_H
+#define CEPH_MOSDPGBACKFILL_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGBackfill final : public MOSDFastDispatchOp {
+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 {
+ using ceph::decode;
+ 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()
+ : MOSDFastDispatchOp{MSG_OSD_PG_BACKFILL, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDPGBackfill(__u32 o, epoch_t e, epoch_t qe, spg_t p)
+ : MOSDFastDispatchOp{MSG_OSD_PG_BACKFILL, HEAD_VERSION, COMPAT_VERSION},
+ op(o),
+ map_epoch(e), query_epoch(e),
+ pgid(p) {}
+private:
+ ~MOSDPGBackfill() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_backfill"; }
+ void print(std::ostream& out) const override {
+ out << "pg_backfill(" << get_op_name(op)
+ << " " << pgid
+ << " e " << map_epoch << "/" << query_epoch
+ << " lb " << last_backfill
+ << ")";
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGBackfillRemove.h b/src/messages/MOSDPGBackfillRemove.h
new file mode 100644
index 000000000..6029024ee
--- /dev/null
+++ b/src/messages/MOSDPGBackfillRemove.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) 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 final : public MOSDFastDispatchOp {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ spg_t pgid; ///< target spg_t
+ epoch_t map_epoch = 0;
+ std::list<std::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()
+ : MOSDFastDispatchOp{MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION,
+ COMPAT_VERSION}
+ {}
+
+ MOSDPGBackfillRemove(spg_t pgid, epoch_t map_epoch)
+ : MOSDFastDispatchOp{MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION,
+ COMPAT_VERSION},
+ pgid(pgid),
+ map_epoch(map_epoch) {}
+
+private:
+ ~MOSDPGBackfillRemove() final {}
+
+public:
+ std::string_view get_type_name() const override { return "backfill_remove"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(ls, p);
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGCreate.h b/src/messages/MOSDPGCreate.h
new file mode 100644
index 000000000..405135ed8
--- /dev/null
+++ b/src/messages/MOSDPGCreate.h
@@ -0,0 +1,73 @@
+// -*- 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 final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+
+ version_t epoch = 0;
+ std::map<pg_t,pg_create_t> mkpg;
+ std::map<pg_t,utime_t> ctimes;
+
+ MOSDPGCreate()
+ : MOSDPGCreate{0}
+ {}
+ MOSDPGCreate(epoch_t e)
+ : Message{MSG_OSD_PG_CREATE, HEAD_VERSION, COMPAT_VERSION},
+ epoch(e)
+ {}
+private:
+ ~MOSDPGCreate() final {}
+
+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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(mkpg, p);
+ decode(ctimes, p);
+ }
+ void print(std::ostream& out) const override {
+ out << "osd_pg_create(e" << epoch;
+ for (auto i = mkpg.begin(); i != mkpg.end(); ++i) {
+ out << " " << i->first << ":" << i->second.created;
+ }
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGCreate2.h b/src/messages/MOSDPGCreate2.h
new file mode 100644
index 000000000..d05387c7b
--- /dev/null
+++ b/src/messages/MOSDPGCreate2.h
@@ -0,0 +1,56 @@
+// -*- 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 final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ epoch_t epoch = 0;
+ std::map<spg_t,std::pair<epoch_t,utime_t>> pgs;
+ std::map<spg_t,std::pair<pg_history_t,PastIntervals>> pg_extra;
+
+ MOSDPGCreate2()
+ : Message{MSG_OSD_PG_CREATE2, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDPGCreate2(epoch_t e)
+ : Message{MSG_OSD_PG_CREATE2, HEAD_VERSION, COMPAT_VERSION},
+ epoch(e) { }
+private:
+ ~MOSDPGCreate2() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "pg_create2";
+ }
+ void print(std::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);
+ encode(pg_extra, payload);
+ }
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ using ceph::decode;
+ decode(epoch, p);
+ decode(pgs, p);
+ if (header.version >= 2) {
+ decode(pg_extra, p);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGCreated.h b/src/messages/MOSDPGCreated.h
new file mode 100644
index 000000000..9be8e2ddc
--- /dev/null
+++ b/src/messages/MOSDPGCreated.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 "osd/osd_types.h"
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDPGCreated : public PaxosServiceMessage {
+public:
+ pg_t pgid;
+ MOSDPGCreated()
+ : PaxosServiceMessage{MSG_OSD_PG_CREATED, 0}
+ {}
+ MOSDPGCreated(pg_t pgid)
+ : PaxosServiceMessage{MSG_OSD_PG_CREATED, 0},
+ pgid(pgid)
+ {}
+ std::string_view get_type_name() const override { return "pg_created"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(pgid, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGInfo.h b/src/messages/MOSDPGInfo.h
new file mode 100644
index 000000000..b742cd014
--- /dev/null
+++ b/src/messages/MOSDPGInfo.h
@@ -0,0 +1,104 @@
+// -*- 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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 6;
+ static constexpr int COMPAT_VERSION = 5;
+
+ epoch_t epoch = 0;
+
+public:
+ using pg_list_t = std::vector<pg_notify_t>;
+ pg_list_t pg_list;
+
+ epoch_t get_epoch() const { return epoch; }
+
+ MOSDPGInfo()
+ : MOSDPGInfo{0, {}}
+ {}
+ MOSDPGInfo(epoch_t mv)
+ : MOSDPGInfo(mv, {})
+ {}
+ MOSDPGInfo(epoch_t mv, pg_list_t&& l)
+ : Message{MSG_OSD_PG_INFO, HEAD_VERSION, COMPAT_VERSION},
+ epoch{mv},
+ pg_list{std::move(l)}
+ {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+private:
+ ~MOSDPGInfo() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_info"; }
+ void print(std::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;
+ }
+ out << " epoch " << epoch
+ << ")";
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ header.version = HEAD_VERSION;
+ encode(epoch, payload);
+ if (!HAVE_FEATURE(features, SERVER_OCTOPUS)) {
+ // pretend to be vector<pair<pg_notify_t,PastIntervals>>
+ header.version = 5;
+ encode((uint32_t)pg_list.size(), payload);
+ for (auto& i : pg_list) {
+ encode(i, payload); // this embeds a dup (ignored) PastIntervals
+ encode(i.past_intervals, payload);
+ }
+ return;
+ }
+ encode(pg_list, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ if (header.version == 5) {
+ // decode legacy vector<pair<pg_notify_t,PastIntervals>>
+ uint32_t num;
+ decode(num, p);
+ pg_list.resize(num);
+ for (unsigned i = 0; i < num; ++i) {
+ decode(pg_list[i], p);
+ decode(pg_list[i].past_intervals, p);
+ }
+ return;
+ }
+ decode(pg_list, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGInfo2.h b/src/messages/MOSDPGInfo2.h
new file mode 100644
index 000000000..8e7f4bc58
--- /dev/null
+++ b/src/messages/MOSDPGInfo2.h
@@ -0,0 +1,98 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "messages/MOSDPeeringOp.h"
+#include "osd/PGPeeringEvent.h"
+
+class MOSDPGInfo2 final : public MOSDPeeringOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t spgid;
+ epoch_t epoch_sent;
+ epoch_t min_epoch;
+ pg_info_t info;
+ std::optional<pg_lease_t> lease;
+ std::optional<pg_lease_ack_t> lease_ack;
+
+ spg_t get_spg() const override {
+ return spgid;
+ }
+ epoch_t get_map_epoch() const override {
+ return epoch_sent;
+ }
+ epoch_t get_min_epoch() const override {
+ return min_epoch;
+ }
+
+ PGPeeringEvent *get_event() override {
+ return new PGPeeringEvent(
+ epoch_sent,
+ min_epoch,
+ MInfoRec(
+ pg_shard_t(get_source().num(), info.pgid.shard),
+ info,
+ epoch_sent,
+ lease,
+ lease_ack));
+ }
+
+ MOSDPGInfo2() : MOSDPeeringOp{MSG_OSD_PG_INFO2,
+ HEAD_VERSION, COMPAT_VERSION} {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGInfo2(
+ spg_t s,
+ pg_info_t q,
+ epoch_t sent,
+ epoch_t min,
+ std::optional<pg_lease_t> l,
+ std::optional<pg_lease_ack_t> la)
+ : MOSDPeeringOp{MSG_OSD_PG_INFO2, HEAD_VERSION, COMPAT_VERSION},
+ spgid(s),
+ epoch_sent(sent),
+ min_epoch(min),
+ info(q),
+ lease(l),
+ lease_ack(la) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+
+private:
+ ~MOSDPGInfo2() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "pg_info2";
+ }
+ void inner_print(std::ostream& out) const override {
+ out << spgid << " " << info;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(spgid, payload);
+ encode(epoch_sent, payload);
+ encode(min_epoch, payload);
+ encode(info, payload);
+ encode(lease, payload);
+ encode(lease_ack, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(spgid, p);
+ decode(epoch_sent, p);
+ decode(min_epoch, p);
+ decode(info, p);
+ decode(lease, p);
+ decode(lease_ack, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGLease.h b/src/messages/MOSDPGLease.h
new file mode 100644
index 000000000..20b197e1d
--- /dev/null
+++ b/src/messages/MOSDPGLease.h
@@ -0,0 +1,68 @@
+// -*- 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"
+
+class MOSDPGLease final : public MOSDPeeringOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ epoch_t epoch = 0;
+ spg_t spgid;
+ pg_lease_t lease;
+
+public:
+ spg_t get_spg() const {
+ return spgid;
+ }
+ 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,
+ MLease(epoch, get_source().num(), lease));
+ }
+
+ MOSDPGLease() : MOSDPeeringOp{MSG_OSD_PG_LEASE,
+ HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDPGLease(version_t mv, spg_t p, pg_lease_t lease) :
+ MOSDPeeringOp{MSG_OSD_PG_LEASE,
+ HEAD_VERSION, COMPAT_VERSION},
+ epoch(mv),
+ spgid(p),
+ lease(lease) { }
+private:
+ ~MOSDPGLease() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_lease"; }
+ void inner_print(std::ostream& out) const override {
+ out << lease;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(spgid, payload);
+ encode(lease, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(spgid, p);
+ decode(lease, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGLeaseAck.h b/src/messages/MOSDPGLeaseAck.h
new file mode 100644
index 000000000..5c6c1188a
--- /dev/null
+++ b/src/messages/MOSDPGLeaseAck.h
@@ -0,0 +1,68 @@
+// -*- 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"
+
+class MOSDPGLeaseAck final : public MOSDPeeringOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ epoch_t epoch = 0;
+ spg_t spgid;
+ pg_lease_ack_t lease_ack;
+
+public:
+ spg_t get_spg() const {
+ return spgid;
+ }
+ 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,
+ MLeaseAck(epoch, get_source().num(), lease_ack));
+ }
+
+ MOSDPGLeaseAck() : MOSDPeeringOp{MSG_OSD_PG_LEASE_ACK,
+ HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDPGLeaseAck(version_t mv, spg_t p, pg_lease_ack_t lease_ack) :
+ MOSDPeeringOp{MSG_OSD_PG_LEASE_ACK,
+ HEAD_VERSION, COMPAT_VERSION},
+ epoch(mv),
+ spgid(p),
+ lease_ack(lease_ack) { }
+private:
+ ~MOSDPGLeaseAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_lease_ack"; }
+ void inner_print(std::ostream& out) const override {
+ out << lease_ack;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(spgid, payload);
+ encode(lease_ack, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(spgid, p);
+ decode(lease_ack, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGLog.h b/src/messages/MOSDPGLog.h
new file mode 100644
index 000000000..fc3b9174d
--- /dev/null
+++ b/src/messages/MOSDPGLog.h
@@ -0,0 +1,135 @@
+// -*- 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"
+#include "osd/PGPeeringEvent.h"
+
+class MOSDPGLog final : public MOSDPeeringOp {
+private:
+ static constexpr int HEAD_VERSION = 6;
+ 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;
+ std::optional<pg_lease_t> lease;
+
+ 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() : MOSDPeeringOp{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, const pg_info_t& i, epoch_t query_epoch)
+ : MOSDPeeringOp{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "PGlog"; }
+ void inner_print(std::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;
+ if (lease) {
+ out << " " << *lease;
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(epoch, payload);
+ encode(info, payload);
+ encode(log, payload);
+ encode(missing, payload, features);
+ 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);
+ encode(lease, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ if (header.version >= 6) {
+ decode(lease, p);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGNotify.h b/src/messages/MOSDPGNotify.h
new file mode 100644
index 000000000..a3b237c1a
--- /dev/null
+++ b/src/messages/MOSDPGNotify.h
@@ -0,0 +1,111 @@
+// -*- 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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 7;
+ 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.
+ using pg_list_t = std::vector<pg_notify_t>;
+ pg_list_t pg_list;
+
+ public:
+ version_t get_epoch() const { return epoch; }
+ const pg_list_t& get_pg_list() const {
+ return pg_list;
+ }
+
+ MOSDPGNotify()
+ : MOSDPGNotify(0, {})
+ {}
+ MOSDPGNotify(epoch_t e, pg_list_t&& l)
+ : Message{MSG_OSD_PG_NOTIFY, HEAD_VERSION, COMPAT_VERSION},
+ epoch(e),
+ pg_list(std::move(l)) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+private:
+ ~MOSDPGNotify() final {}
+
+public:
+ std::string_view get_type_name() const override { return "PGnot"; }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ header.version = HEAD_VERSION;
+ encode(epoch, payload);
+ if (!HAVE_FEATURE(features, SERVER_OCTOPUS)) {
+ // pretend to be vector<pair<pg_notify_t,PastIntervals>>
+ header.version = 6;
+ encode((uint32_t)pg_list.size(), payload);
+ for (auto& i : pg_list) {
+ encode(i, payload); // this embeds a dup (ignored) PastIntervals
+ encode(i.past_intervals, payload);
+ }
+ return;
+ }
+ encode(pg_list, payload);
+ }
+
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ using ceph::decode;
+ decode(epoch, p);
+ if (header.version == 6) {
+ // decode legacy vector<pair<pg_notify_t,PastIntervals>>
+ uint32_t num;
+ decode(num, p);
+ pg_list.resize(num);
+ for (unsigned i = 0; i < num; ++i) {
+ decode(pg_list[i], p);
+ decode(pg_list[i].past_intervals, p);
+ }
+ return;
+ }
+ decode(pg_list, p);
+ }
+ void print(std::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;
+ }
+ out << " epoch " << epoch
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGNotify2.h b/src/messages/MOSDPGNotify2.h
new file mode 100644
index 000000000..127037398
--- /dev/null
+++ b/src/messages/MOSDPGNotify2.h
@@ -0,0 +1,84 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "messages/MOSDPeeringOp.h"
+#include "osd/PGPeeringEvent.h"
+
+class MOSDPGNotify2 final : public MOSDPeeringOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t spgid;
+ pg_notify_t notify;
+
+ spg_t get_spg() const override {
+ return spgid;
+ }
+ epoch_t get_map_epoch() const override {
+ return notify.epoch_sent;
+ }
+ epoch_t get_min_epoch() const override {
+ return notify.query_epoch;
+ }
+
+ PGPeeringEvent *get_event() override {
+ return new PGPeeringEvent(
+ notify.epoch_sent,
+ notify.query_epoch,
+ MNotifyRec(
+ spgid,
+ pg_shard_t(get_source().num(), notify.from),
+ notify,
+ get_connection()->get_features()),
+ true,
+ new PGCreateInfo(
+ spgid,
+ notify.epoch_sent,
+ notify.info.history,
+ notify.past_intervals,
+ false));
+ }
+
+ MOSDPGNotify2() : MOSDPeeringOp{MSG_OSD_PG_NOTIFY2,
+ HEAD_VERSION, COMPAT_VERSION} {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGNotify2(
+ spg_t s,
+ pg_notify_t n)
+ : MOSDPeeringOp{MSG_OSD_PG_NOTIFY2, HEAD_VERSION, COMPAT_VERSION},
+ spgid(s),
+ notify(n) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+
+private:
+ ~MOSDPGNotify2() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "pg_notify2";
+ }
+ void inner_print(std::ostream& out) const override {
+ out << spgid << " " << notify;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(spgid, payload);
+ encode(notify, payload);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(spgid, p);
+ decode(notify, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGPull.h b/src/messages/MOSDPGPull.h
new file mode 100644
index 000000000..eb5c94516
--- /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 MOSDFastDispatchOp {
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 2;
+
+ std::vector<PullOp> pulls;
+
+public:
+ pg_shard_t from;
+ spg_t pgid;
+ epoch_t map_epoch = 0, min_epoch = 0;
+ uint64_t cost = 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;
+ }
+
+ std::vector<PullOp> take_pulls() {
+ return std::move(pulls);
+ }
+ void set_pulls(std::vector<PullOp>&& pull_ops) {
+ pulls = std::move(pull_ops);
+ }
+
+ MOSDPGPull()
+ : MOSDFastDispatchOp{MSG_OSD_PG_PULL, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void compute_cost(CephContext *cct) {
+ cost = 0;
+ for (auto i = pulls.begin(); i != pulls.end(); ++i) {
+ cost += i->cost(cct);
+ }
+ }
+
+ int get_cost() const override {
+ return cost;
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "MOSDPGPull(" << pgid
+ << " e" << map_epoch << "/" << min_epoch
+ << " cost " << cost
+ << ")";
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGPush.h b/src/messages/MOSDPGPush.h
new file mode 100644
index 000000000..df9dbae5b
--- /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 MOSDFastDispatchOp {
+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;
+ std::vector<PushOp> pushes;
+ bool is_repair = false;
+
+private:
+ uint64_t cost = 0;
+
+public:
+ void compute_cost(CephContext *cct) {
+ cost = 0;
+ for (auto 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()
+ : MOSDFastDispatchOp{MSG_OSD_PG_PUSH, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "MOSDPGPush(" << pgid
+ << " " << map_epoch << "/" << min_epoch
+ << " " << pushes;
+ out << ")";
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGPushReply.h b/src/messages/MOSDPGPushReply.h
new file mode 100644
index 000000000..1fdfd9b69
--- /dev/null
+++ b/src/messages/MOSDPGPushReply.h
@@ -0,0 +1,94 @@
+// -*- 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 MOSDFastDispatchOp {
+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;
+ std::vector<PushReplyOp> replies;
+ uint64_t cost = 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;
+ }
+
+ MOSDPGPushReply()
+ : MOSDFastDispatchOp{MSG_OSD_PG_PUSH_REPLY, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void compute_cost(CephContext *cct) {
+ cost = 0;
+ for (auto i = replies.begin(); i != replies.end(); ++i) {
+ cost += i->cost(cct);
+ }
+ }
+
+ int get_cost() const override {
+ return cost;
+ }
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::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 000000000..b9a48b989
--- /dev/null
+++ b/src/messages/MOSDPGQuery.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) 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 final : public Message {
+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; }
+ using pg_list_t = std::map<spg_t, pg_query_t>;
+ pg_list_t pg_list;
+
+ MOSDPGQuery() : Message{MSG_OSD_PG_QUERY,
+ HEAD_VERSION,
+ COMPAT_VERSION} {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGQuery(epoch_t e, pg_list_t&& ls) :
+ Message{MSG_OSD_PG_QUERY,
+ HEAD_VERSION,
+ COMPAT_VERSION},
+ epoch(e),
+ pg_list(std::move(ls)) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+private:
+ ~MOSDPGQuery() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_query"; }
+ void print(std::ostream& out) const override {
+ out << "pg_query(";
+ for (auto 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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pg_list, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGQuery2.h b/src/messages/MOSDPGQuery2.h
new file mode 100644
index 000000000..d2257ee53
--- /dev/null
+++ b/src/messages/MOSDPGQuery2.h
@@ -0,0 +1,78 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "messages/MOSDPeeringOp.h"
+#include "osd/PGPeeringEvent.h"
+
+class MOSDPGQuery2 final : public MOSDPeeringOp {
+private:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ spg_t spgid;
+ pg_query_t query;
+
+ spg_t get_spg() const override {
+ return spgid;
+ }
+ epoch_t get_map_epoch() const override {
+ return query.epoch_sent;
+ }
+ epoch_t get_min_epoch() const override {
+ return query.epoch_sent;
+ }
+
+ PGPeeringEvent *get_event() override {
+ return new PGPeeringEvent(
+ query.epoch_sent,
+ query.epoch_sent,
+ MQuery(
+ spgid,
+ pg_shard_t(get_source().num(), query.from),
+ query,
+ query.epoch_sent),
+ false);
+ }
+
+ MOSDPGQuery2() : MOSDPeeringOp{MSG_OSD_PG_QUERY2,
+ HEAD_VERSION, COMPAT_VERSION} {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+ MOSDPGQuery2(
+ spg_t s,
+ pg_query_t q)
+ : MOSDPeeringOp{MSG_OSD_PG_QUERY2, HEAD_VERSION, COMPAT_VERSION},
+ spgid(s),
+ query(q) {
+ set_priority(CEPH_MSG_PRIO_HIGH);
+ }
+
+private:
+ ~MOSDPGQuery2() final {}
+
+public:
+ std::string_view get_type_name() const override {
+ return "pg_query2";
+ }
+ void inner_print(std::ostream& out) const override {
+ out << spgid << " " << query;
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(spgid, payload);
+ encode(query, payload, features);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(spgid, p);
+ decode(query, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGReadyToMerge.h b/src/messages/MOSDPGReadyToMerge.h
new file mode 100644
index 000000000..e75212638
--- /dev/null
+++ b/src/messages/MOSDPGReadyToMerge.h
@@ -0,0 +1,61 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+class MOSDPGReadyToMerge : public 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()
+ : PaxosServiceMessage{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)
+ : PaxosServiceMessage{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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ 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(std::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 << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDPGRecoveryDelete.h b/src/messages/MOSDPGRecoveryDelete.h
new file mode 100644
index 000000000..555a1c733
--- /dev/null
+++ b/src/messages/MOSDPGRecoveryDelete.h
@@ -0,0 +1,94 @@
+// -*- 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 final : public MOSDFastDispatchOp {
+public:
+ 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;
+ std::list<std::pair<hobject_t, eversion_t>> objects; ///< objects to remove
+
+private:
+ uint64_t cost = 0;
+
+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()
+ : MOSDFastDispatchOp{MSG_OSD_PG_RECOVERY_DELETE, HEAD_VERSION,
+ COMPAT_VERSION}
+ {}
+
+ MOSDPGRecoveryDelete(pg_shard_t from, spg_t pgid, epoch_t map_epoch,
+ epoch_t min_epoch)
+ : MOSDFastDispatchOp{MSG_OSD_PG_RECOVERY_DELETE, HEAD_VERSION,
+ COMPAT_VERSION},
+ from(from),
+ pgid(pgid),
+ map_epoch(map_epoch),
+ min_epoch(min_epoch)
+ {}
+
+private:
+ ~MOSDPGRecoveryDelete() final {}
+
+public:
+ std::string_view get_type_name() const { return "recovery_delete"; }
+ void print(std::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() {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(from, p);
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(min_epoch, p);
+ decode(cost, p);
+ decode(objects, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGRecoveryDeleteReply.h b/src/messages/MOSDPGRecoveryDeleteReply.h
new file mode 100644
index 000000000..60f494b62
--- /dev/null
+++ b/src/messages/MOSDPGRecoveryDeleteReply.h
@@ -0,0 +1,67 @@
+// -*- 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 MOSDFastDispatchOp {
+public:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+ pg_shard_t from;
+ spg_t pgid;
+ epoch_t map_epoch = 0;
+ epoch_t min_epoch = 0;
+ std::list<std::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()
+ : MOSDFastDispatchOp{MSG_OSD_PG_RECOVERY_DELETE_REPLY, HEAD_VERSION, COMPAT_VERSION}
+ {}
+
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::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"; }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGRemove.h b/src/messages/MOSDPGRemove.h
new file mode 100644
index 000000000..3ac651ba7
--- /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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 3;
+
+ epoch_t epoch = 0;
+
+ public:
+ std::vector<spg_t> pg_list;
+
+ epoch_t get_epoch() const { return epoch; }
+
+ MOSDPGRemove() :
+ Message{MSG_OSD_PG_REMOVE, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDPGRemove(epoch_t e, std::vector<spg_t>& l) :
+ Message{MSG_OSD_PG_REMOVE, HEAD_VERSION, COMPAT_VERSION} {
+ this->epoch = e;
+ pg_list.swap(l);
+ }
+private:
+ ~MOSDPGRemove() final {}
+
+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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pg_list, p);
+ }
+ void print(std::ostream& out) const override {
+ out << "osd pg remove(" << "epoch " << epoch << "; ";
+ for (auto i = pg_list.begin(); i != pg_list.end(); ++i) {
+ out << "pg" << *i << "; ";
+ }
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGScan.h b/src/messages/MOSDPGScan.h
new file mode 100644
index 000000000..c80bb6efc
--- /dev/null
+++ b/src/messages/MOSDPGScan.h
@@ -0,0 +1,119 @@
+// -*- 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 final : public MOSDFastDispatchOp {
+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 {
+ using ceph::decode;
+ 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()
+ : MOSDFastDispatchOp{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)
+ : MOSDFastDispatchOp{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_scan"; }
+ void print(std::ostream& out) const override {
+ out << "pg_scan(" << get_op_name(op)
+ << " " << pgid
+ << " " << begin << "-" << end
+ << " e " << map_epoch << "/" << query_epoch
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGTemp.h b/src/messages/MOSDPGTemp.h
new file mode 100644
index 000000000..d73a767b7
--- /dev/null
+++ b/src/messages/MOSDPGTemp.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_MOSDPGTEMP_H
+#define CEPH_MOSDPGTEMP_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MOSDPGTemp final : public PaxosServiceMessage {
+public:
+ epoch_t map_epoch = 0;
+ std::map<pg_t, std::vector<int32_t> > pg_temp;
+ bool forced = false;
+
+ MOSDPGTemp(epoch_t e)
+ : PaxosServiceMessage{MSG_OSD_PGTEMP, e, HEAD_VERSION, COMPAT_VERSION},
+ map_epoch(e)
+ {}
+ MOSDPGTemp()
+ : MOSDPGTemp(0)
+ {}
+private:
+ ~MOSDPGTemp() final {}
+
+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 {
+ using ceph::decode;
+ 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(std::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;
+
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGTrim.h b/src/messages/MOSDPGTrim.h
new file mode 100644
index 000000000..91ba1c786
--- /dev/null
+++ b/src/messages/MOSDPGTrim.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) 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"
+#include "osd/PGPeeringEvent.h"
+
+class MOSDPGTrim final : public MOSDPeeringOp {
+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() : MOSDPeeringOp{MSG_OSD_PG_TRIM, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDPGTrim(version_t mv, spg_t p, eversion_t tt) :
+ MOSDPeeringOp{MSG_OSD_PG_TRIM, HEAD_VERSION, COMPAT_VERSION},
+ epoch(mv), pgid(p), trim_to(tt) { }
+private:
+ ~MOSDPGTrim() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_trim"; }
+ void inner_print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(epoch, p);
+ decode(pgid.pgid, p);
+ decode(trim_to, p);
+ decode(pgid.shard, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGUpdateLogMissing.h b/src/messages/MOSDPGUpdateLogMissing.h
new file mode 100644
index 000000000..2a0011e8f
--- /dev/null
+++ b/src/messages/MOSDPGUpdateLogMissing.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_MOSDPGUPDATELOGMISSING_H
+#define CEPH_MOSDPGUPDATELOGMISSING_H
+
+#include "MOSDFastDispatchOp.h"
+
+class MOSDPGUpdateLogMissing final : public MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{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)
+ : MOSDFastDispatchOp{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "PGUpdateLogMissing"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPGUpdateLogMissingReply.h b/src/messages/MOSDPGUpdateLogMissingReply.h
new file mode 100644
index 000000000..559c14353
--- /dev/null
+++ b/src/messages/MOSDPGUpdateLogMissingReply.h
@@ -0,0 +1,115 @@
+// -*- 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 final : public MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{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)
+ : MOSDFastDispatchOp{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "PGUpdateLogMissingReply"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDPeeringOp.h b/src/messages/MOSDPeeringOp.h
new file mode 100644
index 000000000..56d10cff1
--- /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"
+
+class PGPeeringEvent;
+
+class MOSDPeeringOp : public Message {
+public:
+ MOSDPeeringOp(int t, int version, int compat_version)
+ : Message{t, version, compat_version} {}
+
+ void print(std::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(std::ostream& out) const = 0;
+};
diff --git a/src/messages/MOSDPing.h b/src/messages/MOSDPing.h
new file mode 100644
index 000000000..8f512a7d7
--- /dev/null
+++ b/src/messages/MOSDPing.h
@@ -0,0 +1,168 @@
+// -*- 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 final : public Message {
+private:
+ static constexpr int HEAD_VERSION = 5;
+ 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 ping_stamp; ///< when the PING was sent
+ ceph::signedspan mono_ping_stamp; ///< relative to sender's clock
+ ceph::signedspan mono_send_stamp; ///< replier's send stamp
+ std::optional<ceph::signedspan> delta_ub; ///< ping sender
+ epoch_t up_from = 0;
+
+ uint32_t min_message_size = 0;
+
+ MOSDPing(const uuid_d& f, epoch_t e, __u8 o,
+ utime_t s,
+ ceph::signedspan ms,
+ ceph::signedspan mss,
+ epoch_t upf,
+ uint32_t min_message,
+ std::optional<ceph::signedspan> delta_ub = {})
+ : Message{MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), map_epoch(e), op(o),
+ ping_stamp(s),
+ mono_ping_stamp(ms),
+ mono_send_stamp(mss),
+ delta_ub(delta_ub),
+ up_from(upf),
+ min_message_size(min_message)
+ { }
+ MOSDPing()
+ : Message{MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION}
+ {}
+private:
+ ~MOSDPing() final {}
+
+public:
+ void decode_payload() override {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(map_epoch, p);
+ decode(op, p);
+ decode(ping_stamp, p);
+
+ int payload_mid_length = p.get_off();
+ uint32_t size;
+ decode(size, p);
+
+ if (header.version >= 5) {
+ decode(up_from, p);
+ decode(mono_ping_stamp, p);
+ decode(mono_send_stamp, p);
+ decode(delta_ub, p);
+ }
+
+ p += 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(ping_stamp, payload);
+
+ size_t s = 0;
+ if (min_message_size > payload.length()) {
+ s = min_message_size - payload.length();
+ }
+ encode((uint32_t)s, payload);
+
+ encode(up_from, payload);
+ encode(mono_ping_stamp, payload);
+ encode(mono_send_stamp, payload);
+ encode(delta_ub, 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(ceph::buffer::create_static(sizeof(zeros), zeros));
+ s -= sizeof(zeros);
+ }
+ if (s) {
+ payload.append(ceph::buffer::create_static(s, zeros));
+ }
+ }
+ }
+
+ std::string_view get_type_name() const override { return "osd_ping"; }
+ void print(std::ostream& out) const override {
+ out << "osd_ping(" << get_op_name(op)
+ << " e" << map_epoch
+ << " up_from " << up_from
+ << " ping_stamp " << ping_stamp << "/" << mono_ping_stamp
+ << " send_stamp " << mono_send_stamp;
+ if (delta_ub) {
+ out << " delta_ub " << *delta_ub;
+ }
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDRepOp.h b/src/messages/MOSDRepOp.h
new file mode 100644
index 000000000..5ecec0007
--- /dev/null
+++ b/src/messages/MOSDRepOp.h
@@ -0,0 +1,199 @@
+// -*- 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 final : public MOSDFastDispatchOp {
+private:
+ static constexpr int HEAD_VERSION = 3;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ epoch_t map_epoch, min_epoch;
+
+ // metadata from original request
+ osd_reqid_t reqid;
+
+ spg_t pgid;
+
+ ceph::buffer::list::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
+ ceph::buffer::list 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 min_last_complete_ondisk; // lower bound on committed version
+
+ 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
+ std::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 {
+ using ceph::decode;
+ 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() {
+ using ceph::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);
+
+ if (header.version >= 3) {
+ decode(min_last_complete_ondisk, p);
+ } else {
+ /* This field used to mean pg_roll_foward_to, but ReplicatedBackend
+ * simply assumes that we're rolling foward to version. */
+ eversion_t pg_roll_forward_to;
+ 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(min_last_complete_ondisk, payload);
+ }
+
+ MOSDRepOp()
+ : MOSDFastDispatchOp{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)
+ : MOSDFastDispatchOp{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);
+ }
+
+ void set_rollback_to(const eversion_t &rollback_to) {
+ header.version = 2;
+ min_last_complete_ondisk = rollback_to;
+ }
+private:
+ ~MOSDRepOp() final {}
+
+public:
+ std::string_view get_type_name() const override { return "osd_repop"; }
+ void print(std::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";
+ if (header.version < 3) {
+ out << ", rollback_to(legacy)=" << min_last_complete_ondisk;
+ } else {
+ out << ", mlcod=" << min_last_complete_ondisk;
+ }
+ }
+ out << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDRepOpReply.h b/src/messages/MOSDRepOpReply.h
new file mode 100644
index 000000000..8974b4b0f
--- /dev/null
+++ b/src/messages/MOSDRepOpReply.h
@@ -0,0 +1,164 @@
+// -*- 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"
+#include "MOSDRepOp.h"
+
+/*
+ * OSD Client Subop reply
+ *
+ * oid - object id
+ * op - OSD_OP_DELETE, etc.
+ *
+ */
+
+class MOSDRepOpReply final : public MOSDFastDispatchOp {
+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;
+
+ ceph::buffer::list::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 {
+ using ceph::decode;
+ 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() {
+ using ceph::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) :
+ MOSDFastDispatchOp{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()
+ : MOSDFastDispatchOp{MSG_OSD_REPOPREPLY, HEAD_VERSION, COMPAT_VERSION},
+ map_epoch(0),
+ min_epoch(0),
+ ack_type(0), result(0),
+ final_decode_needed(true) {}
+private:
+ ~MOSDRepOpReply() final {}
+
+public:
+ std::string_view get_type_name() const override { return "osd_repop_reply"; }
+
+ void print(std::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 << ")";
+ }
+
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDRepScrub.h b/src/messages/MOSDRepScrub.h
new file mode 100644
index 000000000..ededcdca8
--- /dev/null
+++ b/src/messages/MOSDRepScrub.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_MOSDREPSCRUB_H
+#define CEPH_MOSDREPSCRUB_H
+
+#include "MOSDFastDispatchOp.h"
+
+/*
+ * instruct an OSD initiate a replica scrub on a specific PG
+ */
+
+class MOSDRepScrub final : public MOSDFastDispatchOp {
+public:
+ 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 (not used)
+ 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()
+ : MOSDFastDispatchOp{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)
+ : MOSDFastDispatchOp{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "replica scrub"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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 000000000..51e8b02ee
--- /dev/null
+++ b/src/messages/MOSDRepScrubMap.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 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 final : public MOSDFastDispatchOp {
+public:
+ 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
+ ceph::buffer::list 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()
+ : MOSDFastDispatchOp{MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION} {}
+
+ MOSDRepScrubMap(spg_t pgid, epoch_t map_epoch, pg_shard_t from)
+ : MOSDFastDispatchOp{MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION},
+ pgid(pgid),
+ map_epoch(map_epoch),
+ from(from) {}
+
+private:
+ ~MOSDRepScrubMap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "rep_scrubmap"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(pgid, p);
+ decode(map_epoch, p);
+ decode(from, p);
+ if (header.version >= 2) {
+ decode(preempted, p);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDScrub.h b/src/messages/MOSDScrub.h
new file mode 100644
index 000000000..4f850fad7
--- /dev/null
+++ b/src/messages/MOSDScrub.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_MOSDSCRUB_H
+#define CEPH_MOSDSCRUB_H
+
+#include "msg/Message.h"
+
+/*
+ * instruct an OSD to scrub some or all pg(s)
+ */
+
+class MOSDScrub final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 2;
+
+ uuid_d fsid;
+ std::vector<pg_t> scrub_pgs;
+ bool repair = false;
+ bool deep = false;
+
+ MOSDScrub() : Message{MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDScrub(const uuid_d& f, bool r, bool d) :
+ Message{MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), repair(r), deep(d) {}
+ MOSDScrub(const uuid_d& f, std::vector<pg_t>& pgs, bool r, bool d) :
+ Message{MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), scrub_pgs(pgs), repair(r), deep(d) {}
+private:
+ ~MOSDScrub() final {}
+
+public:
+ std::string_view get_type_name() const override { return "scrub"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(scrub_pgs, p);
+ decode(repair, p);
+ decode(deep, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MOSDScrub2.h b/src/messages/MOSDScrub2.h
new file mode 100644
index 000000000..61bafba24
--- /dev/null
+++ b/src/messages/MOSDScrub2.h
@@ -0,0 +1,61 @@
+// -*- 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 final : public Message {
+public:
+ static constexpr int HEAD_VERSION = 1;
+ static constexpr int COMPAT_VERSION = 1;
+
+ uuid_d fsid;
+ epoch_t epoch;
+ std::vector<spg_t> scrub_pgs;
+ bool repair = false;
+ bool deep = false;
+
+ MOSDScrub2() : Message{MSG_OSD_SCRUB2, HEAD_VERSION, COMPAT_VERSION} {}
+ MOSDScrub2(const uuid_d& f, epoch_t e, std::vector<spg_t>& pgs, bool r, bool d) :
+ Message{MSG_OSD_SCRUB2, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), epoch(e), scrub_pgs(pgs), repair(r), deep(d) {}
+private:
+ ~MOSDScrub2() final {}
+
+public:
+ std::string_view get_type_name() const override { return "scrub2"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(fsid, p);
+ decode(epoch, p);
+ decode(scrub_pgs, p);
+ decode(repair, p);
+ decode(deep, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MOSDScrubReserve.h b/src/messages/MOSDScrubReserve.h
new file mode 100644
index 000000000..f1f76b3e6
--- /dev/null
+++ b/src/messages/MOSDScrubReserve.h
@@ -0,0 +1,99 @@
+// -*- 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 MOSDFastDispatchOp {
+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()
+ : MOSDFastDispatchOp{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)
+ : MOSDFastDispatchOp{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(std::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() {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MPGStats.h b/src/messages/MPGStats.h
new file mode 100644
index 000000000..65cec5244
--- /dev/null
+++ b/src/messages/MPGStats.h
@@ -0,0 +1,77 @@
+// -*- 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 final : public PaxosServiceMessage {
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ uuid_d fsid;
+ std::map<pg_t, pg_stat_t> pg_stat;
+ osd_stat_t osd_stat;
+ std::map<int64_t, store_statfs_t> pool_stat;
+ epoch_t epoch = 0;
+
+ MPGStats() : PaxosServiceMessage{MSG_PGSTATS, 0, HEAD_VERSION, COMPAT_VERSION} {}
+ MPGStats(const uuid_d& f, epoch_t e)
+ : PaxosServiceMessage{MSG_PGSTATS, 0, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f),
+ epoch(e)
+ {}
+
+private:
+ ~MPGStats() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_stats"; }
+ void print(std::ostream& out) const override {
+ out << "pg_stats(" << pg_stat.size() << " pgs seq " << osd_stat.seq << " 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(utime_t{}, payload);
+ encode(pool_stat, payload, features);
+ }
+ void decode_payload() override {
+ using ceph::decode;
+ 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);
+ utime_t dummy;
+ decode(dummy, 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 000000000..03bade32b
--- /dev/null
+++ b/src/messages/MPGStatsAck.h
@@ -0,0 +1,49 @@
+// -*- 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 final : public Message {
+public:
+ std::map<pg_t,std::pair<version_t,epoch_t> > pg_stat;
+
+ MPGStatsAck() : Message{MSG_PGSTATSACK} {}
+
+private:
+ ~MPGStatsAck() final {}
+
+public:
+ std::string_view get_type_name() const override { return "pg_stats_ack"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(pg_stat, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MPing.h b/src/messages/MPing.h
new file mode 100644
index 000000000..bff4326ee
--- /dev/null
+++ b/src/messages/MPing.h
@@ -0,0 +1,33 @@
+// -*- 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 final : public Message {
+public:
+ MPing() : Message{CEPH_MSG_PING} {}
+private:
+ ~MPing() final {}
+
+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 000000000..0e53c56b9
--- /dev/null
+++ b/src/messages/MPoolOp.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) 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 final : public PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 4;
+ static constexpr int COMPAT_VERSION = 2;
+
+public:
+ uuid_d fsid;
+ __u32 pool = 0;
+ std::string name;
+ __u32 op = 0;
+ snapid_t snapid;
+ __s16 crush_rule = 0;
+
+ MPoolOp()
+ : PaxosServiceMessage{CEPH_MSG_POOLOP, 0, HEAD_VERSION, COMPAT_VERSION} {}
+ MPoolOp(const uuid_d& f, ceph_tid_t t, int p, std::string& n, int o, version_t v)
+ : PaxosServiceMessage{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() final {}
+
+public:
+ std::string_view get_type_name() const override { return "poolop"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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;
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MPoolOpReply.h b/src/messages/MPoolOpReply.h
new file mode 100644
index 000000000..59ec764af
--- /dev/null
+++ b/src/messages/MPoolOpReply.h
@@ -0,0 +1,85 @@
+// -*- 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 PaxosServiceMessage {
+public:
+ uuid_d fsid;
+ __u32 replyCode = 0;
+ epoch_t epoch = 0;
+ ceph::buffer::list response_data;
+
+ MPoolOpReply() : PaxosServiceMessage{CEPH_MSG_POOLOP_REPLY, 0}
+ {}
+ MPoolOpReply( uuid_d& f, ceph_tid_t t, int rc, int e, version_t v) :
+ PaxosServiceMessage{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,
+ ceph::buffer::list *blp) :
+ PaxosServiceMessage{CEPH_MSG_POOLOP_REPLY, v},
+ fsid(f),
+ replyCode(rc),
+ epoch(e) {
+ set_tid(t);
+ if (blp)
+ response_data = std::move(*blp);
+ }
+
+ std::string_view get_type_name() const override { return "poolopreply"; }
+
+ void print(std::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 {
+ using ceph::decode;
+ 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);
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MRecoveryReserve.h b/src/messages/MRecoveryReserve.h
new file mode 100644
index 000000000..55fb2d81b
--- /dev/null
+++ b/src/messages/MRecoveryReserve.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_MRECOVERY_H
+#define CEPH_MRECOVERY_H
+
+#include "msg/Message.h"
+#include "messages/MOSDPeeringOp.h"
+#include "osd/PGPeeringEvent.h"
+
+class MRecoveryReserve : public MOSDPeeringOp {
+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()
+ : MOSDPeeringOp{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)
+ : MOSDPeeringOp{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(std::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();
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MRemoveSnaps.h b/src/messages/MRemoveSnaps.h
new file mode 100644
index 000000000..c0217f832
--- /dev/null
+++ b/src/messages/MRemoveSnaps.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_MREMOVESNAPS_H
+#define CEPH_MREMOVESNAPS_H
+
+#include "messages/PaxosServiceMessage.h"
+
+class MRemoveSnaps final : public PaxosServiceMessage {
+public:
+ std::map<int32_t, std::vector<snapid_t>> snaps;
+
+protected:
+ MRemoveSnaps() :
+ PaxosServiceMessage{MSG_REMOVE_SNAPS, 0} { }
+ MRemoveSnaps(std::map<int, std::vector<snapid_t>>& s) :
+ PaxosServiceMessage{MSG_REMOVE_SNAPS, 0} {
+ snaps.swap(s);
+ }
+ ~MRemoveSnaps() final {}
+
+public:
+ std::string_view get_type_name() const override { return "remove_snaps"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ paxos_decode(p);
+ decode(snaps, p);
+ ceph_assert(p.end());
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MRoute.h b/src/messages/MRoute.h
new file mode 100644
index 000000000..4154434af
--- /dev/null
+++ b/src/messages/MRoute.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_MROUTE_H
+#define CEPH_MROUTE_H
+
+#include "msg/Message.h"
+#include "include/encoding.h"
+
+class MRoute final : public Message {
+public:
+ 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() : Message{MSG_ROUTE, HEAD_VERSION, COMPAT_VERSION},
+ session_mon_tid(0),
+ msg(NULL),
+ send_osdmap_first(0) {}
+ MRoute(uint64_t t, Message *m)
+ : Message{MSG_ROUTE, HEAD_VERSION, COMPAT_VERSION},
+ session_mon_tid(t),
+ msg(m),
+ send_osdmap_first(0) {}
+private:
+ ~MRoute() final {
+ if (msg)
+ msg->put();
+ }
+
+public:
+ void decode_payload() override {
+ auto p = payload.cbegin();
+ using ceph::decode;
+ 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(std::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)";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MServiceMap.h b/src/messages/MServiceMap.h
new file mode 100644
index 000000000..05954354a
--- /dev/null
+++ b/src/messages/MServiceMap.h
@@ -0,0 +1,39 @@
+// -*- 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 final : public Message {
+public:
+ ServiceMap service_map;
+
+ MServiceMap() : Message{MSG_SERVICE_MAP} { }
+ explicit MServiceMap(const ServiceMap& sm)
+ : Message{MSG_SERVICE_MAP},
+ service_map(sm) {
+ }
+private:
+ ~MServiceMap() final {}
+
+public:
+ std::string_view get_type_name() const override { return "service_map"; }
+ void print(std::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 {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(service_map, p);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MStatfs.h b/src/messages/MStatfs.h
new file mode 100644
index 000000000..41b236a9e
--- /dev/null
+++ b/src/messages/MStatfs.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_MSTATFS_H
+#define CEPH_MSTATFS_H
+
+#include <sys/statvfs.h> /* or <sys/statfs.h> */
+#include "messages/PaxosServiceMessage.h"
+
+class MStatfs final : public PaxosServiceMessage {
+private:
+ static constexpr int HEAD_VERSION = 2;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ uuid_d fsid;
+ boost::optional<int64_t> data_pool;
+
+ MStatfs() : PaxosServiceMessage{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)
+ : PaxosServiceMessage{CEPH_MSG_STATFS, v, HEAD_VERSION, COMPAT_VERSION},
+ fsid(f), data_pool(_data_pool) {
+ set_tid(t);
+ }
+
+private:
+ ~MStatfs() final {}
+
+public:
+ std::string_view get_type_name() const override { return "statfs"; }
+ void print(std::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 {
+ using ceph::decode;
+ 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> ();
+ }
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MStatfsReply.h b/src/messages/MStatfsReply.h
new file mode 100644
index 000000000..3bdcfe0a7
--- /dev/null
+++ b/src/messages/MStatfsReply.h
@@ -0,0 +1,49 @@
+// -*- 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 Message {
+public:
+ struct ceph_mon_statfs_reply h{};
+
+ MStatfsReply() : Message{CEPH_MSG_STATFS_REPLY} {}
+ MStatfsReply(uuid_d &f, ceph_tid_t t, epoch_t epoch)
+ : Message{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(std::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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/MTimeCheck.h b/src/messages/MTimeCheck.h
new file mode 100644
index 000000000..03cd157f2
--- /dev/null
+++ b/src/messages/MTimeCheck.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) 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 final : public Message {
+public:
+ 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() : Message{MSG_TIMECHECK, HEAD_VERSION} {}
+ MTimeCheck(int op) :
+ Message{MSG_TIMECHECK, HEAD_VERSION},
+ op(op)
+ {}
+
+private:
+ ~MTimeCheck() final {}
+
+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(std::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 {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif /* CEPH_MTIMECHECK_H */
diff --git a/src/messages/MTimeCheck2.h b/src/messages/MTimeCheck2.h
new file mode 100644
index 000000000..8d9c4215f
--- /dev/null
+++ b/src/messages/MTimeCheck2.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.
+ *
+ */
+
+#pragma once
+
+class MTimeCheck2 final : public Message {
+public:
+ 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;
+ std::map<int, double> skews;
+ std::map<int, double> latencies;
+
+ MTimeCheck2() : Message{MSG_TIMECHECK2, HEAD_VERSION, COMPAT_VERSION} { }
+ MTimeCheck2(int op) :
+ Message{MSG_TIMECHECK2, HEAD_VERSION, COMPAT_VERSION},
+ op(op)
+ { }
+
+private:
+ ~MTimeCheck2() final { }
+
+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(std::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 {
+ using ceph::decode;
+ 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);
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
diff --git a/src/messages/MWatchNotify.h b/src/messages/MWatchNotify.h
new file mode 100644
index 000000000..971c860c7
--- /dev/null
+++ b/src/messages/MWatchNotify.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) 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 final : public Message {
+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_*
+ ceph::buffer::list bl; ///< notify payload (osd->client)
+ errorcode32_t return_code; ///< notify result (osd->client)
+ uint64_t notifier_gid; ///< who sent the notify
+
+ MWatchNotify()
+ : Message{CEPH_MSG_WATCH_NOTIFY, HEAD_VERSION, COMPAT_VERSION} { }
+ MWatchNotify(uint64_t c, uint64_t v, uint64_t i, uint8_t o, ceph::buffer::list b, uint64_t n=0)
+ : Message{CEPH_MSG_WATCH_NOTIFY, HEAD_VERSION, COMPAT_VERSION},
+ cookie(c),
+ ver(v),
+ notify_id(i),
+ opcode(o),
+ bl(b),
+ return_code(0),
+ notifier_gid(n) { }
+private:
+ ~MWatchNotify() final {}
+
+public:
+ void decode_payload() override {
+ using ceph::decode;
+ 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(std::ostream& out) const override {
+ out << "watch-notify("
+ << ceph_watch_event_name(opcode) << " (" << (int)opcode << ")"
+ << " cookie " << cookie
+ << " notify " << notify_id
+ << " ret " << return_code
+ << ")";
+ }
+private:
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif
diff --git a/src/messages/PaxosServiceMessage.h b/src/messages/PaxosServiceMessage.h
new file mode 100644
index 000000000..a2b1ddf4e
--- /dev/null
+++ b/src/messages/PaxosServiceMessage.h
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+
+#ifndef CEPH_PAXOSSERVICEMESSAGE_H
+#define CEPH_PAXOSSERVICEMESSAGE_H
+
+#include "msg/Message.h"
+#include "mon/Session.h"
+
+class PaxosServiceMessage : public Message {
+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()
+ : Message{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)
+ : Message{type, enc_version, compat_enc_version},
+ version(v), deprecated_session_mon(-1), deprecated_session_mon_tid(0),
+ rx_election_epoch(0) { }
+ protected:
+ ~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(ceph::buffer::list::const_iterator& p ) {
+ using ceph::decode;
+ 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