diff options
Diffstat (limited to '')
155 files changed, 14829 insertions, 0 deletions
diff --git a/src/messages/MAuth.h b/src/messages/MAuth.h new file mode 100644 index 00000000..0075e0b9 --- /dev/null +++ b/src/messages/MAuth.h @@ -0,0 +1,62 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MAUTH_H +#define CEPH_MAUTH_H + +#include "messages/PaxosServiceMessage.h" + +class MAuth : public MessageInstance<MAuth, PaxosServiceMessage> { +public: + friend factory; + + __u32 protocol; + bufferlist auth_payload; + epoch_t monmap_epoch; + + /* if protocol == 0, then auth_payload is a set<__u32> listing protocols the client supports */ + + MAuth() : MessageInstance(CEPH_MSG_AUTH, 0), protocol(0), monmap_epoch(0) { } +private: + ~MAuth() override {} + +public: + std::string_view get_type_name() const override { return "auth"; } + void print(ostream& out) const override { + out << "auth(proto " << protocol << " " << auth_payload.length() << " bytes" + << " epoch " << monmap_epoch << ")"; + } + + void decode_payload() override { + using ceph::encode; + auto p = payload.cbegin(); + paxos_decode(p); + decode(protocol, p); + decode(auth_payload, p); + if (!p.end()) + decode(monmap_epoch, p); + else + monmap_epoch = 0; + } + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(protocol, payload); + encode(auth_payload, payload); + encode(monmap_epoch, payload); + } + bufferlist& get_auth_payload() { return auth_payload; } +}; + +#endif diff --git a/src/messages/MAuthReply.h b/src/messages/MAuthReply.h new file mode 100644 index 00000000..be3368e6 --- /dev/null +++ b/src/messages/MAuthReply.h @@ -0,0 +1,69 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MAUTHREPLY_H +#define CEPH_MAUTHREPLY_H + +#include "msg/Message.h" +#include "common/errno.h" + +class MAuthReply : public MessageInstance<MAuthReply> { +public: + friend factory; + + __u32 protocol; + errorcode32_t result; + uint64_t global_id; // if zero, meaningless + string result_msg; + bufferlist result_bl; + + MAuthReply() : MessageInstance(CEPH_MSG_AUTH_REPLY), protocol(0), result(0), global_id(0) {} + MAuthReply(__u32 p, bufferlist *bl = NULL, int r = 0, uint64_t gid=0, const char *msg = "") : + MessageInstance(CEPH_MSG_AUTH_REPLY), + protocol(p), result(r), global_id(gid), + result_msg(msg) { + if (bl) + result_bl = *bl; + } +private: + ~MAuthReply() override {} + +public: + std::string_view get_type_name() const override { return "auth_reply"; } + void print(ostream& o) const override { + o << "auth_reply(proto " << protocol << " " << result << " " << cpp_strerror(result); + if (result_msg.length()) + o << ": " << result_msg; + o << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(protocol, p); + decode(result, p); + decode(global_id, p); + decode(result_bl, p); + decode(result_msg, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(protocol, payload); + encode(result, payload); + encode(global_id, payload); + encode(result_bl, payload); + encode(result_msg, payload); + } +}; + +#endif diff --git a/src/messages/MBackfillReserve.h b/src/messages/MBackfillReserve.h new file mode 100644 index 00000000..ac813293 --- /dev/null +++ b/src/messages/MBackfillReserve.h @@ -0,0 +1,180 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MBACKFILL_H +#define CEPH_MBACKFILL_H + +#include "msg/Message.h" +#include "messages/MOSDPeeringOp.h" + +class MBackfillReserve : public MessageInstance<MBackfillReserve, MOSDPeeringOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 5; + static constexpr int COMPAT_VERSION = 4; +public: + spg_t pgid; + epoch_t query_epoch; + enum { + REQUEST = 0, // primary->replica: please reserve a slot + GRANT = 1, // replica->primary: ok, i reserved it + REJECT_TOOFULL = 2, // replica->primary: too full, sorry, try again later (*) + RELEASE = 3, // primary->replcia: release the slot i reserved before + REVOKE_TOOFULL = 4, // replica->primary: too full, stop backfilling + REVOKE = 5, // replica->primary: i'm taking back the slot i gave you + // (*) NOTE: prior to luminous, REJECT was overloaded to also mean release + }; + uint32_t type; + uint32_t priority; + int64_t primary_num_bytes; + int64_t shard_num_bytes; + + spg_t get_spg() const { + return pgid; + } + epoch_t get_map_epoch() const { + return query_epoch; + } + epoch_t get_min_epoch() const { + return query_epoch; + } + + PGPeeringEvent *get_event() override { + switch (type) { + case REQUEST: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RequestBackfillPrio(priority, primary_num_bytes, shard_num_bytes)); + case GRANT: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RemoteBackfillReserved()); + case REJECT_TOOFULL: + // NOTE: this is replica -> primary "i reject your request" + // and also primary -> replica "cancel my previously-granted request" + // (for older peers) + // and also replica -> primary "i revoke your reservation" + // (for older peers) + return new PGPeeringEvent( + query_epoch, + query_epoch, + RemoteReservationRejectedTooFull()); + case RELEASE: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RemoteReservationCanceled()); + case REVOKE_TOOFULL: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RemoteReservationRevokedTooFull()); + case REVOKE: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RemoteReservationRevoked()); + default: + ceph_abort(); + } + } + + MBackfillReserve() + : MessageInstance(MSG_OSD_BACKFILL_RESERVE, HEAD_VERSION, COMPAT_VERSION), + query_epoch(0), type(-1), priority(-1), primary_num_bytes(0), + shard_num_bytes(0) {} + MBackfillReserve(int type, + spg_t pgid, + epoch_t query_epoch, unsigned prio = -1, + int64_t primary_num_bytes = 0, + int64_t shard_num_bytes = 0) + : MessageInstance(MSG_OSD_BACKFILL_RESERVE, HEAD_VERSION, COMPAT_VERSION), + pgid(pgid), query_epoch(query_epoch), + type(type), priority(prio), primary_num_bytes(primary_num_bytes), + shard_num_bytes(shard_num_bytes) {} + + std::string_view get_type_name() const override { + return "MBackfillReserve"; + } + + void inner_print(ostream& out) const override { + switch (type) { + case REQUEST: + out << "REQUEST"; + break; + case GRANT: + out << "GRANT"; + break; + case REJECT_TOOFULL: + out << "REJECT_TOOFULL"; + break; + case RELEASE: + out << "RELEASE"; + break; + case REVOKE_TOOFULL: + out << "REVOKE_TOOFULL"; + break; + case REVOKE: + out << "REVOKE"; + break; + } + if (type == REQUEST) out << " prio: " << priority; + return; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(query_epoch, p); + decode(type, p); + decode(priority, p); + decode(pgid.shard, p); + if (header.version >= 5) { + decode(primary_num_bytes, p); + decode(shard_num_bytes, p); + } else { + primary_num_bytes = 0; + shard_num_bytes = 0; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + if (!HAVE_FEATURE(features, RECOVERY_RESERVATION_2)) { + header.version = 3; + header.compat_version = 3; + encode(pgid.pgid, payload); + encode(query_epoch, payload); + encode((type == RELEASE || type == REVOKE_TOOFULL || type == REVOKE) ? + REJECT_TOOFULL : type, payload); + encode(priority, payload); + encode(pgid.shard, payload); + return; + } + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(pgid.pgid, payload); + encode(query_epoch, payload); + encode(type, payload); + encode(priority, payload); + encode(pgid.shard, payload); + encode(primary_num_bytes, payload); + encode(shard_num_bytes, payload); + } +}; + +#endif diff --git a/src/messages/MCacheExpire.h b/src/messages/MCacheExpire.h new file mode 100644 index 00000000..d54bcaf5 --- /dev/null +++ b/src/messages/MCacheExpire.h @@ -0,0 +1,113 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCACHEEXPIRE_H +#define CEPH_MCACHEEXPIRE_H + +#include <string_view> + +#include "msg/Message.h" + +#include "mds/mdstypes.h" + +class MCacheExpire : public MessageInstance<MCacheExpire> { +public: + friend factory; +private: + __s32 from; + +public: + /* + group things by realm (auth delgation root), since that's how auth is determined. + that makes it less work to process when exports are in progress. + */ + struct realm { + map<vinodeno_t, uint32_t> inodes; + map<dirfrag_t, uint32_t> dirs; + map<dirfrag_t, map<pair<string,snapid_t>,uint32_t> > dentries; + + void merge(const realm& o) { + inodes.insert(o.inodes.begin(), o.inodes.end()); + dirs.insert(o.dirs.begin(), o.dirs.end()); + for (const auto &p : o.dentries) { + auto em = dentries.emplace(std::piecewise_construct, std::forward_as_tuple(p.first), std::forward_as_tuple(p.second)); + if (!em.second) { + em.first->second.insert(p.second.begin(), p.second.end()); + } + } + } + + void encode(bufferlist &bl) const { + using ceph::encode; + encode(inodes, bl); + encode(dirs, bl); + encode(dentries, bl); + } + void decode(bufferlist::const_iterator &bl) { + using ceph::decode; + decode(inodes, bl); + decode(dirs, bl); + decode(dentries, bl); + } + }; + WRITE_CLASS_ENCODER(realm) + + map<dirfrag_t, realm> realms; + + int get_from() const { return from; } + +protected: + MCacheExpire() : MessageInstance(MSG_MDS_CACHEEXPIRE), from(-1) {} + MCacheExpire(int f) : + MessageInstance(MSG_MDS_CACHEEXPIRE), + from(f) { } + ~MCacheExpire() override {} + +public: + std::string_view get_type_name() const override { return "cache_expire";} + + void add_inode(dirfrag_t r, vinodeno_t vino, unsigned nonce) { + realms[r].inodes[vino] = nonce; + } + void add_dir(dirfrag_t r, dirfrag_t df, unsigned nonce) { + realms[r].dirs[df] = nonce; + } + void add_dentry(dirfrag_t r, dirfrag_t df, std::string_view dn, snapid_t last, unsigned nonce) { + realms[r].dentries[df][pair<string,snapid_t>(dn,last)] = nonce; + } + + void add_realm(dirfrag_t df, const realm& r) { + auto em = realms.emplace(std::piecewise_construct, std::forward_as_tuple(df), std::forward_as_tuple(r)); + if (!em.second) { + em.first->second.merge(r); + } + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(from, p); + decode(realms, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(from, payload); + encode(realms, payload); + } +}; + +WRITE_CLASS_ENCODER(MCacheExpire::realm) + +#endif diff --git a/src/messages/MClientCapRelease.h b/src/messages/MClientCapRelease.h new file mode 100644 index 00000000..403169bd --- /dev/null +++ b/src/messages/MClientCapRelease.h @@ -0,0 +1,69 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCLIENTCAPRELEASE_H +#define CEPH_MCLIENTCAPRELEASE_H + +#include "msg/Message.h" + + +class MClientCapRelease : public MessageInstance<MClientCapRelease> { +public: + friend factory; + +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + public: + + struct ceph_mds_cap_release head; + vector<ceph_mds_cap_item> caps; + + // The message receiver must wait for this OSD epoch + // before actioning this cap release. + epoch_t osd_epoch_barrier; + + MClientCapRelease() : + MessageInstance(CEPH_MSG_CLIENT_CAPRELEASE, HEAD_VERSION, COMPAT_VERSION), + osd_epoch_barrier(0) + { + memset(&head, 0, sizeof(head)); + } +private: + ~MClientCapRelease() override {} + +public: + std::string_view get_type_name() const override { return "client_cap_release";} + void print(ostream& out) const override { + out << "client_cap_release(" << caps.size() << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(head, p); + decode_nohead(head.num, caps, p); + if (header.version >= 2) { + decode(osd_epoch_barrier, p); + } + } + void encode_payload(uint64_t features) override { + using ceph::encode; + head.num = caps.size(); + encode(head, payload); + encode_nohead(caps, payload); + encode(osd_epoch_barrier, payload); + } +}; + +#endif diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h new file mode 100644 index 00000000..fa069f18 --- /dev/null +++ b/src/messages/MClientCaps.h @@ -0,0 +1,336 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCLIENTCAPS_H +#define CEPH_MCLIENTCAPS_H + +#include "msg/Message.h" +#include "mds/mdstypes.h" +#include "include/ceph_features.h" + +class MClientCaps : public MessageInstance<MClientCaps> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 11; + static constexpr int COMPAT_VERSION = 1; + + public: + static constexpr unsigned FLAG_SYNC = (1<<0); + static constexpr unsigned FLAG_NO_CAPSNAP = (1<<1); // unused + static constexpr unsigned FLAG_PENDING_CAPSNAP = (1<<2); + + struct ceph_mds_caps_head head; + + uint64_t size = 0; + uint64_t max_size = 0; + uint64_t truncate_size = 0; + uint64_t change_attr = 0; + uint32_t truncate_seq = 0; + utime_t mtime, atime, ctime, btime; + uint32_t time_warp_seq = 0; + int64_t nfiles = -1; // files in dir + int64_t nsubdirs = -1; // subdirs in dir + + struct ceph_mds_cap_peer peer; + + bufferlist snapbl; + bufferlist xattrbl; + bufferlist flockbl; + version_t inline_version = 0; + bufferlist inline_data; + + // Receivers may not use their new caps until they have this OSD map + epoch_t osd_epoch_barrier = 0; + ceph_tid_t oldest_flush_tid = 0; + uint32_t caller_uid = 0; + uint32_t caller_gid = 0; + + /* advisory CLIENT_CAPS_* flags to send to mds */ + unsigned flags = 0; + + int get_caps() const { return head.caps; } + int get_wanted() const { return head.wanted; } + int get_dirty() const { return head.dirty; } + ceph_seq_t get_seq() const { return head.seq; } + ceph_seq_t get_issue_seq() const { return head.issue_seq; } + ceph_seq_t get_mseq() const { return head.migrate_seq; } + + inodeno_t get_ino() const { return inodeno_t(head.ino); } + inodeno_t get_realm() const { return inodeno_t(head.realm); } + uint64_t get_cap_id() const { return head.cap_id; } + + uint64_t get_size() const { return size; } + uint64_t get_max_size() const { return max_size; } + __u32 get_truncate_seq() const { return truncate_seq; } + uint64_t get_truncate_size() const { return truncate_size; } + utime_t get_ctime() const { return ctime; } + utime_t get_btime() const { return btime; } + utime_t get_mtime() const { return mtime; } + utime_t get_atime() const { return atime; } + __u64 get_change_attr() const { return change_attr; } + __u32 get_time_warp_seq() const { return time_warp_seq; } + uint64_t get_nfiles() const { return nfiles; } + uint64_t get_nsubdirs() const { return nsubdirs; } + bool dirstat_is_valid() const { return nfiles != -1 || nsubdirs != -1; } + + const file_layout_t& get_layout() const { + return layout; + } + + void set_layout(const file_layout_t &l) { + layout = l; + } + + int get_migrate_seq() const { return head.migrate_seq; } + int get_op() const { return head.op; } + + uint64_t get_client_tid() const { return get_tid(); } + void set_client_tid(uint64_t s) { set_tid(s); } + + snapid_t get_snap_follows() const { return snapid_t(head.snap_follows); } + void set_snap_follows(snapid_t s) { head.snap_follows = s; } + + void set_caps(int c) { head.caps = c; } + void set_wanted(int w) { head.wanted = w; } + + void set_max_size(uint64_t ms) { max_size = ms; } + + void set_migrate_seq(unsigned m) { head.migrate_seq = m; } + void set_op(int o) { head.op = o; } + + void set_size(loff_t s) { size = s; } + void set_mtime(const utime_t &t) { mtime = t; } + void set_ctime(const utime_t &t) { ctime = t; } + void set_atime(const utime_t &t) { atime = t; } + + void set_cap_peer(uint64_t id, ceph_seq_t seq, ceph_seq_t mseq, int mds, int flags) { + peer.cap_id = id; + peer.seq = seq; + peer.mseq = mseq; + peer.mds = mds; + peer.flags = flags; + } + + void set_oldest_flush_tid(ceph_tid_t tid) { oldest_flush_tid = tid; } + ceph_tid_t get_oldest_flush_tid() const { return oldest_flush_tid; } + + void clear_dirty() { head.dirty = 0; } + +protected: + MClientCaps() + : MessageInstance(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION) {} + MClientCaps(int op, + inodeno_t ino, + inodeno_t realm, + uint64_t id, + long seq, + int caps, + int wanted, + int dirty, + int mseq, + epoch_t oeb) + : MessageInstance(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION), + osd_epoch_barrier(oeb) { + memset(&head, 0, sizeof(head)); + head.op = op; + head.ino = ino; + head.realm = realm; + head.cap_id = id; + head.seq = seq; + head.caps = caps; + head.wanted = wanted; + head.dirty = dirty; + head.migrate_seq = mseq; + memset(&peer, 0, sizeof(peer)); + } + MClientCaps(int op, + inodeno_t ino, inodeno_t realm, + uint64_t id, int mseq, epoch_t oeb) + : MessageInstance(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION), + osd_epoch_barrier(oeb) { + memset(&head, 0, sizeof(head)); + head.op = op; + head.ino = ino; + head.realm = realm; + head.cap_id = id; + head.migrate_seq = mseq; + memset(&peer, 0, sizeof(peer)); + } + ~MClientCaps() override {} + +private: + file_layout_t layout; + +public: + std::string_view get_type_name() const override { return "Cfcap";} + void print(ostream& out) const override { + out << "client_caps(" << ceph_cap_op_name(head.op) + << " ino " << inodeno_t(head.ino) + << " " << head.cap_id + << " seq " << head.seq; + if (get_tid()) + out << " tid " << get_tid(); + out << " caps=" << ccap_string(head.caps) + << " dirty=" << ccap_string(head.dirty) + << " wanted=" << ccap_string(head.wanted); + out << " follows " << snapid_t(head.snap_follows); + if (head.migrate_seq) + out << " mseq " << head.migrate_seq; + + out << " size " << size << "/" << max_size; + if (truncate_seq) + out << " ts " << truncate_seq << "/" << truncate_size; + out << " mtime " << mtime; + if (time_warp_seq) + out << " tws " << time_warp_seq; + + if (head.xattr_version) + out << " xattrs(v=" << head.xattr_version << " l=" << xattrbl.length() << ")"; + + out << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(head, p); + ceph_mds_caps_body_legacy body; + decode(body, p); + if (head.op == CEPH_CAP_OP_EXPORT) { + peer = body.peer; + } else { + size = body.size; + max_size = body.max_size; + truncate_size = body.truncate_size; + truncate_seq = body.truncate_seq; + mtime = utime_t(body.mtime); + atime = utime_t(body.atime); + ctime = utime_t(body.ctime); + layout.from_legacy(body.layout); + time_warp_seq = body.time_warp_seq; + } + decode_nohead(head.snap_trace_len, snapbl, p); + + ceph_assert(middle.length() == head.xattr_len); + if (head.xattr_len) + xattrbl = middle; + + // conditionally decode flock metadata + if (header.version >= 2) + decode(flockbl, p); + + if (header.version >= 3) { + if (head.op == CEPH_CAP_OP_IMPORT) + decode(peer, p); + } + + if (header.version >= 4) { + decode(inline_version, p); + decode(inline_data, p); + } else { + inline_version = CEPH_INLINE_NONE; + } + + if (header.version >= 5) { + decode(osd_epoch_barrier, p); + } + if (header.version >= 6) { + decode(oldest_flush_tid, p); + } + if (header.version >= 7) { + decode(caller_uid, p); + decode(caller_gid, p); + } + if (header.version >= 8) { + decode(layout.pool_ns, p); + } + if (header.version >= 9) { + decode(btime, p); + decode(change_attr, p); + } + if (header.version >= 10) { + decode(flags, p); + } + if (header.version >= 11) { + decode(nfiles, p); + decode(nsubdirs, p); + } + } + void encode_payload(uint64_t features) override { + using ceph::encode; + header.version = HEAD_VERSION; + head.snap_trace_len = snapbl.length(); + head.xattr_len = xattrbl.length(); + + encode(head, payload); + ceph_mds_caps_body_legacy body; + if (head.op == CEPH_CAP_OP_EXPORT) { + memset(&body, 0, sizeof(body)); + body.peer = peer; + } else { + body.size = size; + body.max_size = max_size; + body.truncate_size = truncate_size; + body.truncate_seq = truncate_seq; + mtime.encode_timeval(&body.mtime); + atime.encode_timeval(&body.atime); + ctime.encode_timeval(&body.ctime); + layout.to_legacy(&body.layout); + body.time_warp_seq = time_warp_seq; + } + encode(body, payload); + encode_nohead(snapbl, payload); + + middle = xattrbl; + + // conditionally include flock metadata + if (features & CEPH_FEATURE_FLOCK) { + encode(flockbl, payload); + } else { + header.version = 1; + return; + } + + if (features & CEPH_FEATURE_EXPORT_PEER) { + if (head.op == CEPH_CAP_OP_IMPORT) + encode(peer, payload); + } else { + header.version = 2; + return; + } + + if (features & CEPH_FEATURE_MDS_INLINE_DATA) { + encode(inline_version, payload); + encode(inline_data, payload); + } else { + encode(inline_version, payload); + encode(bufferlist(), payload); + } + + encode(osd_epoch_barrier, payload); + encode(oldest_flush_tid, payload); + encode(caller_uid, payload); + encode(caller_gid, payload); + + encode(layout.pool_ns, payload); + encode(btime, payload); + encode(change_attr, payload); + encode(flags, payload); + encode(nfiles, payload); + encode(nsubdirs, payload); + } +}; + +#endif diff --git a/src/messages/MClientLease.h b/src/messages/MClientLease.h new file mode 100644 index 00000000..5c2bf84b --- /dev/null +++ b/src/messages/MClientLease.h @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MCLIENTLEASE_H +#define CEPH_MCLIENTLEASE_H + +#include <string_view> + +#include "msg/Message.h" + +class MClientLease : public MessageInstance<MClientLease> { +public: + friend factory; + + struct ceph_mds_lease h; + std::string dname; + + int get_action() const { return h.action; } + ceph_seq_t get_seq() const { return h.seq; } + int get_mask() const { return h.mask; } + inodeno_t get_ino() const { return inodeno_t(h.ino); } + snapid_t get_first() const { return snapid_t(h.first); } + snapid_t get_last() const { return snapid_t(h.last); } + +protected: + MClientLease() : MessageInstance(CEPH_MSG_CLIENT_LEASE) {} + MClientLease(const MClientLease& m) : + MessageInstance(CEPH_MSG_CLIENT_LEASE), + h(m.h), + dname(m.dname) {} + MClientLease(int ac, ceph_seq_t seq, int m, uint64_t i, uint64_t sf, uint64_t sl) : + MessageInstance(CEPH_MSG_CLIENT_LEASE) { + h.action = ac; + h.seq = seq; + h.mask = m; + h.ino = i; + h.first = sf; + h.last = sl; + h.duration_ms = 0; + } + MClientLease(int ac, ceph_seq_t seq, int m, uint64_t i, uint64_t sf, uint64_t sl, std::string_view d) : + MessageInstance(CEPH_MSG_CLIENT_LEASE), + dname(d) { + h.action = ac; + h.seq = seq; + h.mask = m; + h.ino = i; + h.first = sf; + h.last = sl; + h.duration_ms = 0; + } + ~MClientLease() override {} + +public: + std::string_view get_type_name() const override { return "client_lease"; } + void print(ostream& out) const override { + out << "client_lease(a=" << ceph_lease_op_name(get_action()) + << " seq " << get_seq() + << " mask " << get_mask(); + out << " " << get_ino(); + if (h.last != CEPH_NOSNAP) + out << " [" << snapid_t(h.first) << "," << snapid_t(h.last) << "]"; + if (dname.length()) + out << "/" << dname; + out << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(h, p); + decode(dname, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(h, payload); + encode(dname, payload); + } + +}; + +#endif diff --git a/src/messages/MClientQuota.h b/src/messages/MClientQuota.h new file mode 100644 index 00000000..b1aed00b --- /dev/null +++ b/src/messages/MClientQuota.h @@ -0,0 +1,52 @@ +#ifndef CEPH_MCLIENTQUOTA_H +#define CEPH_MCLIENTQUOTA_H + +#include "msg/Message.h" + +class MClientQuota : public MessageInstance<MClientQuota> { +public: + friend factory; + + inodeno_t ino; + nest_info_t rstat; + quota_info_t quota; + +protected: + MClientQuota() : + MessageInstance(CEPH_MSG_CLIENT_QUOTA), + ino(0) + {} + ~MClientQuota() override {} + +public: + std::string_view get_type_name() const override { return "client_quota"; } + void print(ostream& out) const override { + out << "client_quota("; + out << " [" << ino << "] "; + out << rstat << " "; + out << quota; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(rstat.rctime, payload); + encode(rstat.rbytes, payload); + encode(rstat.rfiles, payload); + encode(rstat.rsubdirs, payload); + encode(quota, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(ino, p); + decode(rstat.rctime, p); + decode(rstat.rbytes, p); + decode(rstat.rfiles, p); + decode(rstat.rsubdirs, p); + decode(quota, p); + ceph_assert(p.end()); + } +}; + +#endif diff --git a/src/messages/MClientReclaim.h b/src/messages/MClientReclaim.h new file mode 100644 index 00000000..ffb7609c --- /dev/null +++ b/src/messages/MClientReclaim.h @@ -0,0 +1,64 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MCLIENTRECLAIM_H +#define CEPH_MCLIENTRECLAIM_H + +#include "msg/Message.h" + +class MClientReclaim: public MessageInstance<MClientReclaim> { +public: + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + static constexpr uint32_t FLAG_FINISH = 1U << 31; + + uint32_t get_flags() const { return flags; } + std::string_view get_uuid() const { return uuid; } + + std::string_view get_type_name() const override { return "client_reclaim"; } + void print(ostream& o) const override { + std::ios_base::fmtflags f(o.flags()); + o << "client_reclaim(" << get_uuid() << " flags 0x" << std::hex << get_flags() << ")"; + o.flags(f); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(uuid, payload); + encode(flags, payload); + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(uuid, p); + decode(flags, p); + } + +protected: + friend factory; + MClientReclaim() : + MessageInstance(CEPH_MSG_CLIENT_RECLAIM, HEAD_VERSION, COMPAT_VERSION) {} + MClientReclaim(std::string_view _uuid, uint32_t _flags) : + MessageInstance(CEPH_MSG_CLIENT_RECLAIM, HEAD_VERSION, COMPAT_VERSION), + uuid(_uuid), flags(_flags) {} +private: + ~MClientReclaim() override {} + + std::string uuid; + uint32_t flags = 0; +}; + +#endif diff --git a/src/messages/MClientReclaimReply.h b/src/messages/MClientReclaimReply.h new file mode 100644 index 00000000..288b8868 --- /dev/null +++ b/src/messages/MClientReclaimReply.h @@ -0,0 +1,69 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MCLIENTRECLAIMREPLY_H +#define CEPH_MCLIENTRECLAIMREPLY_H + +#include "msg/Message.h" + +class MClientReclaimReply: public MessageInstance<MClientReclaimReply> { +public: + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + int32_t get_result() const { return result; } + void set_result(int r) { result = r; } + epoch_t get_epoch() const { return epoch; } + void set_epoch(epoch_t e) { epoch = e; } + const entity_addrvec_t& get_addrs() const { return addrs; } + void set_addrs(const entity_addrvec_t& _addrs) { addrs = _addrs; } + + std::string_view get_type_name() const override { return "client_reclaim_reply"; } + void print(ostream& o) const override { + o << "client_reclaim_reply(" << result << " e " << epoch << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(result, payload); + encode(epoch, payload); + encode(addrs, payload, features); + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(result, p); + decode(epoch, p); + decode(addrs, p); + } + +protected: + friend factory; + MClientReclaimReply() : + MessageInstance(CEPH_MSG_CLIENT_RECLAIM_REPLY, HEAD_VERSION, COMPAT_VERSION) {} + MClientReclaimReply(int r, epoch_t e=0) : + MessageInstance(CEPH_MSG_CLIENT_RECLAIM_REPLY, HEAD_VERSION, COMPAT_VERSION), + result(r), epoch(e) {} + +private: + ~MClientReclaimReply() override {} + + int32_t result; + epoch_t epoch; + entity_addrvec_t addrs; +}; + +#endif diff --git a/src/messages/MClientReconnect.h b/src/messages/MClientReconnect.h new file mode 100644 index 00000000..ba3b0fb2 --- /dev/null +++ b/src/messages/MClientReconnect.h @@ -0,0 +1,174 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCLIENTRECONNECT_H +#define CEPH_MCLIENTRECONNECT_H + +#include "msg/Message.h" +#include "mds/mdstypes.h" +#include "include/ceph_features.h" + + +class MClientReconnect : public MessageInstance<MClientReconnect> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 5; + static constexpr int COMPAT_VERSION = 4; + +public: + map<inodeno_t, cap_reconnect_t> caps; // only head inodes + vector<snaprealm_reconnect_t> realms; + bool more = false; + + MClientReconnect() : + MessageInstance(CEPH_MSG_CLIENT_RECONNECT, HEAD_VERSION, COMPAT_VERSION) {} +private: + ~MClientReconnect() override {} + + size_t cap_size = 0; + size_t realm_size = 0; + size_t approx_size = sizeof(__u32) + sizeof(__u32) + 1; + + void calc_item_size() { + using ceph::encode; + { + bufferlist bl; + inodeno_t ino; + cap_reconnect_t cr; + encode(ino, bl); + encode(cr, bl); + cap_size = bl.length(); + } + { + bufferlist bl; + snaprealm_reconnect_t sr; + encode(sr, bl); + realm_size = bl.length(); + } + } + +public: + std::string_view get_type_name() const override { return "client_reconnect"; } + void print(ostream& out) const override { + out << "client_reconnect(" + << caps.size() << " caps " << realms.size() << " realms )"; + } + + // Force to use old encoding. + // Use connection's features to choose encoding if version is set to 0. + void set_encoding_version(int v) { + header.version = v; + if (v <= 3) + header.compat_version = 0; + } + size_t get_approx_size() { + return approx_size; + } + void mark_more() { more = true; } + bool has_more() const { return more; } + + void add_cap(inodeno_t ino, uint64_t cap_id, inodeno_t pathbase, const string& path, + int wanted, int issued, inodeno_t sr, snapid_t sf, bufferlist& lb) + { + caps[ino] = cap_reconnect_t(cap_id, pathbase, path, wanted, issued, sr, sf, lb); + if (!cap_size) + calc_item_size(); + approx_size += cap_size + path.length() + lb.length(); + } + void add_snaprealm(inodeno_t ino, snapid_t seq, inodeno_t parent) { + snaprealm_reconnect_t r; + r.realm.ino = ino; + r.realm.seq = seq; + r.realm.parent = parent; + realms.push_back(r); + if (!realm_size) + calc_item_size(); + approx_size += realm_size; + } + + void encode_payload(uint64_t features) override { + if (header.version == 0) { + if (features & CEPH_FEATURE_MDSENC) + header.version = 3; + else if (features & CEPH_FEATURE_FLOCK) + header.version = 2; + else + header.version = 1; + } + + using ceph::encode; + data.clear(); + + if (header.version >= 4) { + encode(caps, data); + encode(realms, data); + encode(more, data); + } else { + // compat crap + if (header.version == 3) { + encode(caps, data); + } else if (header.version == 2) { + __u32 n = caps.size(); + encode(n, data); + for (auto& p : caps) { + encode(p.first, data); + p.second.encode_old(data); + } + } else { + map<inodeno_t, old_cap_reconnect_t> ocaps; + for (auto& p : caps) { + ocaps[p.first] = p.second; + encode(ocaps, data); + } + for (auto& r : realms) + r.encode_old(data); + } + } + } + void decode_payload() override { + auto p = data.cbegin(); + if (header.version >= 4) { + decode(caps, p); + decode(realms, p); + if (header.version >= 5) + decode(more, p); + } else { + // compat crap + if (header.version == 3) { + decode(caps, p); + } else if (header.version == 2) { + __u32 n; + decode(n, p); + inodeno_t ino; + while (n--) { + decode(ino, p); + caps[ino].decode_old(p); + } + } else { + map<inodeno_t, old_cap_reconnect_t> ocaps; + decode(ocaps, p); + for (auto &q : ocaps) + caps[q.first] = q.second; + } + while (!p.end()) { + realms.push_back(snaprealm_reconnect_t()); + realms.back().decode_old(p); + } + } + } +}; + + +#endif diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h new file mode 100644 index 00000000..fb1ebfe8 --- /dev/null +++ b/src/messages/MClientReply.h @@ -0,0 +1,361 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MCLIENTREPLY_H +#define CEPH_MCLIENTREPLY_H + +#include "include/types.h" +#include "include/fs_types.h" +#include "MClientRequest.h" + +#include "msg/Message.h" +#include "include/ceph_features.h" +#include "common/errno.h" + +/*** + * + * MClientReply - container message for MDS reply to a client's MClientRequest + * + * key fields: + * long tid - transaction id, so the client can match up with pending request + * int result - error code, or fh if it was open + * + * for most requests: + * trace is a vector of InodeStat's tracing from root to the file/dir/whatever + * the operation referred to, so that the client can update it's info about what + * metadata lives on what MDS. + * + * for readdir replies: + * dir_contents is a vector of InodeStat*'s. + * + * that's mostly it, i think! + * + */ + + +struct LeaseStat { + // this matches ceph_mds_reply_lease + __u16 mask; + __u32 duration_ms; + __u32 seq; + + LeaseStat() : mask(0), duration_ms(0), seq(0) {} + LeaseStat(__u16 msk, __u32 dur, __u32 sq) : mask{msk}, duration_ms{dur}, seq{sq} {} + + void decode(bufferlist::const_iterator &bl, const uint64_t features) { + using ceph::decode; + if (features == (uint64_t)-1) { + DECODE_START(1, bl); + decode(mask, bl); + decode(duration_ms, bl); + decode(seq, bl); + DECODE_FINISH(bl); + } + else { + decode(mask, bl); + decode(duration_ms, bl); + decode(seq, bl); + } + } +}; + +inline ostream& operator<<(ostream& out, const LeaseStat& l) { + return out << "lease(mask " << l.mask << " dur " << l.duration_ms << ")"; +} + +struct DirStat { + // mds distribution hints + frag_t frag; + __s32 auth; + set<__s32> dist; + + DirStat() : auth(CDIR_AUTH_PARENT) {} + DirStat(bufferlist::const_iterator& p, const uint64_t features) { + decode(p, features); + } + + void decode(bufferlist::const_iterator& p, const uint64_t features) { + using ceph::decode; + if (features == (uint64_t)-1) { + DECODE_START(1, p); + decode(frag, p); + decode(auth, p); + decode(dist, p); + DECODE_FINISH(p); + } + else { + decode(frag, p); + decode(auth, p); + decode(dist, p); + } + } + + // see CDir::encode_dirstat for encoder. +}; + +struct InodeStat { + vinodeno_t vino; + uint32_t rdev = 0; + version_t version = 0; + version_t xattr_version = 0; + ceph_mds_reply_cap cap; + file_layout_t layout; + utime_t ctime, btime, mtime, atime, snap_btime; + uint32_t time_warp_seq = 0; + uint64_t size = 0, max_size = 0; + uint64_t change_attr = 0; + uint64_t truncate_size = 0; + uint32_t truncate_seq = 0; + uint32_t mode = 0, uid = 0, gid = 0, nlink = 0; + frag_info_t dirstat; + nest_info_t rstat; + + fragtree_t dirfragtree; + string symlink; // symlink content (if symlink) + + ceph_dir_layout dir_layout; + + bufferlist xattrbl; + + bufferlist inline_data; + version_t inline_version; + + quota_info_t quota; + + mds_rank_t dir_pin; + + public: + InodeStat() {} + InodeStat(bufferlist::const_iterator& p, const uint64_t features) { + decode(p, features); + } + + void decode(bufferlist::const_iterator &p, const uint64_t features) { + using ceph::decode; + if (features == (uint64_t)-1) { + DECODE_START(2, p); + decode(vino.ino, p); + decode(vino.snapid, p); + decode(rdev, p); + decode(version, p); + decode(xattr_version, p); + decode(cap, p); + { + ceph_file_layout legacy_layout; + decode(legacy_layout, p); + layout.from_legacy(legacy_layout); + } + decode(ctime, p); + decode(mtime, p); + decode(atime, p); + decode(time_warp_seq, p); + decode(size, p); + decode(max_size, p); + decode(truncate_size, p); + decode(truncate_seq, p); + decode(mode, p); + decode(uid, p); + decode(gid, p); + decode(nlink, p); + decode(dirstat.nfiles, p); + decode(dirstat.nsubdirs, p); + decode(rstat.rbytes, p); + decode(rstat.rfiles, p); + decode(rstat.rsubdirs, p); + decode(rstat.rctime, p); + decode(dirfragtree, p); + decode(symlink, p); + decode(dir_layout, p); + decode(xattrbl, p); + decode(inline_version, p); + decode(inline_data, p); + decode(quota, p); + decode(layout.pool_ns, p); + decode(btime, p); + decode(change_attr, p); + if (struct_v > 1) { + decode(dir_pin, p); + } else { + dir_pin = -ENODATA; + } + if (struct_v >= 3) { + decode(snap_btime, p); + } // else remains zero + DECODE_FINISH(p); + } + else { + decode(vino.ino, p); + decode(vino.snapid, p); + decode(rdev, p); + decode(version, p); + decode(xattr_version, p); + decode(cap, p); + { + ceph_file_layout legacy_layout; + decode(legacy_layout, p); + layout.from_legacy(legacy_layout); + } + decode(ctime, p); + decode(mtime, p); + decode(atime, p); + decode(time_warp_seq, p); + decode(size, p); + decode(max_size, p); + decode(truncate_size, p); + decode(truncate_seq, p); + decode(mode, p); + decode(uid, p); + decode(gid, p); + decode(nlink, p); + decode(dirstat.nfiles, p); + decode(dirstat.nsubdirs, p); + decode(rstat.rbytes, p); + decode(rstat.rfiles, p); + decode(rstat.rsubdirs, p); + decode(rstat.rctime, p); + decode(dirfragtree, p); + decode(symlink, p); + if (features & CEPH_FEATURE_DIRLAYOUTHASH) + decode(dir_layout, p); + else + memset(&dir_layout, 0, sizeof(dir_layout)); + + decode(xattrbl, p); + + if (features & CEPH_FEATURE_MDS_INLINE_DATA) { + decode(inline_version, p); + decode(inline_data, p); + } else { + inline_version = CEPH_INLINE_NONE; + } + + if (features & CEPH_FEATURE_MDS_QUOTA) + decode(quota, p); + else + quota = quota_info_t{}; + + if ((features & CEPH_FEATURE_FS_FILE_LAYOUT_V2)) + decode(layout.pool_ns, p); + + if ((features & CEPH_FEATURE_FS_BTIME)) { + decode(btime, p); + decode(change_attr, p); + } else { + btime = utime_t(); + change_attr = 0; + } + } + } + + // see CInode::encode_inodestat for encoder. +}; + + +class MClientReply : public MessageInstance<MClientReply> { +public: + friend factory; + + // reply data + struct ceph_mds_reply_head head {}; + bufferlist trace_bl; + bufferlist extra_bl; + bufferlist snapbl; + + int get_op() const { return head.op; } + + void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; } + epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; } + + int get_result() const { + return ceph_to_hostos_errno((__s32)(__u32)head.result); + } + + void set_result(int r) { head.result = r; } + + void set_unsafe() { head.safe = 0; } + + bool is_safe() const { return head.safe; } + +protected: + MClientReply() : MessageInstance(CEPH_MSG_CLIENT_REPLY) {} + MClientReply(const MClientRequest &req, int result = 0) : + MessageInstance(CEPH_MSG_CLIENT_REPLY) { + memset(&head, 0, sizeof(head)); + header.tid = req.get_tid(); + head.op = req.get_op(); + head.result = result; + head.safe = 1; + } + ~MClientReply() override {} + +public: + std::string_view get_type_name() const override { return "creply"; } + void print(ostream& o) const override { + o << "client_reply(???:" << get_tid(); + o << " = " << get_result(); + if (get_result() <= 0) { + o << " " << cpp_strerror(get_result()); + } + if (head.op & CEPH_MDS_OP_WRITE) { + if (head.safe) + o << " safe"; + else + o << " unsafe"; + } + o << ")"; + } + + // serialization + void decode_payload() override { + auto p = payload.cbegin(); + decode(head, p); + decode(trace_bl, p); + decode(extra_bl, p); + decode(snapbl, p); + ceph_assert(p.end()); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(head, payload); + encode(trace_bl, payload); + encode(extra_bl, payload); + encode(snapbl, payload); + } + + + // dir contents + void set_extra_bl(bufferlist& bl) { + extra_bl.claim(bl); + } + bufferlist& get_extra_bl() { + return extra_bl; + } + const bufferlist& get_extra_bl() const { + return extra_bl; + } + + // trace + void set_trace(bufferlist& bl) { + trace_bl.claim(bl); + } + bufferlist& get_trace_bl() { + return trace_bl; + } + const bufferlist& get_trace_bl() const { + return trace_bl; + } +}; + +#endif diff --git a/src/messages/MClientRequest.h b/src/messages/MClientRequest.h new file mode 100644 index 00000000..602eff1d --- /dev/null +++ b/src/messages/MClientRequest.h @@ -0,0 +1,289 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MCLIENTREQUEST_H +#define CEPH_MCLIENTREQUEST_H + +/** + * + * MClientRequest - container for a client METADATA request. created/sent by clients. + * can be forwarded around between MDS's. + * + * int client - the originating client + * long tid - transaction id, unique among requests for that client. probably just a counter! + * -> the MDS passes the Request to the Reply constructor, so this always matches. + * + * int op - the metadata op code. MDS_OP_RENAME, etc. + * int caller_uid, _gid - guess + * + * fixed size arguments are in a union. + * there's also a string argument, for e.g. symlink(). + * + */ + +#include <string_view> + +#include "msg/Message.h" +#include "include/filepath.h" +#include "mds/mdstypes.h" +#include "include/ceph_features.h" + +#include <sys/types.h> +#include <utime.h> +#include <sys/stat.h> +#include <fcntl.h> + + +// metadata ops. + +class MClientRequest : public MessageInstance<MClientRequest> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 1; + +public: + mutable struct ceph_mds_request_head head; /* XXX HACK! */ + utime_t stamp; + + struct Release { + mutable ceph_mds_request_release item; + string dname; + + Release() : item(), dname() {} + Release(const ceph_mds_request_release& rel, string name) : + item(rel), dname(name) {} + + void encode(bufferlist& bl) const { + using ceph::encode; + item.dname_len = dname.length(); + encode(item, bl); + encode_nohead(dname, bl); + } + void decode(bufferlist::const_iterator& bl) { + using ceph::decode; + decode(item, bl); + decode_nohead(item.dname_len, dname, bl); + } + }; + mutable vector<Release> releases; /* XXX HACK! */ + + // path arguments + filepath path, path2; + vector<uint64_t> gid_list; + + /* XXX HACK */ + mutable bool queued_for_replay = false; + +protected: + // cons + MClientRequest() + : MessageInstance(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {} + MClientRequest(int op) + : MessageInstance(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) { + memset(&head, 0, sizeof(head)); + head.op = op; + } + ~MClientRequest() override {} + +public: + void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; } + epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; } + epoch_t get_osdmap_epoch() const { + ceph_assert(head.op == CEPH_MDS_OP_SETXATTR); + if (header.version >= 3) + return head.args.setxattr.osdmap_epoch; + else + return 0; + } + void set_osdmap_epoch(epoch_t e) { + ceph_assert(head.op == CEPH_MDS_OP_SETXATTR); + head.args.setxattr.osdmap_epoch = e; + } + + metareqid_t get_reqid() const { + // FIXME: for now, assume clients always have 1 incarnation + return metareqid_t(get_orig_source(), header.tid); + } + + /*bool open_file_mode_is_readonly() { + return file_mode_is_readonly(ceph_flags_to_mode(head.args.open.flags)); + }*/ + bool may_write() const { + return + (head.op & CEPH_MDS_OP_WRITE) || + (head.op == CEPH_MDS_OP_OPEN && (head.args.open.flags & (O_CREAT|O_TRUNC))); + } + + int get_flags() const { + return head.flags; + } + bool is_replay() const { + return get_flags() & CEPH_MDS_FLAG_REPLAY; + } + + // normal fields + void set_stamp(utime_t t) { stamp = t; } + void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; } + void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; } + void set_retry_attempt(int a) { head.num_retry = a; } + void set_filepath(const filepath& fp) { path = fp; } + void set_filepath2(const filepath& fp) { path2 = fp; } + void set_string2(const char *s) { path2.set_path(std::string_view(s), 0); } + void set_caller_uid(unsigned u) { head.caller_uid = u; } + void set_caller_gid(unsigned g) { head.caller_gid = g; } + void set_gid_list(int count, const gid_t *gids) { + gid_list.reserve(count); + for (int i = 0; i < count; ++i) { + gid_list.push_back(gids[i]); + } + } + void set_dentry_wanted() { + head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY; + } + void set_replayed_op() { + head.flags = head.flags | CEPH_MDS_FLAG_REPLAY; + } + + utime_t get_stamp() const { return stamp; } + ceph_tid_t get_oldest_client_tid() const { return head.oldest_client_tid; } + int get_num_fwd() const { return head.num_fwd; } + int get_retry_attempt() const { return head.num_retry; } + int get_op() const { return head.op; } + unsigned get_caller_uid() const { return head.caller_uid; } + unsigned get_caller_gid() const { return head.caller_gid; } + const vector<uint64_t>& get_caller_gid_list() const { return gid_list; } + + const string& get_path() const { return path.get_path(); } + const filepath& get_filepath() const { return path; } + const string& get_path2() const { return path2.get_path(); } + const filepath& get_filepath2() const { return path2; } + + int get_dentry_wanted() const { return get_flags() & CEPH_MDS_FLAG_WANT_DENTRY; } + + void mark_queued_for_replay() const { queued_for_replay = true; } + bool is_queued_for_replay() const { return queued_for_replay; } + + void decode_payload() override { + auto p = payload.cbegin(); + + if (header.version >= 4) { + decode(head, p); + } else { + struct ceph_mds_request_head_legacy old_mds_head; + + decode(old_mds_head, p); + copy_from_legacy_head(&head, &old_mds_head); + head.version = 0; + + /* Can't set the btime from legacy struct */ + if (head.op == CEPH_MDS_OP_SETATTR) { + int localmask = head.args.setattr.mask; + + localmask &= ~CEPH_SETATTR_BTIME; + + head.args.setattr.btime = { 0 }; + head.args.setattr.mask = localmask; + } + } + + decode(path, p); + decode(path2, p); + decode_nohead(head.num_releases, releases, p); + if (header.version >= 2) + decode(stamp, p); + if (header.version >= 4) // epoch 3 was for a ceph_mds_request_args change + decode(gid_list, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + head.num_releases = releases.size(); + head.version = CEPH_MDS_REQUEST_HEAD_VERSION; + + if (features & CEPH_FEATURE_FS_BTIME) { + encode(head, payload); + } else { + struct ceph_mds_request_head_legacy old_mds_head; + + copy_to_legacy_head(&old_mds_head, &head); + encode(old_mds_head, payload); + } + + encode(path, payload); + encode(path2, payload); + encode_nohead(releases, payload); + encode(stamp, payload); + encode(gid_list, payload); + } + + std::string_view get_type_name() const override { return "creq"; } + void print(ostream& out) const override { + out << "client_request(" << get_orig_source() + << ":" << get_tid() + << " " << ceph_mds_op_name(get_op()); + if (head.op == CEPH_MDS_OP_GETATTR) + out << " " << ccap_string(head.args.getattr.mask); + if (head.op == CEPH_MDS_OP_SETATTR) { + if (head.args.setattr.mask & CEPH_SETATTR_MODE) + out << " mode=0" << std::oct << head.args.setattr.mode << std::dec; + if (head.args.setattr.mask & CEPH_SETATTR_UID) + out << " uid=" << head.args.setattr.uid; + if (head.args.setattr.mask & CEPH_SETATTR_GID) + out << " gid=" << head.args.setattr.gid; + if (head.args.setattr.mask & CEPH_SETATTR_SIZE) + out << " size=" << head.args.setattr.size; + if (head.args.setattr.mask & CEPH_SETATTR_MTIME) + out << " mtime=" << utime_t(head.args.setattr.mtime); + if (head.args.setattr.mask & CEPH_SETATTR_ATIME) + out << " atime=" << utime_t(head.args.setattr.atime); + } + if (head.op == CEPH_MDS_OP_SETFILELOCK || + head.op == CEPH_MDS_OP_GETFILELOCK) { + out << " rule " << (int)head.args.filelock_change.rule + << ", type " << (int)head.args.filelock_change.type + << ", owner " << head.args.filelock_change.owner + << ", pid " << head.args.filelock_change.pid + << ", start " << head.args.filelock_change.start + << ", length " << head.args.filelock_change.length + << ", wait " << (int)head.args.filelock_change.wait; + } + //if (!get_filepath().empty()) + out << " " << get_filepath(); + if (!get_filepath2().empty()) + out << " " << get_filepath2(); + if (stamp != utime_t()) + out << " " << stamp; + if (head.num_retry) + out << " RETRY=" << (int)head.num_retry; + if (get_flags() & CEPH_MDS_FLAG_REPLAY) + out << " REPLAY"; + if (queued_for_replay) + out << " QUEUED_FOR_REPLAY"; + out << " caller_uid=" << head.caller_uid + << ", caller_gid=" << head.caller_gid + << '{'; + for (auto i = gid_list.begin(); i != gid_list.end(); ++i) + out << *i << ','; + out << '}' + << ")"; + } + +}; + +WRITE_CLASS_ENCODER(MClientRequest::Release) + +#endif diff --git a/src/messages/MClientRequestForward.h b/src/messages/MClientRequestForward.h new file mode 100644 index 00000000..e3dc8071 --- /dev/null +++ b/src/messages/MClientRequestForward.h @@ -0,0 +1,70 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MCLIENTREQUESTFORWARD_H +#define CEPH_MCLIENTREQUESTFORWARD_H + +#include "msg/Message.h" + +class MClientRequestForward : public MessageInstance<MClientRequestForward> { +public: + friend factory; +private: + int32_t dest_mds; + int32_t num_fwd; + bool client_must_resend; + +protected: + MClientRequestForward() + : MessageInstance(CEPH_MSG_CLIENT_REQUEST_FORWARD), + dest_mds(-1), num_fwd(-1), client_must_resend(false) {} + MClientRequestForward(ceph_tid_t t, int dm, int nf, bool cmr) : + MessageInstance(CEPH_MSG_CLIENT_REQUEST_FORWARD), + dest_mds(dm), num_fwd(nf), client_must_resend(cmr) { + ceph_assert(client_must_resend); + header.tid = t; + } + ~MClientRequestForward() override {} + +public: + int get_dest_mds() const { return dest_mds; } + int get_num_fwd() const { return num_fwd; } + bool must_resend() const { return client_must_resend; } + + std::string_view get_type_name() const override { return "client_request_forward"; } + void print(ostream& o) const override { + o << "client_request_forward(" << get_tid() + << " to mds." << dest_mds + << " num_fwd=" << num_fwd + << (client_must_resend ? " client_must_resend":"") + << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dest_mds, payload); + encode(num_fwd, payload); + encode(client_must_resend, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(dest_mds, p); + decode(num_fwd, p); + decode(client_must_resend, p); + } +}; + +#endif diff --git a/src/messages/MClientSession.h b/src/messages/MClientSession.h new file mode 100644 index 00000000..c7a2a3b5 --- /dev/null +++ b/src/messages/MClientSession.h @@ -0,0 +1,92 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCLIENTSESSION_H +#define CEPH_MCLIENTSESSION_H + +#include "msg/Message.h" +#include "mds/mdstypes.h" + +class MClientSession : public MessageInstance<MClientSession> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + +public: + ceph_mds_session_head head; + + std::map<std::string, std::string> metadata; + feature_bitset_t supported_features; + + int get_op() const { return head.op; } + version_t get_seq() const { return head.seq; } + utime_t get_stamp() const { return utime_t(head.stamp); } + int get_max_caps() const { return head.max_caps; } + int get_max_leases() const { return head.max_leases; } + +protected: + MClientSession() : MessageInstance(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) { } + MClientSession(int o, version_t s=0) : + MessageInstance(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) { + memset(&head, 0, sizeof(head)); + head.op = o; + head.seq = s; + } + MClientSession(int o, utime_t st) : + MessageInstance(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) { + memset(&head, 0, sizeof(head)); + head.op = o; + head.seq = 0; + st.encode_timeval(&head.stamp); + } + ~MClientSession() override {} + +public: + std::string_view get_type_name() const override { return "client_session"; } + void print(ostream& out) const override { + out << "client_session(" << ceph_session_op_name(get_op()); + if (get_seq()) + out << " seq " << get_seq(); + if (get_op() == CEPH_SESSION_RECALL_STATE) + out << " max_caps " << head.max_caps << " max_leases " << head.max_leases; + out << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(head, p); + if (header.version >= 2) + decode(metadata, p); + if (header.version >= 3) + decode(supported_features, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(head, payload); + if (metadata.empty() && supported_features.empty()) { + // If we're not trying to send any metadata (always the case if + // we are a server) then send older-format message to avoid upsetting + // old kernel clients. + header.version = 1; + } else { + header.version = HEAD_VERSION; + encode(metadata, payload); + encode(supported_features, payload); + } + } +}; + +#endif diff --git a/src/messages/MClientSnap.h b/src/messages/MClientSnap.h new file mode 100644 index 00000000..f0f96e4e --- /dev/null +++ b/src/messages/MClientSnap.h @@ -0,0 +1,70 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCLIENTSNAP_H +#define CEPH_MCLIENTSNAP_H + +#include "msg/Message.h" + +class MClientSnap : public MessageInstance<MClientSnap> { +public: + friend factory; + + ceph_mds_snap_head head; + bufferlist bl; + + // (for split only) + vector<inodeno_t> split_inos; + vector<inodeno_t> split_realms; + +protected: + MClientSnap(int o=0) : + MessageInstance(CEPH_MSG_CLIENT_SNAP) { + memset(&head, 0, sizeof(head)); + head.op = o; + } + ~MClientSnap() override {} + +public: + std::string_view get_type_name() const override { return "client_snap"; } + void print(ostream& out) const override { + out << "client_snap(" << ceph_snap_op_name(head.op); + if (head.split) + out << " split=" << inodeno_t(head.split); + out << " tracelen=" << bl.length(); + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + head.num_split_inos = split_inos.size(); + head.num_split_realms = split_realms.size(); + head.trace_len = bl.length(); + encode(head, payload); + encode_nohead(split_inos, payload); + encode_nohead(split_realms, payload); + encode_nohead(bl, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(head, p); + decode_nohead(head.num_split_inos, split_inos, p); + decode_nohead(head.num_split_realms, split_realms, p); + decode_nohead(head.trace_len, bl, p); + ceph_assert(p.end()); + } + +}; + +#endif diff --git a/src/messages/MCommand.h b/src/messages/MCommand.h new file mode 100644 index 00000000..421d04c2 --- /dev/null +++ b/src/messages/MCommand.h @@ -0,0 +1,61 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCOMMAND_H +#define CEPH_MCOMMAND_H + +#include <vector> + +#include "msg/Message.h" + +class MCommand : public MessageInstance<MCommand> { +public: + friend factory; + + uuid_d fsid; + std::vector<string> cmd; + + MCommand() + : MessageInstance(MSG_COMMAND) {} + MCommand(const uuid_d &f) + : MessageInstance(MSG_COMMAND), + fsid(f) { } + +private: + ~MCommand() override {} + +public: + std::string_view get_type_name() const override { return "command"; } + void print(ostream& o) const override { + o << "command(tid " << get_tid() << ": "; + for (unsigned i=0; i<cmd.size(); i++) { + if (i) o << ' '; + o << cmd[i]; + } + o << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(fsid, payload); + encode(cmd, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(cmd, p); + } +}; + +#endif diff --git a/src/messages/MCommandReply.h b/src/messages/MCommandReply.h new file mode 100644 index 00000000..d740565b --- /dev/null +++ b/src/messages/MCommandReply.h @@ -0,0 +1,60 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MCOMMANDREPLY_H +#define CEPH_MCOMMANDREPLY_H + +#include <string_view> + +#include "msg/Message.h" +#include "MCommand.h" + +class MCommandReply : public MessageInstance<MCommandReply> { +public: + friend factory; + + errorcode32_t r; + string rs; + + MCommandReply() + : MessageInstance(MSG_COMMAND_REPLY) {} + MCommandReply(MCommand *m, int _r) + : MessageInstance(MSG_COMMAND_REPLY), r(_r) { + header.tid = m->get_tid(); + } + MCommandReply(int _r, std::string_view s) + : MessageInstance(MSG_COMMAND_REPLY), + r(_r), rs(s) { } +private: + ~MCommandReply() override {} + +public: + std::string_view get_type_name() const override { return "command_reply"; } + void print(ostream& o) const override { + o << "command_reply(tid " << get_tid() << ": " << r << " " << rs << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(r, payload); + encode(rs, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(r, p); + decode(rs, p); + } +}; + +#endif diff --git a/src/messages/MConfig.h b/src/messages/MConfig.h new file mode 100644 index 00000000..1e433e52 --- /dev/null +++ b/src/messages/MConfig.h @@ -0,0 +1,40 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" + +class MConfig : public MessageInstance<MConfig> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + map<string,string> config; + + MConfig() : MessageInstance(MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION) { } + MConfig(const map<string,string>& c) + : MessageInstance(MSG_CONFIG, HEAD_VERSION, COMPAT_VERSION), + config(c) {} + + std::string_view get_type_name() const override { + return "config"; + } + void print(ostream& o) const override { + o << "config(" << config.size() << " keys" << ")"; + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(config, p); + } + + void encode_payload(uint64_t) override { + using ceph::encode; + encode(config, payload); + } + +}; diff --git a/src/messages/MDataPing.h b/src/messages/MDataPing.h new file mode 100644 index 00000000..615bdc05 --- /dev/null +++ b/src/messages/MDataPing.h @@ -0,0 +1,92 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MDATAPING_H +#define CEPH_MDATAPING_H + +#include "msg/Message.h" +#include "messages/MPing.h" +#include "include/encoding.h" +#if defined(HAVE_XIO) +extern "C" { +#include "libxio.h" +} +#else +struct xio_reg_mem {}; +#endif /* HAVE_XIO */ + +typedef void (*mdata_hook_func)(struct xio_reg_mem *mp); + +class MDataPing : public MessageInstance<MDataPing> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + std::string tag; + uint32_t counter = 0; + mdata_hook_func mdata_hook; + struct xio_reg_mem mp; + bool free_data; + + MDataPing() + : MessageInstance(MSG_DATA_PING, HEAD_VERSION, COMPAT_VERSION), + mdata_hook(NULL), + free_data(false) + {} + + struct xio_reg_mem *get_mp() + { + return ∓ + } + + void set_rdma_hook(mdata_hook_func hook) + { + mdata_hook = hook; + } + +private: + ~MDataPing() override + { + if (mdata_hook) + mdata_hook(&mp); + + if (free_data) { + for (const auto& node : data.buffers()) { + free(const_cast<void*>(static_cast<const void*>(node.c_str()))); + } + } + } + +public: + void decode_payload() override { + auto p = payload.cbegin(); + decode(tag, p); + decode(counter, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(tag, payload); + encode(counter, payload); + } + + std::string_view get_type_name() const override { return "data_ping"; } + + void print(ostream& out) const override { + out << get_type_name() << " " << tag << " " << counter; + } +}; + +#endif /* CEPH_MDATAPING_H */ diff --git a/src/messages/MDentryLink.h b/src/messages/MDentryLink.h new file mode 100644 index 00000000..75dea9ba --- /dev/null +++ b/src/messages/MDentryLink.h @@ -0,0 +1,75 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MDENTRYLINK_H +#define CEPH_MDENTRYLINK_H + +#include <string_view> + +#include "msg/Message.h" + +class MDentryLink : public MessageInstance<MDentryLink> { +public: + friend factory; +private: + dirfrag_t subtree; + dirfrag_t dirfrag; + string dn; + bool is_primary = false; + + public: + dirfrag_t get_subtree() const { return subtree; } + dirfrag_t get_dirfrag() const { return dirfrag; } + const string& get_dn() const { return dn; } + bool get_is_primary() const { return is_primary; } + + bufferlist bl; + +protected: + MDentryLink() : + MessageInstance(MSG_MDS_DENTRYLINK) { } + MDentryLink(dirfrag_t r, dirfrag_t df, std::string_view n, bool p) : + MessageInstance(MSG_MDS_DENTRYLINK), + subtree(r), + dirfrag(df), + dn(n), + is_primary(p) {} + ~MDentryLink() override {} + +public: + std::string_view get_type_name() const override { return "dentry_link";} + void print(ostream& o) const override { + o << "dentry_link(" << dirfrag << " " << dn << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(subtree, p); + decode(dirfrag, p); + decode(dn, p); + decode(is_primary, p); + decode(bl, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(subtree, payload); + encode(dirfrag, payload); + encode(dn, payload); + encode(is_primary, payload); + encode(bl, payload); + } +}; + +#endif diff --git a/src/messages/MDentryUnlink.h b/src/messages/MDentryUnlink.h new file mode 100644 index 00000000..1d3d9715 --- /dev/null +++ b/src/messages/MDentryUnlink.h @@ -0,0 +1,67 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MDENTRYUNLINK_H +#define CEPH_MDENTRYUNLINK_H + +#include <string_view> + +#include "msg/Message.h" + +class MDentryUnlink : public MessageInstance<MDentryUnlink> { +public: + friend factory; +private: + + dirfrag_t dirfrag; + string dn; + + public: + dirfrag_t get_dirfrag() const { return dirfrag; } + const string& get_dn() const { return dn; } + + bufferlist straybl; + bufferlist snapbl; + +protected: + MDentryUnlink() : + MessageInstance(MSG_MDS_DENTRYUNLINK) { } + MDentryUnlink(dirfrag_t df, std::string_view n) : + MessageInstance(MSG_MDS_DENTRYUNLINK), + dirfrag(df), + dn(n) {} + ~MDentryUnlink() override {} + +public: + std::string_view get_type_name() const override { return "dentry_unlink";} + void print(ostream& o) const override { + o << "dentry_unlink(" << dirfrag << " " << dn << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(dn, p); + decode(straybl, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(dn, payload); + encode(straybl, payload); + } +}; + +#endif diff --git a/src/messages/MDirUpdate.h b/src/messages/MDirUpdate.h new file mode 100644 index 00000000..c1154ac7 --- /dev/null +++ b/src/messages/MDirUpdate.h @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MDIRUPDATE_H +#define CEPH_MDIRUPDATE_H + +#include "msg/Message.h" + +class MDirUpdate : public MessageInstance<MDirUpdate> { +public: + friend factory; + + mds_rank_t get_source_mds() const { return from_mds; } + dirfrag_t get_dirfrag() const { return dirfrag; } + int get_dir_rep() const { return dir_rep; } + const std::set<int32_t>& get_dir_rep_by() const { return dir_rep_by; } + bool should_discover() const { return discover > tried_discover; } + const filepath& get_path() const { return path; } + + bool has_tried_discover() const { return tried_discover > 0; } + void inc_tried_discover() const { ++tried_discover; } + + std::string_view get_type_name() const override { return "dir_update"; } + void print(ostream& out) const override { + out << "dir_update(" << get_dirfrag() << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(from_mds, p); + decode(dirfrag, p); + decode(dir_rep, p); + decode(discover, p); + decode(dir_rep_by, p); + decode(path, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(from_mds, payload); + encode(dirfrag, payload); + encode(dir_rep, payload); + encode(discover, payload); + encode(dir_rep_by, payload); + encode(path, payload); + } + +protected: + ~MDirUpdate() {} + MDirUpdate() : MessageInstance(MSG_MDS_DIRUPDATE) {} + MDirUpdate(mds_rank_t f, + dirfrag_t dirfrag, + int dir_rep, + const std::set<int32_t>& dir_rep_by, + filepath& path, + bool discover = false) : + MessageInstance(MSG_MDS_DIRUPDATE), from_mds(f), dirfrag(dirfrag), + dir_rep(dir_rep), dir_rep_by(dir_rep_by), path(path) { + this->discover = discover ? 5 : 0; + } + MDirUpdate(const MDirUpdate& m) + : MessageInstance(MSG_MDS_DIRUPDATE), + from_mds(m.from_mds), + dirfrag(m.dirfrag), + dir_rep(m.dir_rep), + discover(m.discover), + dir_rep_by(m.dir_rep_by), + path(m.path), + tried_discover(m.tried_discover) + {} + + mds_rank_t from_mds = -1; + dirfrag_t dirfrag; + int32_t dir_rep = 5; + int32_t discover = 5; + std::set<int32_t> dir_rep_by; + filepath path; + mutable int tried_discover = 0; // XXX HACK +}; + +#endif diff --git a/src/messages/MDiscover.h b/src/messages/MDiscover.h new file mode 100644 index 00000000..f4418e61 --- /dev/null +++ b/src/messages/MDiscover.h @@ -0,0 +1,97 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MDISCOVER_H +#define CEPH_MDISCOVER_H + +#include "msg/Message.h" +#include "include/filepath.h" + +#include <string> + + +class MDiscover : public MessageInstance<MDiscover> { +public: + friend factory; +private: + + inodeno_t base_ino; // 1 -> root + frag_t base_dir_frag; + + snapid_t snapid; + filepath want; // ... [/]need/this/stuff + + bool want_base_dir = true; + bool want_xlocked = false; + + public: + inodeno_t get_base_ino() const { return base_ino; } + frag_t get_base_dir_frag() const { return base_dir_frag; } + snapid_t get_snapid() const { return snapid; } + + const filepath& get_want() const { return want; } + const std::string& get_dentry(int n) const { return want[n]; } + + bool wants_base_dir() const { return want_base_dir; } + bool wants_xlocked() const { return want_xlocked; } + + void set_base_dir_frag(frag_t f) { base_dir_frag = f; } + +protected: + MDiscover() : MessageInstance(MSG_MDS_DISCOVER) { } + MDiscover(inodeno_t base_ino_, + frag_t base_frag_, + snapid_t s, + filepath& want_path_, + bool want_base_dir_ = true, + bool discover_xlocks_ = false) : + MessageInstance(MSG_MDS_DISCOVER), + base_ino(base_ino_), + base_dir_frag(base_frag_), + snapid(s), + want(want_path_), + want_base_dir(want_base_dir_), + want_xlocked(discover_xlocks_) { } + ~MDiscover() override {} + +public: + std::string_view get_type_name() const override { return "Dis"; } + void print(ostream &out) const override { + out << "discover(" << header.tid << " " << base_ino << "." << base_dir_frag + << " " << want << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(base_ino, p); + decode(base_dir_frag, p); + decode(snapid, p); + decode(want, p); + decode(want_base_dir, p); + decode(want_xlocked, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(base_ino, payload); + encode(base_dir_frag, payload); + encode(snapid, payload); + encode(want, payload); + encode(want_base_dir, payload); + encode(want_xlocked, payload); + } + +}; + +#endif diff --git a/src/messages/MDiscoverReply.h b/src/messages/MDiscoverReply.h new file mode 100644 index 00000000..bd4f3475 --- /dev/null +++ b/src/messages/MDiscoverReply.h @@ -0,0 +1,212 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MDISCOVERREPLY_H +#define CEPH_MDISCOVERREPLY_H + +#include "msg/Message.h" +#include "include/filepath.h" + +#include <string> + + + +/** + * MDiscoverReply - return new replicas (of inodes, dirs, dentries) + * + * we group returned items by (dir, dentry, inode). each + * item in each set shares an index (it's "depth"). + * + * we can start and end with any type. + * no_base_dir = true if the first group has an inode but no dir + * no_base_dentry = true if the first group has an inode but no dentry + * they are false if there is no returned data, ie the first group is empty. + * + * we also return errors: + * error_flag_dn(std::string) - the specified dentry dne + * error_flag_dir - the last item wasn't a dir, so we couldn't continue. + * + * and sometimes, + * dir_auth_hint - where we think the dir auth is + * + * depth() gives us the number of depth units/indices for which we have + * information. this INCLUDES those for which we have errors but no data. + * + * see MDCache::handle_discover, handle_discover_reply. + * + * + * so basically, we get + * + * dir den ino i + * x 0 + * x x x 1 + * or + * x x 0 + * x x x 1 + * or + * x x x 0 + * x x x 1 + * ...and trail off however we want. + * + * + */ + +class MDiscoverReply : public MessageInstance<MDiscoverReply> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + + // info about original request + inodeno_t base_ino; + frag_t base_dir_frag; + bool wanted_base_dir = false; + bool wanted_xlocked = false; + snapid_t wanted_snapid; + + // and the response + bool flag_error_dn = false; + bool flag_error_dir = false; + std::string error_dentry; // dentry that was not found (to trigger waiters on asker) + bool unsolicited = false; + + mds_rank_t dir_auth_hint = 0; + + public: + __u8 starts_with = 0; + bufferlist trace; + + enum { DIR, DENTRY, INODE }; + + // accessors + inodeno_t get_base_ino() const { return base_ino; } + frag_t get_base_dir_frag() const { return base_dir_frag; } + bool get_wanted_base_dir() const { return wanted_base_dir; } + bool get_wanted_xlocked() const { return wanted_xlocked; } + snapid_t get_wanted_snapid() const { return wanted_snapid; } + + bool is_flag_error_dn() const { return flag_error_dn; } + bool is_flag_error_dir() const { return flag_error_dir; } + const std::string& get_error_dentry() const { return error_dentry; } + + int get_starts_with() const { return starts_with; } + + mds_rank_t get_dir_auth_hint() const { return dir_auth_hint; } + + bool is_unsolicited() const { return unsolicited; } + void mark_unsolicited() { unsolicited = true; } + + void set_base_dir_frag(frag_t df) { base_dir_frag = df; } + +protected: + MDiscoverReply() : MessageInstance(MSG_MDS_DISCOVERREPLY, HEAD_VERSION) { } + MDiscoverReply(const MDiscover &dis) : + MessageInstance(MSG_MDS_DISCOVERREPLY, HEAD_VERSION), + base_ino(dis.get_base_ino()), + base_dir_frag(dis.get_base_dir_frag()), + wanted_base_dir(dis.wants_base_dir()), + wanted_xlocked(dis.wants_xlocked()), + wanted_snapid(dis.get_snapid()), + flag_error_dn(false), + flag_error_dir(false), + unsolicited(false), + dir_auth_hint(CDIR_AUTH_UNKNOWN), + starts_with(DIR) + { + header.tid = dis.get_tid(); + } + MDiscoverReply(dirfrag_t df) : + MessageInstance(MSG_MDS_DISCOVERREPLY, HEAD_VERSION), + base_ino(df.ino), + base_dir_frag(df.frag), + wanted_base_dir(false), + wanted_xlocked(false), + wanted_snapid(CEPH_NOSNAP), + flag_error_dn(false), + flag_error_dir(false), + unsolicited(false), + dir_auth_hint(CDIR_AUTH_UNKNOWN), + starts_with(DIR) + { + header.tid = 0; + } + ~MDiscoverReply() override {} + +public: + std::string_view get_type_name() const override { return "discover_reply"; } + void print(ostream& out) const override { + out << "discover_reply(" << header.tid << " " << base_ino << ")"; + } + + // builders + bool is_empty() const { + return trace.length() == 0 && + !flag_error_dn && + !flag_error_dir && + dir_auth_hint == CDIR_AUTH_UNKNOWN; + } + + // void set_flag_forward() { flag_forward = true; } + void set_flag_error_dn(std::string_view dn) { + flag_error_dn = true; + error_dentry = dn; + } + void set_flag_error_dir() { + flag_error_dir = true; + } + void set_dir_auth_hint(int a) { + dir_auth_hint = a; + } + void set_error_dentry(std::string_view dn) { + error_dentry = dn; + } + + + // ... + void decode_payload() override { + auto p = payload.cbegin(); + decode(base_ino, p); + decode(base_dir_frag, p); + decode(wanted_base_dir, p); + decode(wanted_xlocked, p); + decode(wanted_snapid, p); + decode(flag_error_dn, p); + decode(flag_error_dir, p); + decode(error_dentry, p); + decode(dir_auth_hint, p); + decode(unsolicited, p); + + decode(starts_with, p); + decode(trace, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(base_ino, payload); + encode(base_dir_frag, payload); + encode(wanted_base_dir, payload); + encode(wanted_xlocked, payload); + encode(wanted_snapid, payload); + encode(flag_error_dn, payload); + encode(flag_error_dir, payload); + encode(error_dentry, payload); + encode(dir_auth_hint, payload); + encode(unsolicited, payload); + + encode(starts_with, payload); + encode(trace, payload); + } +}; + +#endif diff --git a/src/messages/MExportCaps.h b/src/messages/MExportCaps.h new file mode 100644 index 00000000..93e53b0f --- /dev/null +++ b/src/messages/MExportCaps.h @@ -0,0 +1,63 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MEXPORTCAPS_H +#define CEPH_MEXPORTCAPS_H + +#include "msg/Message.h" + + +class MExportCaps : public MessageInstance<MExportCaps> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; +public: + inodeno_t ino; + bufferlist cap_bl; + map<client_t,entity_inst_t> client_map; + map<client_t,client_metadata_t> client_metadata_map; + +protected: + MExportCaps() : + MessageInstance(MSG_MDS_EXPORTCAPS, HEAD_VERSION, COMPAT_VERSION) {} + ~MExportCaps() override {} + +public: + std::string_view get_type_name() const override { return "export_caps"; } + void print(ostream& o) const override { + o << "export_caps(" << ino << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(cap_bl, payload); + encode(client_map, payload, features); + encode(client_metadata_map, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(ino, p); + decode(cap_bl, p); + decode(client_map, p); + if (header.version >= 2) + decode(client_metadata_map, p); + } + +}; + +#endif diff --git a/src/messages/MExportCapsAck.h b/src/messages/MExportCapsAck.h new file mode 100644 index 00000000..d159161e --- /dev/null +++ b/src/messages/MExportCapsAck.h @@ -0,0 +1,54 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MEXPORTCAPSACK_H +#define CEPH_MEXPORTCAPSACK_H + +#include "msg/Message.h" + + +class MExportCapsAck : public MessageInstance<MExportCapsAck> { +public: + friend factory; + + inodeno_t ino; + bufferlist cap_bl; + +protected: + MExportCapsAck() : + MessageInstance(MSG_MDS_EXPORTCAPSACK) {} + MExportCapsAck(inodeno_t i) : + MessageInstance(MSG_MDS_EXPORTCAPSACK), ino(i) {} + ~MExportCapsAck() override {} + +public: + std::string_view get_type_name() const override { return "export_caps_ack"; } + void print(ostream& o) const override { + o << "export_caps_ack(" << ino << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(cap_bl, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(ino, p); + decode(cap_bl, p); + } +}; + +#endif diff --git a/src/messages/MExportDir.h b/src/messages/MExportDir.h new file mode 100644 index 00000000..8f509e03 --- /dev/null +++ b/src/messages/MExportDir.h @@ -0,0 +1,65 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MEXPORTDIR_H +#define CEPH_MEXPORTDIR_H + +#include "msg/Message.h" + + +class MExportDir : public MessageInstance<MExportDir> { +public: + friend factory; + dirfrag_t dirfrag; + bufferlist export_data; + vector<dirfrag_t> bounds; + bufferlist client_map; + +protected: + MExportDir() : MessageInstance(MSG_MDS_EXPORTDIR) {} + MExportDir(dirfrag_t df, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIR), dirfrag(df) { + set_tid(tid); + } + ~MExportDir() override {} + +public: + std::string_view get_type_name() const override { return "Ex"; } + void print(ostream& o) const override { + o << "export(" << dirfrag << ")"; + } + + void add_export(dirfrag_t df) { + bounds.push_back(df); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(bounds, payload); + encode(export_data, payload); + encode(client_map, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(bounds, p); + decode(export_data, p); + decode(client_map, p); + } + +}; + +#endif diff --git a/src/messages/MExportDirAck.h b/src/messages/MExportDirAck.h new file mode 100644 index 00000000..ff8be816 --- /dev/null +++ b/src/messages/MExportDirAck.h @@ -0,0 +1,57 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRACK_H +#define CEPH_MEXPORTDIRACK_H + +#include "MExportDir.h" +#include "msg/Message.h" + +class MExportDirAck : public MessageInstance<MExportDirAck> { +public: + friend factory; + + dirfrag_t dirfrag; + bufferlist imported_caps; + + dirfrag_t get_dirfrag() const { return dirfrag; } + +protected: + MExportDirAck() : MessageInstance(MSG_MDS_EXPORTDIRACK) {} + MExportDirAck(dirfrag_t df, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIRACK), dirfrag(df) { + set_tid(tid); + } + ~MExportDirAck() override {} + +public: + std::string_view get_type_name() const override { return "ExAck"; } + void print(ostream& o) const override { + o << "export_ack(" << dirfrag << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(imported_caps, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(imported_caps, payload); + } + +}; + +#endif diff --git a/src/messages/MExportDirCancel.h b/src/messages/MExportDirCancel.h new file mode 100644 index 00000000..56f2c4d1 --- /dev/null +++ b/src/messages/MExportDirCancel.h @@ -0,0 +1,54 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRCANCEL_H +#define CEPH_MEXPORTDIRCANCEL_H + +#include "msg/Message.h" +#include "include/types.h" + +class MExportDirCancel : public MessageInstance<MExportDirCancel> { +public: + friend factory; +private: + dirfrag_t dirfrag; + + public: + dirfrag_t get_dirfrag() const { return dirfrag; } + +protected: + MExportDirCancel() : MessageInstance(MSG_MDS_EXPORTDIRCANCEL) {} + MExportDirCancel(dirfrag_t df, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIRCANCEL), dirfrag(df) { + set_tid(tid); + } + ~MExportDirCancel() override {} + +public: + std::string_view get_type_name() const override { return "ExCancel"; } + void print(ostream& o) const override { + o << "export_cancel(" << dirfrag << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(dirfrag, p); + } +}; + +#endif diff --git a/src/messages/MExportDirDiscover.h b/src/messages/MExportDirDiscover.h new file mode 100644 index 00000000..74f298bc --- /dev/null +++ b/src/messages/MExportDirDiscover.h @@ -0,0 +1,69 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRDISCOVER_H +#define CEPH_MEXPORTDIRDISCOVER_H + +#include "msg/Message.h" +#include "include/types.h" + +class MExportDirDiscover : public MessageInstance<MExportDirDiscover> { +public: + friend factory; +private: + mds_rank_t from = -1; + dirfrag_t dirfrag; + filepath path; + + public: + mds_rank_t get_source_mds() const { return from; } + inodeno_t get_ino() const { return dirfrag.ino; } + dirfrag_t get_dirfrag() const { return dirfrag; } + const filepath& get_path() const { return path; } + + bool started; + +protected: + MExportDirDiscover() : + MessageInstance(MSG_MDS_EXPORTDIRDISCOVER), + started(false) { } + MExportDirDiscover(dirfrag_t df, filepath& p, mds_rank_t f, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIRDISCOVER), + from(f), dirfrag(df), path(p), started(false) { + set_tid(tid); + } + ~MExportDirDiscover() override {} + +public: + std::string_view get_type_name() const override { return "ExDis"; } + void print(ostream& o) const override { + o << "export_discover(" << dirfrag << " " << path << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(from, p); + decode(dirfrag, p); + decode(path, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(from, payload); + encode(dirfrag, payload); + encode(path, payload); + } +}; + +#endif diff --git a/src/messages/MExportDirDiscoverAck.h b/src/messages/MExportDirDiscoverAck.h new file mode 100644 index 00000000..ba8fda56 --- /dev/null +++ b/src/messages/MExportDirDiscoverAck.h @@ -0,0 +1,64 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRDISCOVERACK_H +#define CEPH_MEXPORTDIRDISCOVERACK_H + +#include "msg/Message.h" +#include "include/types.h" + +class MExportDirDiscoverAck : public MessageInstance<MExportDirDiscoverAck> { +public: + friend factory; +private: + dirfrag_t dirfrag; + bool success; + + public: + inodeno_t get_ino() const { return dirfrag.ino; } + dirfrag_t get_dirfrag() const { return dirfrag; } + bool is_success() const { return success; } + +protected: + MExportDirDiscoverAck() : MessageInstance(MSG_MDS_EXPORTDIRDISCOVERACK) {} + MExportDirDiscoverAck(dirfrag_t df, uint64_t tid, bool s=true) : + MessageInstance(MSG_MDS_EXPORTDIRDISCOVERACK), + dirfrag(df), success(s) { + set_tid(tid); + } + ~MExportDirDiscoverAck() override {} + +public: + std::string_view get_type_name() const override { return "ExDisA"; } + void print(ostream& o) const override { + o << "export_discover_ack(" << dirfrag; + if (success) + o << " success)"; + else + o << " failure)"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(success, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(success, payload); + } +}; + +#endif diff --git a/src/messages/MExportDirFinish.h b/src/messages/MExportDirFinish.h new file mode 100644 index 00000000..6cc35d09 --- /dev/null +++ b/src/messages/MExportDirFinish.h @@ -0,0 +1,58 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRFINISH_H +#define CEPH_MEXPORTDIRFINISH_H + +#include "msg/Message.h" + +class MExportDirFinish : public MessageInstance<MExportDirFinish> { +public: + friend factory; +private: + dirfrag_t dirfrag; + bool last; + + public: + dirfrag_t get_dirfrag() const { return dirfrag; } + bool is_last() const { return last; } + +protected: + MExportDirFinish() : last(false) {} + MExportDirFinish(dirfrag_t df, bool l, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIRFINISH), dirfrag(df), last(l) { + set_tid(tid); + } + ~MExportDirFinish() override {} + +public: + std::string_view get_type_name() const override { return "ExFin"; } + void print(ostream& o) const override { + o << "export_finish(" << dirfrag << (last ? " last" : "") << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(last, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(last, p); + } + +}; + +#endif diff --git a/src/messages/MExportDirNotify.h b/src/messages/MExportDirNotify.h new file mode 100644 index 00000000..fbb7a30b --- /dev/null +++ b/src/messages/MExportDirNotify.h @@ -0,0 +1,84 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRNOTIFY_H +#define CEPH_MEXPORTDIRNOTIFY_H + +#include "msg/Message.h" + +class MExportDirNotify : public MessageInstance<MExportDirNotify> { +public: + friend factory; +private: + dirfrag_t base; + bool ack; + pair<__s32,__s32> old_auth, new_auth; + list<dirfrag_t> bounds; // bounds; these dirs are _not_ included (tho the dirfragdes are) + + public: + dirfrag_t get_dirfrag() const { return base; } + pair<__s32,__s32> get_old_auth() const { return old_auth; } + pair<__s32,__s32> get_new_auth() const { return new_auth; } + bool wants_ack() const { return ack; } + const list<dirfrag_t>& get_bounds() const { return bounds; } + list<dirfrag_t>& get_bounds() { return bounds; } + +protected: + MExportDirNotify() {} + MExportDirNotify(dirfrag_t i, uint64_t tid, bool a, pair<__s32,__s32> oa, pair<__s32,__s32> na) : + MessageInstance(MSG_MDS_EXPORTDIRNOTIFY), + base(i), ack(a), old_auth(oa), new_auth(na) { + set_tid(tid); + } + ~MExportDirNotify() override {} + +public: + std::string_view get_type_name() const override { return "ExNot"; } + void print(ostream& o) const override { + o << "export_notify(" << base; + o << " " << old_auth << " -> " << new_auth; + if (ack) + o << " ack)"; + else + o << " no ack)"; + } + + void copy_bounds(list<dirfrag_t>& ex) { + this->bounds = ex; + } + void copy_bounds(set<dirfrag_t>& ex) { + for (set<dirfrag_t>::iterator i = ex.begin(); + i != ex.end(); ++i) + bounds.push_back(*i); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(base, payload); + encode(ack, payload); + encode(old_auth, payload); + encode(new_auth, payload); + encode(bounds, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(base, p); + decode(ack, p); + decode(old_auth, p); + decode(new_auth, p); + decode(bounds, p); + } +}; + +#endif diff --git a/src/messages/MExportDirNotifyAck.h b/src/messages/MExportDirNotifyAck.h new file mode 100644 index 00000000..05f77167 --- /dev/null +++ b/src/messages/MExportDirNotifyAck.h @@ -0,0 +1,59 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRNOTIFYACK_H +#define CEPH_MEXPORTDIRNOTIFYACK_H + +#include "msg/Message.h" + +class MExportDirNotifyAck : public MessageInstance<MExportDirNotifyAck> { +public: + friend factory; +private: + dirfrag_t dirfrag; + pair<__s32,__s32> new_auth; + + public: + dirfrag_t get_dirfrag() const { return dirfrag; } + pair<__s32,__s32> get_new_auth() const { return new_auth; } + +protected: + MExportDirNotifyAck() {} + MExportDirNotifyAck(dirfrag_t df, uint64_t tid, pair<__s32,__s32> na) : + MessageInstance(MSG_MDS_EXPORTDIRNOTIFYACK), dirfrag(df), new_auth(na) { + set_tid(tid); + } + ~MExportDirNotifyAck() override {} + +public: + std::string_view get_type_name() const override { return "ExNotA"; } + void print(ostream& o) const override { + o << "export_notify_ack(" << dirfrag << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(new_auth, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(new_auth, p); + } + +}; + +#endif diff --git a/src/messages/MExportDirPrep.h b/src/messages/MExportDirPrep.h new file mode 100644 index 00000000..e10d4f24 --- /dev/null +++ b/src/messages/MExportDirPrep.h @@ -0,0 +1,90 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MEXPORTDIRPREP_H +#define CEPH_MEXPORTDIRPREP_H + +#include "msg/Message.h" +#include "include/types.h" + +class MExportDirPrep : public MessageInstance<MExportDirPrep> { +public: + friend factory; +private: + dirfrag_t dirfrag; + public: + bufferlist basedir; + list<dirfrag_t> bounds; + list<bufferlist> traces; +private: + set<mds_rank_t> bystanders; + bool b_did_assim; + +public: + dirfrag_t get_dirfrag() const { return dirfrag; } + const list<dirfrag_t>& get_bounds() const { return bounds; } + const set<mds_rank_t> &get_bystanders() const { return bystanders; } + + bool did_assim() const { return b_did_assim; } + void mark_assim() { b_did_assim = true; } + +protected: + MExportDirPrep() { + b_did_assim = false; + } + MExportDirPrep(dirfrag_t df, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIRPREP), + dirfrag(df), b_did_assim(false) { + set_tid(tid); + } + ~MExportDirPrep() override {} + +public: + std::string_view get_type_name() const override { return "ExP"; } + void print(ostream& o) const override { + o << "export_prep(" << dirfrag << ")"; + } + + void add_bound(dirfrag_t df) { + bounds.push_back( df ); + } + void add_trace(bufferlist& bl) { + traces.push_back(bl); + } + void add_bystander(mds_rank_t who) { + bystanders.insert(who); + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(basedir, p); + decode(bounds, p); + decode(traces, p); + decode(bystanders, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(basedir, payload); + encode(bounds, payload); + encode(traces, payload); + encode(bystanders, payload); + } +}; + +#endif diff --git a/src/messages/MExportDirPrepAck.h b/src/messages/MExportDirPrepAck.h new file mode 100644 index 00000000..11e59a8d --- /dev/null +++ b/src/messages/MExportDirPrepAck.h @@ -0,0 +1,59 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MEXPORTDIRPREPACK_H +#define CEPH_MEXPORTDIRPREPACK_H + +#include "msg/Message.h" +#include "include/types.h" + +class MExportDirPrepAck : public MessageInstance<MExportDirPrepAck> { +public: + friend factory; +private: + dirfrag_t dirfrag; + bool success = false; + + public: + dirfrag_t get_dirfrag() const { return dirfrag; } + +protected: + MExportDirPrepAck() {} + MExportDirPrepAck(dirfrag_t df, bool s, uint64_t tid) : + MessageInstance(MSG_MDS_EXPORTDIRPREPACK), dirfrag(df), success(s) { + set_tid(tid); + } + ~MExportDirPrepAck() override {} + +public: + bool is_success() const { return success; } + std::string_view get_type_name() const override { return "ExPAck"; } + void print(ostream& o) const override { + o << "export_prep_ack(" << dirfrag << (success ? " success)" : " fail)"); + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(dirfrag, p); + decode(success, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(dirfrag, payload); + encode(success, payload); + } +}; + +#endif diff --git a/src/messages/MFSMap.h b/src/messages/MFSMap.h new file mode 100644 index 00000000..99f241d5 --- /dev/null +++ b/src/messages/MFSMap.h @@ -0,0 +1,64 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MFSMAP_H +#define CEPH_MFSMAP_H + +#include "msg/Message.h" +#include "mds/FSMap.h" +#include "include/ceph_features.h" + +class MFSMap : public MessageInstance<MFSMap> { +public: + friend factory; + + epoch_t epoch; + bufferlist encoded; + + version_t get_epoch() const { return epoch; } + const FSMap& get_fsmap() const {return fsmap;} + + MFSMap() : + MessageInstance(CEPH_MSG_FS_MAP), epoch(0) {} + MFSMap(const uuid_d &f, const FSMap &fsmap_) : + MessageInstance(CEPH_MSG_FS_MAP), epoch(fsmap_.get_epoch()) + { + fsmap = fsmap_; + } +private: + FSMap fsmap; + + ~MFSMap() override {} + +public: + std::string_view get_type_name() const override { return "fsmap"; } + void print(ostream& out) const override { + out << "fsmap(e " << epoch << ")"; + } + + // marshalling + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(fsmap, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(fsmap, payload, features); + } +}; + +#endif diff --git a/src/messages/MFSMapUser.h b/src/messages/MFSMapUser.h new file mode 100644 index 00000000..215b1211 --- /dev/null +++ b/src/messages/MFSMapUser.h @@ -0,0 +1,62 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + + +#ifndef CEPH_MFSMAPCOMPACT_H +#define CEPH_MFSMAPCOMPACT_H + +#include "msg/Message.h" +#include "mds/FSMapUser.h" +#include "include/ceph_features.h" + +class MFSMapUser : public MessageInstance<MFSMapUser> { +public: + friend factory; + + epoch_t epoch; + + version_t get_epoch() const { return epoch; } + const FSMapUser& get_fsmap() const { return fsmap; } + + MFSMapUser() : + MessageInstance(CEPH_MSG_FS_MAP_USER), epoch(0) {} + MFSMapUser(const uuid_d &f, const FSMapUser &fsmap_) : + MessageInstance(CEPH_MSG_FS_MAP_USER), epoch(fsmap_.epoch) + { + fsmap = fsmap_; + } +private: + FSMapUser fsmap; + + ~MFSMapUser() override {} + +public: + std::string_view get_type_name() const override { return "fsmap.user"; } + void print(ostream& out) const override { + out << "fsmap.user(e " << epoch << ")"; + } + + // marshalling + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(fsmap, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(fsmap, payload, features); + } +}; + +#endif diff --git a/src/messages/MForward.h b/src/messages/MForward.h new file mode 100644 index 00000000..7f552ca1 --- /dev/null +++ b/src/messages/MForward.h @@ -0,0 +1,156 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + * Client requests often need to get forwarded from some monitor + * to the leader. This class encapsulates the original message + * along with the client's caps so the leader can do proper permissions + * checking. + */ + +#ifndef CEPH_MFORWARD_H +#define CEPH_MFORWARD_H + +#include "msg/Message.h" +#include "mon/MonCap.h" +#include "include/encoding.h" +#include "include/stringify.h" + +class MForward : public MessageInstance<MForward> { +public: + friend factory; + + uint64_t tid; + uint8_t client_type; + entity_addrvec_t client_addrs; + entity_addr_t client_socket_addr; + MonCap client_caps; + uint64_t con_features; + EntityName entity_name; + PaxosServiceMessage *msg; // incoming or outgoing message + + string msg_desc; // for operator<< only + + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 4; + + MForward() : MessageInstance(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION), + tid(0), con_features(0), msg(NULL) {} + MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat, + const MonCap& caps) : + MessageInstance(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION), + tid(t), client_caps(caps), msg(NULL) { + client_type = m->get_source().type(); + client_addrs = m->get_source_addrs(); + if (auto con = m->get_connection()) { + client_socket_addr = con->get_peer_socket_addr(); + } + con_features = feat; + msg = (PaxosServiceMessage*)m->get(); + } +private: + ~MForward() override { + if (msg) { + // message was unclaimed + msg->put(); + msg = NULL; + } + } + +public: + void encode_payload(uint64_t features) override { + using ceph::encode; + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + header.version = 3; + header.compat_version = 3; + encode(tid, payload); + entity_inst_t client; + client.name = entity_name_t(client_type, -1); + client.addr = client_addrs.legacy_addr(); + encode(client, payload, features); + encode(client_caps, payload, features); + // Encode client message with intersection of target and source + // features. This could matter if the semantics of the encoded + // message are changed when reencoding with more features than the + // client had originally. That should never happen, but we may as + // well be defensive here. + if (con_features != features) { + msg->clear_payload(); + } + encode_message(msg, features & con_features, payload); + encode(con_features, payload); + encode(entity_name, payload); + return; + } + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(tid, payload); + encode(client_type, payload, features); + encode(client_addrs, payload, features); + encode(client_socket_addr, payload, features); + encode(client_caps, payload, features); + // Encode client message with intersection of target and source + // features. This could matter if the semantics of the encoded + // message are changed when reencoding with more features than the + // client had originally. That should never happen, but we may as + // well be defensive here. + if (con_features != features) { + msg->clear_payload(); + } + encode_message(msg, features & con_features, payload); + encode(con_features, payload); + encode(entity_name, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(tid, p); + if (header.version < 4) { + entity_inst_t client; + decode(client, p); + client_type = client.name.type(); + client_addrs = entity_addrvec_t(client.addr); + client_socket_addr = client.addr; + } else { + decode(client_type, p); + decode(client_addrs, p); + decode(client_socket_addr, p); + } + decode(client_caps, p); + msg = (PaxosServiceMessage *)decode_message(NULL, 0, p); + decode(con_features, p); + decode(entity_name, p); + } + + PaxosServiceMessage *claim_message() { + // let whoever is claiming the message deal with putting it. + ceph_assert(msg); + msg_desc = stringify(*msg); + PaxosServiceMessage *m = msg; + msg = NULL; + return m; + } + + std::string_view get_type_name() const override { return "forward"; } + void print(ostream& o) const override { + o << "forward("; + if (msg) { + o << *msg; + } else { + o << msg_desc; + } + o << " caps " << client_caps + << " tid " << tid + << " con_features " << con_features << ")"; + } +}; + +#endif diff --git a/src/messages/MGatherCaps.h b/src/messages/MGatherCaps.h new file mode 100644 index 00000000..fe8b4187 --- /dev/null +++ b/src/messages/MGatherCaps.h @@ -0,0 +1,37 @@ +#ifndef CEPH_MGATHERCAPS_H +#define CEPH_MGATHERCAPS_H + +#include "msg/Message.h" + + +class MGatherCaps : public MessageInstance<MGatherCaps> { +public: + friend factory; + + + inodeno_t ino; + +protected: + MGatherCaps() : + MessageInstance(MSG_MDS_GATHERCAPS) {} + ~MGatherCaps() override {} + +public: + std::string_view get_type_name() const override { return "gather_caps"; } + void print(ostream& o) const override { + o << "gather_caps(" << ino << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(ino, p); + } + +}; + +#endif diff --git a/src/messages/MGenericMessage.h b/src/messages/MGenericMessage.h new file mode 100644 index 00000000..49e906d6 --- /dev/null +++ b/src/messages/MGenericMessage.h @@ -0,0 +1,42 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MGENERICMESSAGE_H +#define CEPH_MGENERICMESSAGE_H + +#include "msg/Message.h" + +class MGenericMessage : public MessageInstance<MGenericMessage> { +public: + friend factory; +private: + char tname[20]; + //long pcid; + + public: + MGenericMessage(int t=0) : MessageInstance(t) { + snprintf(tname, sizeof(tname), "generic%d", get_type()); + } + + //void set_pcid(long pcid) { this->pcid = pcid; } + //long get_pcid() { return pcid; } + + std::string_view get_type_name() const override { return tname; } + + void decode_payload() override { } + void encode_payload(uint64_t features) override { } +}; + +#endif diff --git a/src/messages/MGetConfig.h b/src/messages/MGetConfig.h new file mode 100644 index 00000000..0e548576 --- /dev/null +++ b/src/messages/MGetConfig.h @@ -0,0 +1,50 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" + +class MGetConfig : public MessageInstance<MGetConfig> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + EntityName name; ///< e.g., mon.a, client.foo + string host; ///< our hostname + string device_class; + + MGetConfig() : MessageInstance(MSG_GET_CONFIG, HEAD_VERSION, COMPAT_VERSION) { } + MGetConfig(const EntityName& n, const string& h) + : MessageInstance(MSG_GET_CONFIG, HEAD_VERSION, COMPAT_VERSION), + name(n), + host(h) {} + + std::string_view get_type_name() const override { + return "get_config"; + } + void print(ostream& o) const override { + o << "get_config(" << name << "@" << host; + if (device_class.size()) { + o << " device_class " << device_class; + } + o << ")"; + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(name, p); + decode(host, p); + decode(device_class, p); + } + + void encode_payload(uint64_t) override { + using ceph::encode; + encode(name, payload); + encode(host, payload); + encode(device_class, payload); + } +}; diff --git a/src/messages/MGetPoolStats.h b/src/messages/MGetPoolStats.h new file mode 100644 index 00000000..54ee08f6 --- /dev/null +++ b/src/messages/MGetPoolStats.h @@ -0,0 +1,59 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MGETPOOLSTATS_H +#define CEPH_MGETPOOLSTATS_H + +#include "messages/PaxosServiceMessage.h" + +class MGetPoolStats : public MessageInstance<MGetPoolStats, PaxosServiceMessage> { +public: + friend factory; + + uuid_d fsid; + list<string> pools; + + MGetPoolStats() : MessageInstance(MSG_GETPOOLSTATS, 0) {} + MGetPoolStats(const uuid_d& f, ceph_tid_t t, list<string>& ls, version_t l) : + MessageInstance(MSG_GETPOOLSTATS, l), + fsid(f), pools(ls) { + set_tid(t); + } + +private: + ~MGetPoolStats() override {} + +public: + std::string_view get_type_name() const override { return "getpoolstats"; } + void print(ostream& out) const override { + out << "getpoolstats(" << get_tid() << " " << pools << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(pools, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(pools, p); + } +}; + +#endif diff --git a/src/messages/MGetPoolStatsReply.h b/src/messages/MGetPoolStatsReply.h new file mode 100644 index 00000000..8af58584 --- /dev/null +++ b/src/messages/MGetPoolStatsReply.h @@ -0,0 +1,72 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MGETPOOLSTATSREPLY_H +#define CEPH_MGETPOOLSTATSREPLY_H + +class MGetPoolStatsReply : public MessageInstance<MGetPoolStatsReply, PaxosServiceMessage> { + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + friend factory; + + uuid_d fsid; + map<string,pool_stat_t> pool_stats; + bool per_pool = false; + + MGetPoolStatsReply() : MessageInstance(MSG_GETPOOLSTATSREPLY, 0, + HEAD_VERSION, COMPAT_VERSION) {} + MGetPoolStatsReply(uuid_d& f, ceph_tid_t t, version_t v) : + MessageInstance(MSG_GETPOOLSTATSREPLY, v, + HEAD_VERSION, COMPAT_VERSION), + fsid(f) { + set_tid(t); + } + +private: + ~MGetPoolStatsReply() override {} + +public: + std::string_view get_type_name() const override { return "getpoolstats"; } + void print(ostream& out) const override { + out << "getpoolstatsreply(" << get_tid(); + if (per_pool) + out << " per_pool"; + out << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(pool_stats, payload, features); + encode(per_pool, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(pool_stats, p); + if (header.version >= 2) { + decode(per_pool, p); + } else { + per_pool = false; + } + } +}; + +#endif diff --git a/src/messages/MHeartbeat.h b/src/messages/MHeartbeat.h new file mode 100644 index 00000000..50259619 --- /dev/null +++ b/src/messages/MHeartbeat.h @@ -0,0 +1,65 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MHEARTBEAT_H +#define CEPH_MHEARTBEAT_H + +#include "include/types.h" +#include "msg/Message.h" +#include "common/DecayCounter.h" + +class MHeartbeat : public MessageInstance<MHeartbeat> { +public: + friend factory; +private: + mds_load_t load; + __s32 beat = 0; + map<mds_rank_t, float> import_map; + + public: + const mds_load_t& get_load() const { return load; } + int get_beat() const { return beat; } + + const map<mds_rank_t, float>& get_import_map() const { return import_map; } + map<mds_rank_t, float>& get_import_map() { return import_map; } + +protected: + MHeartbeat() : MessageInstance(MSG_MDS_HEARTBEAT), load(DecayRate()) {} + MHeartbeat(mds_load_t& load, int beat) + : MessageInstance(MSG_MDS_HEARTBEAT), + load(load) { + this->beat = beat; + } + ~MHeartbeat() override {} + +public: + std::string_view get_type_name() const override { return "HB"; } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(load, payload); + encode(beat, payload); + encode(import_map, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(load, p); + decode(beat, p); + decode(import_map, p); + } + +}; + +#endif diff --git a/src/messages/MInodeFileCaps.h b/src/messages/MInodeFileCaps.h new file mode 100644 index 00000000..0d32dcd7 --- /dev/null +++ b/src/messages/MInodeFileCaps.h @@ -0,0 +1,61 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MINODEFILECAPS_H +#define CEPH_MINODEFILECAPS_H + +#include "msg/Message.h" + +class MInodeFileCaps : public MessageInstance<MInodeFileCaps> { +public: + friend factory; +private: + inodeno_t ino; + __u32 caps = 0; + + public: + + inodeno_t get_ino() const { return ino; } + int get_caps() const { return caps; } + +protected: + MInodeFileCaps() : MessageInstance(MSG_MDS_INODEFILECAPS) {} + MInodeFileCaps(inodeno_t ino, int caps) : + MessageInstance(MSG_MDS_INODEFILECAPS) { + this->ino = ino; + this->caps = caps; + } + ~MInodeFileCaps() override {} + +public: + std::string_view get_type_name() const override { return "inode_file_caps";} + void print(ostream& out) const override { + out << "inode_file_caps(" << ino << " " << ccap_string(caps) << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(caps, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(ino, p); + decode(caps, p); + } +}; + +#endif diff --git a/src/messages/MLock.h b/src/messages/MLock.h new file mode 100644 index 00000000..decaabae --- /dev/null +++ b/src/messages/MLock.h @@ -0,0 +1,103 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MLOCK_H +#define CEPH_MLOCK_H + +#include "msg/Message.h" +#include "mds/locks.h" +#include "mds/SimpleLock.h" + +class MLock : public MessageInstance<MLock> { +public: + friend factory; +private: + int32_t action = 0; // action type + mds_rank_t asker = 0; // who is initiating this request + metareqid_t reqid; // for remote lock requests + + __u16 lock_type = 0; // lock object type + MDSCacheObjectInfo object_info; + + bufferlist lockdata; // and possibly some data + +public: + bufferlist& get_data() { return lockdata; } + const bufferlist& get_data() const { return lockdata; } + int get_asker() const { return asker; } + int get_action() const { return action; } + metareqid_t get_reqid() const { return reqid; } + + int get_lock_type() const { return lock_type; } + const MDSCacheObjectInfo &get_object_info() const { return object_info; } + MDSCacheObjectInfo &get_object_info() { return object_info; } + +protected: + MLock() : MessageInstance(MSG_MDS_LOCK) {} + MLock(int ac, mds_rank_t as) : + MessageInstance(MSG_MDS_LOCK), + action(ac), asker(as), + lock_type(0) { } + MLock(SimpleLock *lock, int ac, mds_rank_t as) : + MessageInstance(MSG_MDS_LOCK), + action(ac), asker(as), + lock_type(lock->get_type()) { + lock->get_parent()->set_object_info(object_info); + } + MLock(SimpleLock *lock, int ac, mds_rank_t as, bufferlist& bl) : + MessageInstance(MSG_MDS_LOCK), + action(ac), asker(as), lock_type(lock->get_type()) { + lock->get_parent()->set_object_info(object_info); + lockdata.claim(bl); + } + ~MLock() override {} + +public: + std::string_view get_type_name() const override { return "ILock"; } + void print(ostream& out) const override { + out << "lock(a=" << SimpleLock::get_lock_action_name(action) + << " " << SimpleLock::get_lock_type_name(lock_type) + << " " << object_info + << ")"; + } + + void set_reqid(metareqid_t ri) { reqid = ri; } + void set_data(const bufferlist& lockdata) { + this->lockdata = lockdata; + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(asker, p); + decode(action, p); + decode(reqid, p); + decode(lock_type, p); + decode(object_info, p); + decode(lockdata, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(asker, payload); + encode(action, payload); + encode(reqid, payload); + encode(lock_type, payload); + encode(object_info, payload); + encode(lockdata, payload); + } + +}; + +#endif diff --git a/src/messages/MLog.h b/src/messages/MLog.h new file mode 100644 index 00000000..d2c6e9e9 --- /dev/null +++ b/src/messages/MLog.h @@ -0,0 +1,61 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MLOG_H +#define CEPH_MLOG_H + +#include "common/LogEntry.h" +#include "messages/PaxosServiceMessage.h" + +#include <deque> + +class MLog : public MessageInstance<MLog, PaxosServiceMessage> { +public: + friend factory; + + uuid_d fsid; + std::deque<LogEntry> entries; + + MLog() : MessageInstance(MSG_LOG, 0) {} + MLog(const uuid_d& f, const std::deque<LogEntry>& e) + : MessageInstance(MSG_LOG, 0), fsid(f), entries(e) { } + MLog(const uuid_d& f) : MessageInstance(MSG_LOG, 0), fsid(f) { } +private: + ~MLog() override {} + +public: + std::string_view get_type_name() const override { return "log"; } + void print(ostream& out) const override { + out << "log("; + if (entries.size()) + out << entries.size() << " entries from seq " << entries.front().seq + << " at " << entries.front().stamp; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(entries, payload, features); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(entries, p); + } +}; + +#endif diff --git a/src/messages/MLogAck.h b/src/messages/MLogAck.h new file mode 100644 index 00000000..012c758d --- /dev/null +++ b/src/messages/MLogAck.h @@ -0,0 +1,53 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MLOGACK_H +#define CEPH_MLOGACK_H + +class MLogAck : public MessageInstance<MLogAck> { +public: + friend factory; + + uuid_d fsid; + version_t last = 0; + std::string channel; + + MLogAck() : MessageInstance(MSG_LOGACK) {} + MLogAck(uuid_d& f, version_t l) : MessageInstance(MSG_LOGACK), fsid(f), last(l) {} +private: + ~MLogAck() override {} + +public: + std::string_view get_type_name() const override { return "log_ack"; } + void print(ostream& out) const override { + out << "log(last " << last << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(fsid, payload); + encode(last, payload); + encode(channel, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(fsid, p); + decode(last, p); + if (!p.end()) + decode(channel, p); + } +}; + +#endif diff --git a/src/messages/MMDSBeacon.h b/src/messages/MMDSBeacon.h new file mode 100644 index 00000000..10b5ae46 --- /dev/null +++ b/src/messages/MMDSBeacon.h @@ -0,0 +1,307 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSBEACON_H +#define CEPH_MMDSBEACON_H + +#include <string_view> + +#include "msg/Message.h" +#include "messages/PaxosServiceMessage.h" + +#include "include/types.h" + +#include "mds/MDSMap.h" + + + +/** + * Unique ID for each type of metric we can send to the mon, so that if the mon + * knows about the IDs then it can implement special behaviour for certain + * messages. + */ +enum mds_metric_t { + MDS_HEALTH_NULL = 0, + MDS_HEALTH_TRIM, + MDS_HEALTH_CLIENT_RECALL, + MDS_HEALTH_CLIENT_LATE_RELEASE, + MDS_HEALTH_CLIENT_RECALL_MANY, + MDS_HEALTH_CLIENT_LATE_RELEASE_MANY, + MDS_HEALTH_CLIENT_OLDEST_TID, + MDS_HEALTH_CLIENT_OLDEST_TID_MANY, + MDS_HEALTH_DAMAGE, + MDS_HEALTH_READ_ONLY, + MDS_HEALTH_SLOW_REQUEST, + MDS_HEALTH_CACHE_OVERSIZED, + MDS_HEALTH_SLOW_METADATA_IO, +}; + +inline const char *mds_metric_name(mds_metric_t m) +{ + switch (m) { + case MDS_HEALTH_TRIM: return "MDS_TRIM"; + case MDS_HEALTH_CLIENT_RECALL: return "MDS_CLIENT_RECALL"; + case MDS_HEALTH_CLIENT_LATE_RELEASE: return "MDS_CLIENT_LATE_RELEASE"; + case MDS_HEALTH_CLIENT_RECALL_MANY: return "MDS_CLIENT_RECALL_MANY"; + case MDS_HEALTH_CLIENT_LATE_RELEASE_MANY: return "MDS_CLIENT_LATE_RELEASE_MANY"; + case MDS_HEALTH_CLIENT_OLDEST_TID: return "MDS_CLIENT_OLDEST_TID"; + case MDS_HEALTH_CLIENT_OLDEST_TID_MANY: return "MDS_CLIENT_OLDEST_TID_MANY"; + case MDS_HEALTH_DAMAGE: return "MDS_DAMAGE"; + case MDS_HEALTH_READ_ONLY: return "MDS_READ_ONLY"; + case MDS_HEALTH_SLOW_REQUEST: return "MDS_SLOW_REQUEST"; + case MDS_HEALTH_CACHE_OVERSIZED: return "MDS_CACHE_OVERSIZED"; + case MDS_HEALTH_SLOW_METADATA_IO: return "MDS_SLOW_METADATA_IO"; + default: + return "???"; + } +} + +inline const char *mds_metric_summary(mds_metric_t m) +{ + switch (m) { + case MDS_HEALTH_TRIM: + return "%num% MDSs behind on trimming"; + case MDS_HEALTH_CLIENT_RECALL: + return "%num% clients failing to respond to cache pressure"; + case MDS_HEALTH_CLIENT_LATE_RELEASE: + return "%num% clients failing to respond to capability release"; + case MDS_HEALTH_CLIENT_RECALL_MANY: + return "%num% MDSs have many clients failing to respond to cache pressure"; + case MDS_HEALTH_CLIENT_LATE_RELEASE_MANY: + return "%num% MDSs have many clients failing to respond to capability " + "release"; + case MDS_HEALTH_CLIENT_OLDEST_TID: + return "%num% clients failing to advance oldest client/flush tid"; + case MDS_HEALTH_CLIENT_OLDEST_TID_MANY: + return "%num% MDSs have clients failing to advance oldest client/flush tid"; + case MDS_HEALTH_DAMAGE: + return "%num% MDSs report damaged metadata"; + case MDS_HEALTH_READ_ONLY: + return "%num% MDSs are read only"; + case MDS_HEALTH_SLOW_REQUEST: + return "%num% MDSs report slow requests"; + case MDS_HEALTH_CACHE_OVERSIZED: + return "%num% MDSs report oversized cache"; + case MDS_HEALTH_SLOW_METADATA_IO: + return "%num% MDSs report slow metadata IOs"; + default: + return "???"; + } +} + +/** + * This structure is designed to allow some flexibility in how we emit health + * complaints, such that: + * - The mon doesn't have to have foreknowledge of all possible metrics: we can + * implement new messages in the MDS and have the mon pass them through to the user + * (enables us to do complex checks inside the MDS, and allows mon to be older version + * than MDS) + * - The mon has enough information to perform reductions on some types of metric, for + * example complaints about the same client from multiple MDSs where we might want + * to reduce three "client X is stale on MDS y" metrics into one "client X is stale + * on 3 MDSs" message. + */ +struct MDSHealthMetric +{ + mds_metric_t type; + health_status_t sev; + std::string message; + std::map<std::string, std::string> metadata; + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ceph_assert(type != MDS_HEALTH_NULL); + encode((uint16_t)type, bl); + encode((uint8_t)sev, bl); + encode(message, bl); + encode(metadata, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::const_iterator& bl) { + DECODE_START(1, bl); + uint16_t raw_type; + decode(raw_type, bl); + type = (mds_metric_t)raw_type; + ceph_assert(type != MDS_HEALTH_NULL); + uint8_t raw_sev; + decode(raw_sev, bl); + sev = (health_status_t)raw_sev; + decode(message, bl); + decode(metadata, bl); + DECODE_FINISH(bl); + } + + bool operator==(MDSHealthMetric const &other) const + { + return (type == other.type && sev == other.sev && message == other.message); + } + + MDSHealthMetric() : type(MDS_HEALTH_NULL), sev(HEALTH_OK) {} + MDSHealthMetric(mds_metric_t type_, health_status_t sev_, std::string_view message_) + : type(type_), sev(sev_), message(message_) {} +}; +WRITE_CLASS_ENCODER(MDSHealthMetric) + + +/** + * Health metrics send by the MDS to the mon, so that the mon can generate + * user friendly warnings about undesirable states. + */ +struct MDSHealth +{ + std::list<MDSHealthMetric> metrics; + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + encode(metrics, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::const_iterator& bl) { + DECODE_START(1, bl); + decode(metrics, bl); + DECODE_FINISH(bl); + } + + bool operator==(MDSHealth const &other) const + { + return metrics == other.metrics; + } +}; +WRITE_CLASS_ENCODER(MDSHealth) + + +class MMDSBeacon : public MessageInstance<MMDSBeacon, PaxosServiceMessage> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 7; + static constexpr int COMPAT_VERSION = 6; + + uuid_d fsid; + mds_gid_t global_id = MDS_GID_NONE; + string name; + + MDSMap::DaemonState state = MDSMap::STATE_NULL; + version_t seq = 0; + + CompatSet compat; + + MDSHealth health; + + map<string, string> sys_info; + + uint64_t mds_features = 0; + +protected: + MMDSBeacon() : MessageInstance(MSG_MDS_BEACON, 0, HEAD_VERSION, COMPAT_VERSION) + { + set_priority(CEPH_MSG_PRIO_HIGH); + } + MMDSBeacon(const uuid_d &f, mds_gid_t g, const string& n, epoch_t les, MDSMap::DaemonState st, version_t se, uint64_t feat) : + MessageInstance(MSG_MDS_BEACON, les, HEAD_VERSION, COMPAT_VERSION), + fsid(f), global_id(g), name(n), state(st), seq(se), + mds_features(feat) { + set_priority(CEPH_MSG_PRIO_HIGH); + } + ~MMDSBeacon() override {} + +public: + const uuid_d& get_fsid() const { return fsid; } + mds_gid_t get_global_id() const { return global_id; } + const string& get_name() const { return name; } + epoch_t get_last_epoch_seen() const { return version; } + MDSMap::DaemonState get_state() const { return state; } + version_t get_seq() const { return seq; } + std::string_view get_type_name() const override { return "mdsbeacon"; } + uint64_t get_mds_features() const { return mds_features; } + + CompatSet const& get_compat() const { return compat; } + void set_compat(const CompatSet& c) { compat = c; } + + MDSHealth const& get_health() const { return health; } + void set_health(const MDSHealth &h) { health = h; } + + const map<string, string>& get_sys_info() const { return sys_info; } + void set_sys_info(const map<string, string>& i) { sys_info = i; } + + void print(ostream& out) const override { + out << "mdsbeacon(" << global_id << "/" << name << " " << ceph_mds_state_name(state) + << " seq " << seq << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(global_id, payload); + encode((__u32)state, payload); + encode(seq, payload); + encode(name, payload); + encode(MDS_RANK_NONE, payload); + encode(std::string(), payload); + encode(compat, payload); + encode(health, payload); + if (state == MDSMap::STATE_BOOT) { + encode(sys_info, payload); + } + encode(mds_features, payload); + encode(FS_CLUSTER_ID_NONE, payload); + encode(false, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(global_id, p); + __u32 raw_state; + decode(raw_state, p); + state = (MDSMap::DaemonState)raw_state; + decode(seq, p); + decode(name, p); + { + mds_rank_t standby_for_rank; + decode(standby_for_rank, p); + } + { + std::string standby_for_name; + decode(standby_for_name, p); + } + decode(compat, p); + decode(health, p); + if (state == MDSMap::STATE_BOOT) { + decode(sys_info, p); + } + decode(mds_features, p); + { + fs_cluster_id_t standby_for_fscid; + decode(standby_for_fscid, p); + } + if (header.version >= 7) { + bool standby_replay; + decode(standby_replay, p); + } + + if (header.version < 7 && state == MDSMap::STATE_STANDBY_REPLAY) { + // Old MDS daemons request the state, instead of explicitly + // advertising that they are configured as a replay daemon. + state = MDSMap::STATE_STANDBY; + } + } +}; + +#endif diff --git a/src/messages/MMDSCacheRejoin.h b/src/messages/MMDSCacheRejoin.h new file mode 100644 index 00000000..985adb52 --- /dev/null +++ b/src/messages/MMDSCacheRejoin.h @@ -0,0 +1,372 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSCACHEREJOIN_H +#define CEPH_MMDSCACHEREJOIN_H + +#include <string_view> + +#include "msg/Message.h" + +#include "include/types.h" + +#include "mds/CInode.h" +#include "mds/CDir.h" +#include "mds/mdstypes.h" + +// sent from replica to auth + +class MMDSCacheRejoin : public MessageInstance<MMDSCacheRejoin> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + + public: + static constexpr int OP_WEAK = 1; // replica -> auth, i exist, + maybe open files. + static constexpr int OP_STRONG = 2; // replica -> auth, i exist, + open files and lock state. + static constexpr int OP_ACK = 3; // auth -> replica, here is your lock state. + static const char *get_opname(int op) { + switch (op) { + case OP_WEAK: return "weak"; + case OP_STRONG: return "strong"; + case OP_ACK: return "ack"; + default: ceph_abort(); return 0; + } + } + + // -- types -- + struct inode_strong { + uint32_t nonce = 0; + int32_t caps_wanted = 0; + int32_t filelock = 0, nestlock = 0, dftlock = 0; + inode_strong() {} + inode_strong(int n, int cw, int dl, int nl, int dftl) : + nonce(n), caps_wanted(cw), + filelock(dl), nestlock(nl), dftlock(dftl) { } + void encode(bufferlist &bl) const { + using ceph::encode; + encode(nonce, bl); + encode(caps_wanted, bl); + encode(filelock, bl); + encode(nestlock, bl); + encode(dftlock, bl); + } + void decode(bufferlist::const_iterator &bl) { + using ceph::decode; + decode(nonce, bl); + decode(caps_wanted, bl); + decode(filelock, bl); + decode(nestlock, bl); + decode(dftlock, bl); + } + }; + WRITE_CLASS_ENCODER(inode_strong) + + struct dirfrag_strong { + uint32_t nonce = 0; + int8_t dir_rep = 0; + dirfrag_strong() {} + dirfrag_strong(int n, int dr) : nonce(n), dir_rep(dr) {} + void encode(bufferlist &bl) const { + using ceph::encode; + encode(nonce, bl); + encode(dir_rep, bl); + } + void decode(bufferlist::const_iterator &bl) { + using ceph::decode; + decode(nonce, bl); + decode(dir_rep, bl); + } + }; + WRITE_CLASS_ENCODER(dirfrag_strong) + + struct dn_strong { + snapid_t first; + inodeno_t ino; + inodeno_t remote_ino; + unsigned char remote_d_type; + uint32_t nonce; + int32_t lock; + dn_strong() : + ino(0), remote_ino(0), remote_d_type(0), nonce(0), lock(0) {} + dn_strong(snapid_t f, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int l) : + first(f), ino(pi), remote_ino(ri), remote_d_type(rdt), nonce(n), lock(l) {} + bool is_primary() const { return ino > 0; } + bool is_remote() const { return remote_ino > 0; } + bool is_null() const { return ino == 0 && remote_ino == 0; } + void encode(bufferlist &bl) const { + using ceph::encode; + encode(first, bl); + encode(ino, bl); + encode(remote_ino, bl); + encode(remote_d_type, bl); + encode(nonce, bl); + encode(lock, bl); + } + void decode(bufferlist::const_iterator &bl) { + using ceph::decode; + decode(first, bl); + decode(ino, bl); + decode(remote_ino, bl); + decode(remote_d_type, bl); + decode(nonce, bl); + decode(lock, bl); + } + }; + WRITE_CLASS_ENCODER(dn_strong) + + struct dn_weak { + snapid_t first; + inodeno_t ino; + dn_weak() : ino(0) {} + dn_weak(snapid_t f, inodeno_t pi) : first(f), ino(pi) {} + void encode(bufferlist &bl) const { + using ceph::encode; + encode(first, bl); + encode(ino, bl); + } + void decode(bufferlist::const_iterator &bl) { + using ceph::decode; + decode(first, bl); + decode(ino, bl); + } + }; + WRITE_CLASS_ENCODER(dn_weak) + + // -- data -- + int32_t op; + + struct lock_bls { + bufferlist file, nest, dft; + void encode(bufferlist& bl) const { + using ceph::encode; + encode(file, bl); + encode(nest, bl); + encode(dft, bl); + } + void decode(bufferlist::const_iterator& bl) { + using ceph::decode; + decode(file, bl); + decode(nest, bl); + decode(dft, bl); + } + }; + WRITE_CLASS_ENCODER(lock_bls) + + // weak + map<inodeno_t, map<string_snap_t, dn_weak> > weak; + set<dirfrag_t> weak_dirfrags; + set<vinodeno_t> weak_inodes; + map<inodeno_t, lock_bls> inode_scatterlocks; + + // strong + map<dirfrag_t, dirfrag_strong> strong_dirfrags; + map<dirfrag_t, map<string_snap_t, dn_strong> > strong_dentries; + map<vinodeno_t, inode_strong> strong_inodes; + + // open + map<inodeno_t,map<client_t, cap_reconnect_t> > cap_exports; + map<client_t, entity_inst_t> client_map; + map<client_t,client_metadata_t> client_metadata_map; + bufferlist imported_caps; + + // full + bufferlist inode_base; + bufferlist inode_locks; + map<dirfrag_t, bufferlist> dirfrag_bases; + + // authpins, xlocks + struct slave_reqid { + metareqid_t reqid; + __u32 attempt; + slave_reqid() : attempt(0) {} + slave_reqid(const metareqid_t& r, __u32 a) + : reqid(r), attempt(a) {} + void encode(bufferlist& bl) const { + using ceph::encode; + encode(reqid, bl); + encode(attempt, bl); + } + void decode(bufferlist::const_iterator& bl) { + using ceph::decode; + decode(reqid, bl); + decode(attempt, bl); + } + }; + map<vinodeno_t, list<slave_reqid> > authpinned_inodes; + map<vinodeno_t, slave_reqid> frozen_authpin_inodes; + map<vinodeno_t, map<__s32, slave_reqid> > xlocked_inodes; + map<vinodeno_t, map<__s32, list<slave_reqid> > > wrlocked_inodes; + map<dirfrag_t, map<string_snap_t, list<slave_reqid> > > authpinned_dentries; + map<dirfrag_t, map<string_snap_t, slave_reqid> > xlocked_dentries; + +protected: + MMDSCacheRejoin() : + MessageInstance(MSG_MDS_CACHEREJOIN, HEAD_VERSION, COMPAT_VERSION), + op(0) {} + MMDSCacheRejoin(int o) : + MessageInstance(MSG_MDS_CACHEREJOIN, HEAD_VERSION, COMPAT_VERSION), + op(o) {} + ~MMDSCacheRejoin() override {} + +public: + std::string_view get_type_name() const override { return "cache_rejoin"; } + void print(ostream& out) const override { + out << "cache_rejoin " << get_opname(op); + } + + // -- builders -- + // inodes + void add_weak_inode(vinodeno_t i) { + weak_inodes.insert(i); + } + void add_strong_inode(vinodeno_t i, int n, int cw, int dl, int nl, int dftl) { + strong_inodes[i] = inode_strong(n, cw, dl, nl, dftl); + } + void add_inode_locks(CInode *in, __u32 nonce, bufferlist& bl) { + using ceph::encode; + encode(in->inode.ino, inode_locks); + encode(in->last, inode_locks); + encode(nonce, inode_locks); + encode(bl, inode_locks); + } + void add_inode_base(CInode *in, uint64_t features) { + using ceph::encode; + encode(in->inode.ino, inode_base); + encode(in->last, inode_base); + bufferlist bl; + in->_encode_base(bl, features); + encode(bl, inode_base); + } + void add_inode_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) { + authpinned_inodes[ino].push_back(slave_reqid(ri, attempt)); + } + void add_inode_frozen_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) { + frozen_authpin_inodes[ino] = slave_reqid(ri, attempt); + } + void add_inode_xlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) { + xlocked_inodes[ino][lt] = slave_reqid(ri, attempt); + } + void add_inode_wrlock(vinodeno_t ino, int lt, const metareqid_t& ri, __u32 attempt) { + wrlocked_inodes[ino][lt].push_back(slave_reqid(ri, attempt)); + } + + void add_scatterlock_state(CInode *in) { + if (inode_scatterlocks.count(in->ino())) + return; // already added this one + in->encode_lock_state(CEPH_LOCK_IFILE, inode_scatterlocks[in->ino()].file); + in->encode_lock_state(CEPH_LOCK_INEST, inode_scatterlocks[in->ino()].nest); + in->encode_lock_state(CEPH_LOCK_IDFT, inode_scatterlocks[in->ino()].dft); + } + + // dirfrags + void add_strong_dirfrag(dirfrag_t df, int n, int dr) { + strong_dirfrags[df] = dirfrag_strong(n, dr); + } + void add_dirfrag_base(CDir *dir) { + bufferlist& bl = dirfrag_bases[dir->dirfrag()]; + dir->_encode_base(bl); + } + + // dentries + void add_weak_dirfrag(dirfrag_t df) { + weak_dirfrags.insert(df); + } + void add_weak_dentry(inodeno_t dirino, std::string_view dname, snapid_t last, dn_weak& dnw) { + weak[dirino][string_snap_t(dname, last)] = dnw; + } + void add_weak_primary_dentry(inodeno_t dirino, std::string_view dname, snapid_t first, snapid_t last, inodeno_t ino) { + weak[dirino][string_snap_t(dname, last)] = dn_weak(first, ino); + } + void add_strong_dentry(dirfrag_t df, std::string_view dname, snapid_t first, snapid_t last, inodeno_t pi, inodeno_t ri, unsigned char rdt, int n, int ls) { + strong_dentries[df][string_snap_t(dname, last)] = dn_strong(first, pi, ri, rdt, n, ls); + } + void add_dentry_authpin(dirfrag_t df, std::string_view dname, snapid_t last, + const metareqid_t& ri, __u32 attempt) { + authpinned_dentries[df][string_snap_t(dname, last)].push_back(slave_reqid(ri, attempt)); + } + void add_dentry_xlock(dirfrag_t df, std::string_view dname, snapid_t last, + const metareqid_t& ri, __u32 attempt) { + xlocked_dentries[df][string_snap_t(dname, last)] = slave_reqid(ri, attempt); + } + + // -- encoding -- + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(op, payload); + encode(strong_inodes, payload); + encode(inode_base, payload); + encode(inode_locks, payload); + encode(inode_scatterlocks, payload); + encode(authpinned_inodes, payload); + encode(frozen_authpin_inodes, payload); + encode(xlocked_inodes, payload); + encode(wrlocked_inodes, payload); + encode(cap_exports, payload); + encode(client_map, payload, features); + encode(imported_caps, payload); + encode(strong_dirfrags, payload); + encode(dirfrag_bases, payload); + encode(weak, payload); + encode(weak_dirfrags, payload); + encode(weak_inodes, payload); + encode(strong_dentries, payload); + encode(authpinned_dentries, payload); + encode(xlocked_dentries, payload); + encode(client_metadata_map, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + using ceph::decode; + decode(op, p); + decode(strong_inodes, p); + decode(inode_base, p); + decode(inode_locks, p); + decode(inode_scatterlocks, p); + decode(authpinned_inodes, p); + decode(frozen_authpin_inodes, p); + decode(xlocked_inodes, p); + decode(wrlocked_inodes, p); + decode(cap_exports, p); + decode(client_map, p); + decode(imported_caps, p); + decode(strong_dirfrags, p); + decode(dirfrag_bases, p); + decode(weak, p); + decode(weak_dirfrags, p); + decode(weak_inodes, p); + decode(strong_dentries, p); + decode(authpinned_dentries, p); + decode(xlocked_dentries, p); + if (header.version >= 2) + decode(client_metadata_map, p); + } + +}; + +WRITE_CLASS_ENCODER(MMDSCacheRejoin::inode_strong) +WRITE_CLASS_ENCODER(MMDSCacheRejoin::dirfrag_strong) +WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_strong) +WRITE_CLASS_ENCODER(MMDSCacheRejoin::dn_weak) +WRITE_CLASS_ENCODER(MMDSCacheRejoin::lock_bls) +WRITE_CLASS_ENCODER(MMDSCacheRejoin::slave_reqid) + +inline ostream& operator<<(ostream& out, const MMDSCacheRejoin::slave_reqid& r) { + return out << r.reqid << '.' << r.attempt; +} + +#endif diff --git a/src/messages/MMDSFindIno.h b/src/messages/MMDSFindIno.h new file mode 100644 index 00000000..a6d661b9 --- /dev/null +++ b/src/messages/MMDSFindIno.h @@ -0,0 +1,51 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MDSFINDINO_H +#define CEPH_MDSFINDINO_H + +#include "msg/Message.h" +#include "include/filepath.h" + +class MMDSFindIno : public MessageInstance<MMDSFindIno> { +public: + friend factory; + + ceph_tid_t tid {0}; + inodeno_t ino; + +protected: + MMDSFindIno() : MessageInstance(MSG_MDS_FINDINO) {} + MMDSFindIno(ceph_tid_t t, inodeno_t i) : MessageInstance(MSG_MDS_FINDINO), tid(t), ino(i) {} + ~MMDSFindIno() override {} + +public: + std::string_view get_type_name() const override { return "findino"; } + void print(ostream &out) const override { + out << "findino(" << tid << " " << ino << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(tid, payload); + encode(ino, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(tid, p); + decode(ino, p); + } +}; + +#endif diff --git a/src/messages/MMDSFindInoReply.h b/src/messages/MMDSFindInoReply.h new file mode 100644 index 00000000..10e003b3 --- /dev/null +++ b/src/messages/MMDSFindInoReply.h @@ -0,0 +1,51 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MDSFINDINOREPLY_H +#define CEPH_MDSFINDINOREPLY_H + +#include "msg/Message.h" +#include "include/filepath.h" + +class MMDSFindInoReply : public MessageInstance<MMDSFindInoReply> { +public: + friend factory; + + ceph_tid_t tid = 0; + filepath path; + +protected: + MMDSFindInoReply() : MessageInstance(MSG_MDS_FINDINOREPLY) {} + MMDSFindInoReply(ceph_tid_t t) : MessageInstance(MSG_MDS_FINDINOREPLY), tid(t) {} + ~MMDSFindInoReply() override {} + +public: + std::string_view get_type_name() const override { return "findinoreply"; } + void print(ostream &out) const override { + out << "findinoreply(" << tid << " " << path << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(tid, payload); + encode(path, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(tid, p); + decode(path, p); + } +}; + +#endif diff --git a/src/messages/MMDSFragmentNotify.h b/src/messages/MMDSFragmentNotify.h new file mode 100644 index 00000000..0baa874f --- /dev/null +++ b/src/messages/MMDSFragmentNotify.h @@ -0,0 +1,75 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSFRAGMENTNOTIFY_H +#define CEPH_MMDSFRAGMENTNOTIFY_H + +#include "msg/Message.h" + +class MMDSFragmentNotify : public MessageInstance<MMDSFragmentNotify> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + + dirfrag_t base_dirfrag; + int8_t bits = 0; + bool ack_wanted = false; + + public: + inodeno_t get_ino() const { return base_dirfrag.ino; } + frag_t get_basefrag() const { return base_dirfrag.frag; } + dirfrag_t get_base_dirfrag() const { return base_dirfrag; } + int get_bits() const { return bits; } + bool is_ack_wanted() const { return ack_wanted; } + void mark_ack_wanted() { ack_wanted = true; } + + bufferlist basebl; + +protected: + MMDSFragmentNotify() : + MessageInstance(MSG_MDS_FRAGMENTNOTIFY, HEAD_VERSION, COMPAT_VERSION) {} + MMDSFragmentNotify(dirfrag_t df, int b, uint64_t tid) : + MessageInstance(MSG_MDS_FRAGMENTNOTIFY, HEAD_VERSION, COMPAT_VERSION), + base_dirfrag(df), bits(b) { + set_tid(tid); + } + ~MMDSFragmentNotify() override {} + +public: + std::string_view get_type_name() const override { return "fragment_notify"; } + void print(ostream& o) const override { + o << "fragment_notify(" << base_dirfrag << " " << (int)bits << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(base_dirfrag, payload); + encode(bits, payload); + encode(basebl, payload); + encode(ack_wanted, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(base_dirfrag, p); + decode(bits, p); + decode(basebl, p); + if (header.version >= 2) + decode(ack_wanted, p); + } + +}; + +#endif diff --git a/src/messages/MMDSFragmentNotifyAck.h b/src/messages/MMDSFragmentNotifyAck.h new file mode 100644 index 00000000..e20a3089 --- /dev/null +++ b/src/messages/MMDSFragmentNotifyAck.h @@ -0,0 +1,60 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSFRAGMENTNOTIFYAck_H +#define CEPH_MMDSFRAGMENTNOTIFYAck_H + +#include "msg/Message.h" + +class MMDSFragmentNotifyAck : public MessageInstance<MMDSFragmentNotifyAck> { +public: + friend factory; +private: + dirfrag_t base_dirfrag; + int8_t bits = 0; + + public: + dirfrag_t get_base_dirfrag() const { return base_dirfrag; } + int get_bits() const { return bits; } + + bufferlist basebl; + +protected: + MMDSFragmentNotifyAck() : MessageInstance(MSG_MDS_FRAGMENTNOTIFYACK) {} + MMDSFragmentNotifyAck(dirfrag_t df, int b, uint64_t tid) : + MessageInstance(MSG_MDS_FRAGMENTNOTIFYACK), + base_dirfrag(df), bits(b) { + set_tid(tid); + } + ~MMDSFragmentNotifyAck() override {} + +public: + std::string_view get_type_name() const override { return "fragment_notify_ack"; } + void print(ostream& o) const override { + o << "fragment_notify_ack(" << base_dirfrag << " " << (int)bits << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(base_dirfrag, payload); + encode(bits, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(base_dirfrag, p); + decode(bits, p); + } +}; + +#endif diff --git a/src/messages/MMDSLoadTargets.h b/src/messages/MMDSLoadTargets.h new file mode 100644 index 00000000..98d845de --- /dev/null +++ b/src/messages/MMDSLoadTargets.h @@ -0,0 +1,62 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2009 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSLoadTargets_H +#define CEPH_MMDSLoadTargets_H + +#include "msg/Message.h" +#include "mds/mdstypes.h" +#include "messages/PaxosServiceMessage.h" +#include "include/types.h" + +#include <map> +using std::map; + +class MMDSLoadTargets : public MessageInstance<MMDSLoadTargets, PaxosServiceMessage> { +public: + friend factory; + + mds_gid_t global_id; + set<mds_rank_t> targets; + +protected: + MMDSLoadTargets() : MessageInstance(MSG_MDS_OFFLOAD_TARGETS, 0) {} + MMDSLoadTargets(mds_gid_t g, set<mds_rank_t>& mds_targets) : + MessageInstance(MSG_MDS_OFFLOAD_TARGETS, 0), + global_id(g), targets(mds_targets) {} + ~MMDSLoadTargets() override {} + +public: + std::string_view get_type_name() const override { return "mds_load_targets"; } + void print(ostream& o) const override { + o << "mds_load_targets(" << global_id << " " << targets << ")"; + } + + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + paxos_decode(p); + decode(global_id, p); + decode(targets, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(global_id, payload); + encode(targets, payload); + } +}; + +#endif diff --git a/src/messages/MMDSMap.h b/src/messages/MMDSMap.h new file mode 100644 index 00000000..726cfac5 --- /dev/null +++ b/src/messages/MMDSMap.h @@ -0,0 +1,79 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMDSMAP_H +#define CEPH_MMDSMAP_H + +#include "msg/Message.h" +#include "mds/MDSMap.h" +#include "include/ceph_features.h" + +class MMDSMap : public MessageInstance<MMDSMap> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; +public: + uuid_d fsid; + epoch_t epoch = 0; + bufferlist encoded; + + version_t get_epoch() const { return epoch; } + const bufferlist& get_encoded() const { return encoded; } + +protected: + MMDSMap() : + MessageInstance(CEPH_MSG_MDS_MAP, HEAD_VERSION, COMPAT_VERSION) {} + MMDSMap(const uuid_d &f, const MDSMap &mm) : + MessageInstance(CEPH_MSG_MDS_MAP, HEAD_VERSION, COMPAT_VERSION), + fsid(f) { + epoch = mm.get_epoch(); + mm.encode(encoded, -1); // we will reencode with fewer features as necessary + } + ~MMDSMap() override {} + +public: + std::string_view get_type_name() const override { return "mdsmap"; } + void print(ostream& out) const override { + out << "mdsmap(e " << epoch << ")"; + } + + // marshalling + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(epoch, p); + decode(encoded, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(fsid, payload); + encode(epoch, payload); + if ((features & CEPH_FEATURE_PGID64) == 0 || + (features & CEPH_FEATURE_MDSENC) == 0 || + (features & CEPH_FEATURE_MSG_ADDR2) == 0 || + !HAVE_FEATURE(features, SERVER_NAUTILUS)) { + // reencode for old clients. + MDSMap m; + m.decode(encoded); + encoded.clear(); + m.encode(encoded, features); + } + encode(encoded, payload); + } +}; + +#endif diff --git a/src/messages/MMDSOpenIno.h b/src/messages/MMDSOpenIno.h new file mode 100644 index 00000000..b9a068be --- /dev/null +++ b/src/messages/MMDSOpenIno.h @@ -0,0 +1,55 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MDSOPENINO_H +#define CEPH_MDSOPENINO_H + +#include "msg/Message.h" + +class MMDSOpenIno : public MessageInstance<MMDSOpenIno> { +public: + friend factory; + + inodeno_t ino; + vector<inode_backpointer_t> ancestors; + +protected: + MMDSOpenIno() : MessageInstance(MSG_MDS_OPENINO) {} + MMDSOpenIno(ceph_tid_t t, inodeno_t i, vector<inode_backpointer_t>* pa) : + MessageInstance(MSG_MDS_OPENINO), ino(i) { + header.tid = t; + if (pa) + ancestors = *pa; + } + ~MMDSOpenIno() override {} + +public: + std::string_view get_type_name() const override { return "openino"; } + void print(ostream &out) const override { + out << "openino(" << header.tid << " " << ino << " " << ancestors << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(ancestors, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(ino, p); + decode(ancestors, p); + } +}; + +#endif diff --git a/src/messages/MMDSOpenInoReply.h b/src/messages/MMDSOpenInoReply.h new file mode 100644 index 00000000..6f87e6a9 --- /dev/null +++ b/src/messages/MMDSOpenInoReply.h @@ -0,0 +1,60 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MDSOPENINOREPLY_H +#define CEPH_MDSOPENINOREPLY_H + +#include "msg/Message.h" + +class MMDSOpenInoReply : public MessageInstance<MMDSOpenInoReply> { +public: + friend factory; + + inodeno_t ino; + vector<inode_backpointer_t> ancestors; + mds_rank_t hint; + int32_t error; + +protected: + MMDSOpenInoReply() : MessageInstance(MSG_MDS_OPENINOREPLY), error(0) {} + MMDSOpenInoReply(ceph_tid_t t, inodeno_t i, mds_rank_t h=MDS_RANK_NONE, int e=0) : + MessageInstance(MSG_MDS_OPENINOREPLY), ino(i), hint(h), error(e) { + header.tid = t; + } + + +public: + std::string_view get_type_name() const override { return "openinoreply"; } + void print(ostream &out) const override { + out << "openinoreply(" << header.tid << " " + << ino << " " << hint << " " << ancestors << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(ancestors, payload); + encode(hint, payload); + encode(error, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(ino, p); + decode(ancestors, p); + decode(hint, p); + decode(error, p); + } +}; + +#endif diff --git a/src/messages/MMDSResolve.h b/src/messages/MMDSResolve.h new file mode 100644 index 00000000..52fad12e --- /dev/null +++ b/src/messages/MMDSResolve.h @@ -0,0 +1,129 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSRESOLVE_H +#define CEPH_MMDSRESOLVE_H + +#include "msg/Message.h" + +#include "include/types.h" + +class MMDSResolve : public MessageInstance<MMDSResolve> { +public: + friend factory; + + map<dirfrag_t, vector<dirfrag_t> > subtrees; + map<dirfrag_t, vector<dirfrag_t> > ambiguous_imports; + + struct slave_request { + bufferlist inode_caps; + bool committing; + slave_request() : committing(false) {} + void encode(bufferlist &bl) const { + using ceph::encode; + encode(inode_caps, bl); + encode(committing, bl); + } + void decode(bufferlist::const_iterator &bl) { + using ceph::decode; + decode(inode_caps, bl); + decode(committing, bl); + } + }; + + map<metareqid_t, slave_request> slave_requests; + + // table client information + struct table_client { + __u8 type; + set<version_t> pending_commits; + + table_client() : type(0) {} + table_client(int _type, const set<version_t>& commits) + : type(_type), pending_commits(commits) {} + + void encode(bufferlist& bl) const { + using ceph::encode; + encode(type, bl); + encode(pending_commits, bl); + } + void decode(bufferlist::const_iterator& bl) { + using ceph::decode; + decode(type, bl); + decode(pending_commits, bl); + } + }; + + list<table_client> table_clients; + +protected: + MMDSResolve() : MessageInstance(MSG_MDS_RESOLVE) {} + ~MMDSResolve() override {} + +public: + std::string_view get_type_name() const override { return "mds_resolve"; } + + void print(ostream& out) const override { + out << "mds_resolve(" << subtrees.size() + << "+" << ambiguous_imports.size() + << " subtrees +" << slave_requests.size() << " slave requests)"; + } + + void add_subtree(dirfrag_t im) { + subtrees[im].clear(); + } + void add_subtree_bound(dirfrag_t im, dirfrag_t ex) { + subtrees[im].push_back(ex); + } + + void add_ambiguous_import(dirfrag_t im, const vector<dirfrag_t>& m) { + ambiguous_imports[im] = m; + } + + void add_slave_request(metareqid_t reqid, bool committing) { + slave_requests[reqid].committing = committing; + } + + void add_slave_request(metareqid_t reqid, bufferlist& bl) { + slave_requests[reqid].inode_caps.claim(bl); + } + + void add_table_commits(int table, const set<version_t>& pending_commits) { + table_clients.push_back(table_client(table, pending_commits)); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(subtrees, payload); + encode(ambiguous_imports, payload); + encode(slave_requests, payload); + encode(table_clients, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(subtrees, p); + decode(ambiguous_imports, p); + decode(slave_requests, p); + decode(table_clients, p); + } +}; + +inline ostream& operator<<(ostream& out, const MMDSResolve::slave_request&) { + return out; +} + +WRITE_CLASS_ENCODER(MMDSResolve::slave_request) +WRITE_CLASS_ENCODER(MMDSResolve::table_client) +#endif diff --git a/src/messages/MMDSResolveAck.h b/src/messages/MMDSResolveAck.h new file mode 100644 index 00000000..42698834 --- /dev/null +++ b/src/messages/MMDSResolveAck.h @@ -0,0 +1,63 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSRESOLVEACK_H +#define CEPH_MMDSRESOLVEACK_H + +#include "msg/Message.h" + +#include "include/types.h" + + +class MMDSResolveAck : public MessageInstance<MMDSResolveAck> { +public: + friend factory; + + map<metareqid_t, bufferlist> commit; + vector<metareqid_t> abort; + +protected: + MMDSResolveAck() : MessageInstance(MSG_MDS_RESOLVEACK) {} + ~MMDSResolveAck() override {} + +public: + std::string_view get_type_name() const override { return "resolve_ack"; } + /*void print(ostream& out) const { + out << "resolve_ack.size() + << "+" << ambiguous_imap.size() + << " imports +" << slave_requests.size() << " slave requests)"; + } + */ + + void add_commit(metareqid_t r) { + commit[r].clear(); + } + void add_abort(metareqid_t r) { + abort.push_back(r); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(commit, payload); + encode(abort, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(commit, p); + decode(abort, p); + } +}; + +#endif diff --git a/src/messages/MMDSSlaveRequest.h b/src/messages/MMDSSlaveRequest.h new file mode 100644 index 00000000..f9be3af8 --- /dev/null +++ b/src/messages/MMDSSlaveRequest.h @@ -0,0 +1,220 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMDSSLAVEREQUEST_H +#define CEPH_MMDSSLAVEREQUEST_H + +#include "msg/Message.h" +#include "mds/mdstypes.h" + +class MMDSSlaveRequest : public MessageInstance<MMDSSlaveRequest> { +public: + friend factory; + + static constexpr int OP_XLOCK = 1; + static constexpr int OP_XLOCKACK = -1; + static constexpr int OP_UNXLOCK = 2; + static constexpr int OP_AUTHPIN = 3; + static constexpr int OP_AUTHPINACK = -3; + + static constexpr int OP_LINKPREP = 4; + static constexpr int OP_UNLINKPREP = 5; + static constexpr int OP_LINKPREPACK = -4; + + static constexpr int OP_RENAMEPREP = 7; + static constexpr int OP_RENAMEPREPACK = -7; + + static constexpr int OP_WRLOCK = 8; + static constexpr int OP_WRLOCKACK = -8; + static constexpr int OP_UNWRLOCK = 9; + + static constexpr int OP_RMDIRPREP = 10; + static constexpr int OP_RMDIRPREPACK = -10; + + static constexpr int OP_DROPLOCKS = 11; + + static constexpr int OP_RENAMENOTIFY = 12; + static constexpr int OP_RENAMENOTIFYACK = -12; + + static constexpr int OP_FINISH = 17; + static constexpr int OP_COMMITTED = -18; + + static constexpr int OP_ABORT = 20; // used for recovery only + //static constexpr int OP_COMMIT = 21; // used for recovery only + + + static const char *get_opname(int o) { + switch (o) { + case OP_XLOCK: return "xlock"; + case OP_XLOCKACK: return "xlock_ack"; + case OP_UNXLOCK: return "unxlock"; + case OP_AUTHPIN: return "authpin"; + case OP_AUTHPINACK: return "authpin_ack"; + + case OP_LINKPREP: return "link_prep"; + case OP_LINKPREPACK: return "link_prep_ack"; + case OP_UNLINKPREP: return "unlink_prep"; + + case OP_RENAMEPREP: return "rename_prep"; + case OP_RENAMEPREPACK: return "rename_prep_ack"; + + case OP_FINISH: return "finish"; // commit + case OP_COMMITTED: return "committed"; + + case OP_WRLOCK: return "wrlock"; + case OP_WRLOCKACK: return "wrlock_ack"; + case OP_UNWRLOCK: return "unwrlock"; + + case OP_RMDIRPREP: return "rmdir_prep"; + case OP_RMDIRPREPACK: return "rmdir_prep_ack"; + + case OP_DROPLOCKS: return "drop_locks"; + + case OP_RENAMENOTIFY: return "rename_notify"; + case OP_RENAMENOTIFYACK: return "rename_notify_ack"; + + case OP_ABORT: return "abort"; + //case OP_COMMIT: return "commit"; + + default: ceph_abort(); return 0; + } + } + + private: + metareqid_t reqid; + __u32 attempt; + __s16 op; + mutable __u16 flags; /* XXX HACK for mark_interrupted */ + + static constexpr unsigned FLAG_NONBLOCK = 1<<0; + static constexpr unsigned FLAG_WOULDBLOCK = 1<<1; + static constexpr unsigned FLAG_NOTJOURNALED = 1<<2; + static constexpr unsigned FLAG_EROFS = 1<<3; + static constexpr unsigned FLAG_ABORT = 1<<4; + static constexpr unsigned FLAG_INTERRUPTED = 1<<5; + + // for locking + __u16 lock_type; // lock object type + MDSCacheObjectInfo object_info; + + // for authpins + vector<MDSCacheObjectInfo> authpins; + + public: + // for rename prep + filepath srcdnpath; + filepath destdnpath; + set<mds_rank_t> witnesses; + bufferlist inode_export; + version_t inode_export_v; + mds_rank_t srcdn_auth; + utime_t op_stamp; + + mutable bufferlist straybl; // stray dir + dentry + bufferlist srci_snapbl; + bufferlist desti_snapbl; + +public: + metareqid_t get_reqid() const { return reqid; } + __u32 get_attempt() const { return attempt; } + int get_op() const { return op; } + bool is_reply() const { return op < 0; } + + int get_lock_type() const { return lock_type; } + const MDSCacheObjectInfo &get_object_info() const { return object_info; } + MDSCacheObjectInfo &get_object_info() { return object_info; } + const MDSCacheObjectInfo &get_authpin_freeze() const { return object_info; } + MDSCacheObjectInfo &get_authpin_freeze() { return object_info; } + + const vector<MDSCacheObjectInfo>& get_authpins() const { return authpins; } + vector<MDSCacheObjectInfo>& get_authpins() { return authpins; } + void mark_nonblock() { flags |= FLAG_NONBLOCK; } + bool is_nonblock() const { return (flags & FLAG_NONBLOCK); } + void mark_error_wouldblock() { flags |= FLAG_WOULDBLOCK; } + bool is_error_wouldblock() const { return (flags & FLAG_WOULDBLOCK); } + void mark_not_journaled() { flags |= FLAG_NOTJOURNALED; } + bool is_not_journaled() const { return (flags & FLAG_NOTJOURNALED); } + void mark_error_rofs() { flags |= FLAG_EROFS; } + bool is_error_rofs() const { return (flags & FLAG_EROFS); } + bool is_abort() const { return (flags & FLAG_ABORT); } + void mark_abort() { flags |= FLAG_ABORT; } + bool is_interrupted() const { return (flags & FLAG_INTERRUPTED); } + void mark_interrupted() const { flags |= FLAG_INTERRUPTED; } + + void set_lock_type(int t) { lock_type = t; } + const bufferlist& get_lock_data() const { return inode_export; } + bufferlist& get_lock_data() { return inode_export; } + +protected: + MMDSSlaveRequest() : MessageInstance(MSG_MDS_SLAVE_REQUEST) { } + MMDSSlaveRequest(metareqid_t ri, __u32 att, int o) : + MessageInstance(MSG_MDS_SLAVE_REQUEST), + reqid(ri), attempt(att), op(o), flags(0), lock_type(0), + inode_export_v(0), srcdn_auth(MDS_RANK_NONE) { } + ~MMDSSlaveRequest() override {} + +public: + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(reqid, payload); + encode(attempt, payload); + encode(op, payload); + encode(flags, payload); + encode(lock_type, payload); + encode(object_info, payload); + encode(authpins, payload); + encode(srcdnpath, payload); + encode(destdnpath, payload); + encode(witnesses, payload); + encode(op_stamp, payload); + encode(inode_export, payload); + encode(inode_export_v, payload); + encode(srcdn_auth, payload); + encode(straybl, payload); + encode(srci_snapbl, payload); + encode(desti_snapbl, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(reqid, p); + decode(attempt, p); + decode(op, p); + decode(flags, p); + decode(lock_type, p); + decode(object_info, p); + decode(authpins, p); + decode(srcdnpath, p); + decode(destdnpath, p); + decode(witnesses, p); + decode(op_stamp, p); + decode(inode_export, p); + decode(inode_export_v, p); + decode(srcdn_auth, p); + decode(straybl, p); + decode(srci_snapbl, p); + decode(desti_snapbl, p); + } + + std::string_view get_type_name() const override { return "slave_request"; } + void print(ostream& out) const override { + out << "slave_request(" << reqid + << "." << attempt + << " " << get_opname(op) + << ")"; + } + +}; + +#endif diff --git a/src/messages/MMDSSnapUpdate.h b/src/messages/MMDSSnapUpdate.h new file mode 100644 index 00000000..06872cdc --- /dev/null +++ b/src/messages/MMDSSnapUpdate.h @@ -0,0 +1,63 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMDSSNAPUPDATE_H +#define CEPH_MMDSSNAPUPDATE_H + +#include "msg/Message.h" + +class MMDSSnapUpdate : public MessageInstance<MMDSSnapUpdate> { +public: + friend factory; +private: + + inodeno_t ino; + __s16 snap_op; + +public: + inodeno_t get_ino() const { return ino; } + int get_snap_op() const { return snap_op; } + + bufferlist snap_blob; + +protected: + MMDSSnapUpdate() : MessageInstance(MSG_MDS_SNAPUPDATE) {} + MMDSSnapUpdate(inodeno_t i, version_t tid, int op) : + MessageInstance(MSG_MDS_SNAPUPDATE), ino(i), snap_op(op) { + set_tid(tid); + } + ~MMDSSnapUpdate() override {} + +public: + std::string_view get_type_name() const override { return "snap_update"; } + void print(ostream& o) const override { + o << "snap_update(" << ino << " table_tid " << get_tid() << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(ino, payload); + encode(snap_op, payload); + encode(snap_blob, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + decode(ino, p); + decode(snap_op, p); + decode(snap_blob, p); + } +}; + +#endif diff --git a/src/messages/MMDSTableRequest.h b/src/messages/MMDSTableRequest.h new file mode 100644 index 00000000..4a6e2ca9 --- /dev/null +++ b/src/messages/MMDSTableRequest.h @@ -0,0 +1,68 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMDSTABLEREQUEST_H +#define CEPH_MMDSTABLEREQUEST_H + +#include "msg/Message.h" +#include "mds/mds_table_types.h" + +class MMDSTableRequest : public MessageInstance<MMDSTableRequest> { +public: + friend factory; + + __u16 table = 0; + __s16 op = 0; + uint64_t reqid = 0; + bufferlist bl; + +protected: + MMDSTableRequest() : MessageInstance(MSG_MDS_TABLE_REQUEST) {} + MMDSTableRequest(int tab, int o, uint64_t r, version_t v=0) : + MessageInstance(MSG_MDS_TABLE_REQUEST), + table(tab), op(o), reqid(r) { + set_tid(v); + } + ~MMDSTableRequest() override {} + +public: + std::string_view get_type_name() const override { return "mds_table_request"; } + void print(ostream& o) const override { + o << "mds_table_request(" << get_mdstable_name(table) + << " " << get_mdstableserver_opname(op); + if (reqid) o << " " << reqid; + if (get_tid()) o << " tid " << get_tid(); + if (bl.length()) o << " " << bl.length() << " bytes"; + o << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(table, p); + decode(op, p); + decode(reqid, p); + decode(bl, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(table, payload); + encode(op, payload); + encode(reqid, payload); + encode(bl, payload); + } +}; + +#endif diff --git a/src/messages/MMgrBeacon.h b/src/messages/MMgrBeacon.h new file mode 100644 index 00000000..f3bb8384 --- /dev/null +++ b/src/messages/MMgrBeacon.h @@ -0,0 +1,185 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMGRBEACON_H +#define CEPH_MMGRBEACON_H + +#include "messages/PaxosServiceMessage.h" +#include "mon/MonCommand.h" +#include "mon/MgrMap.h" + +#include "include/types.h" + + +class MMgrBeacon : public MessageInstance<MMgrBeacon, PaxosServiceMessage> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 8; + static constexpr int COMPAT_VERSION = 8; + +protected: + uint64_t gid; + entity_addrvec_t server_addrs; + bool available; + std::string name; + uuid_d fsid; + + // From active daemon to populate MgrMap::services + std::map<std::string, std::string> services; + + // Only populated during activation + std::vector<MonCommand> command_descs; + + // Information about the modules found locally on this daemon + std::vector<MgrMap::ModuleInfo> modules; + + map<string,string> metadata; ///< misc metadata about this osd + +public: + MMgrBeacon() + : MessageInstance(MSG_MGR_BEACON, 0, HEAD_VERSION, COMPAT_VERSION), + gid(0), available(false) + { + } + + MMgrBeacon(const uuid_d& fsid_, uint64_t gid_, const std::string &name_, + entity_addrvec_t server_addrs_, bool available_, + std::vector<MgrMap::ModuleInfo>&& modules_, + map<string,string>&& metadata_) + : MessageInstance(MSG_MGR_BEACON, 0, HEAD_VERSION, COMPAT_VERSION), + gid(gid_), server_addrs(server_addrs_), available(available_), name(name_), + fsid(fsid_), modules(std::move(modules_)), metadata(std::move(metadata_)) + { + } + + uint64_t get_gid() const { return gid; } + entity_addrvec_t get_server_addrs() const { return server_addrs; } + bool get_available() const { return available; } + const std::string& get_name() const { return name; } + const uuid_d& get_fsid() const { return fsid; } + const std::map<std::string,std::string>& get_metadata() const { + return metadata; + } + + const std::map<std::string,std::string>& get_services() const { + return services; + } + + void set_services(const std::map<std::string, std::string> &svcs) + { + services = svcs; + } + + void set_command_descs(const std::vector<MonCommand> &cmds) + { + command_descs = cmds; + } + + const std::vector<MonCommand> &get_command_descs() + { + return command_descs; + } + + const std::vector<MgrMap::ModuleInfo> &get_available_modules() const + { + return modules; + } + +private: + ~MMgrBeacon() override {} + +public: + + std::string_view get_type_name() const override { return "mgrbeacon"; } + + void print(ostream& out) const override { + out << get_type_name() << " mgr." << name << "(" << fsid << "," + << gid << ", " << server_addrs << ", " << available + << ")"; + } + + void encode_payload(uint64_t features) override { + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + using ceph::encode; + paxos_encode(); + + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + header.version = 7; + header.compat_version = 1; + encode(server_addrs.legacy_addr(), payload, features); + } else { + encode(server_addrs, payload, features); + } + encode(gid, payload); + encode(available, payload); + encode(name, payload); + encode(fsid, payload); + + // Fill out old-style list of module names (deprecated by + // later field of full ModuleInfos) + std::set<std::string> module_names; + for (const auto &info : modules) { + module_names.insert(info.name); + } + encode(module_names, payload); + + encode(command_descs, payload); + encode(metadata, payload); + encode(services, payload); + + encode(modules, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(server_addrs, p); // entity_addr_t for version < 8 + decode(gid, p); + decode(available, p); + decode(name, p); + if (header.version >= 2) { + decode(fsid, p); + } + if (header.version >= 3) { + std::set<std::string> module_name_list; + decode(module_name_list, p); + // Only need to unpack this field if we won't have the full + // ModuleInfo structures added in v7 + if (header.version < 7) { + for (const auto &i : module_name_list) { + MgrMap::ModuleInfo info; + info.name = i; + modules.push_back(std::move(info)); + } + } + } + if (header.version >= 4) { + decode(command_descs, p); + } + if (header.version >= 5) { + decode(metadata, p); + } + if (header.version >= 6) { + decode(services, p); + } + if (header.version >= 7) { + decode(modules, p); + } + } +}; + + +#endif diff --git a/src/messages/MMgrClose.h b/src/messages/MMgrClose.h new file mode 100644 index 00000000..43d603a8 --- /dev/null +++ b/src/messages/MMgrClose.h @@ -0,0 +1,48 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" + +class MMgrClose : public MessageInstance<MMgrClose> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + +public: + std::string daemon_name; + std::string service_name; // optional; otherwise infer from entity type + + void decode_payload() override + { + auto p = payload.cbegin(); + decode(daemon_name, p); + decode(service_name, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(daemon_name, payload); + encode(service_name, payload); + } + + std::string_view get_type_name() const override { return "mgrclose"; } + void print(ostream& out) const override { + out << get_type_name() << "("; + if (service_name.length()) { + out << service_name; + } else { + out << ceph_entity_type_name(get_source().type()); + } + out << "." << daemon_name; + out << ")"; + } + + MMgrClose() + : MessageInstance(MSG_MGR_CLOSE, HEAD_VERSION, COMPAT_VERSION) + {} +}; diff --git a/src/messages/MMgrConfigure.h b/src/messages/MMgrConfigure.h new file mode 100644 index 00000000..b9f69095 --- /dev/null +++ b/src/messages/MMgrConfigure.h @@ -0,0 +1,72 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 John Spray <john.spray@redhat.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + + +#ifndef CEPH_MMGRCONFIGURE_H_ +#define CEPH_MMGRCONFIGURE_H_ + +#include "msg/Message.h" +#include "mgr/OSDPerfMetricTypes.h" + +/** + * This message is sent from ceph-mgr to MgrClient, instructing it + * it about what data to send back to ceph-mgr at what frequency. + */ +class MMgrConfigure : public MessageInstance<MMgrConfigure> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + +public: + uint32_t stats_period = 0; + + // Default 0 means if unspecified will include all stats + uint32_t stats_threshold = 0; + + std::map<OSDPerfMetricQuery, OSDPerfMetricLimits> osd_perf_metric_queries; + + void decode_payload() override + { + auto p = payload.cbegin(); + decode(stats_period, p); + if (header.version >= 2) { + decode(stats_threshold, p); + } + if (header.version >= 3) { + decode(osd_perf_metric_queries, p); + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(stats_period, payload); + encode(stats_threshold, payload); + encode(osd_perf_metric_queries, payload); + } + + std::string_view get_type_name() const override { return "mgrconfigure"; } + void print(ostream& out) const override { + out << get_type_name() << "(period=" << stats_period + << ", threshold=" << stats_threshold << ")"; + } + + MMgrConfigure() + : MessageInstance(MSG_MGR_CONFIGURE, HEAD_VERSION, COMPAT_VERSION) + {} +}; + +#endif + diff --git a/src/messages/MMgrDigest.h b/src/messages/MMgrDigest.h new file mode 100644 index 00000000..ec4800d4 --- /dev/null +++ b/src/messages/MMgrDigest.h @@ -0,0 +1,56 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMGRDIGEST_H +#define CEPH_MMGRDIGEST_H + +#include "msg/Message.h" + +/** + * The mgr digest is a way for the mgr to subscribe to things + * other than the cluster maps, which are needed by + */ +class MMgrDigest : public MessageInstance<MMgrDigest> { +public: + friend factory; + + bufferlist mon_status_json; + bufferlist health_json; + + MMgrDigest() : + MessageInstance(MSG_MGR_DIGEST) {} + + std::string_view get_type_name() const override { return "mgrdigest"; } + void print(ostream& out) const override { + out << get_type_name(); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(mon_status_json, p); + decode(health_json, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(mon_status_json, payload); + encode(health_json, payload); + } + +private: + ~MMgrDigest() override {} + +}; + +#endif diff --git a/src/messages/MMgrMap.h b/src/messages/MMgrMap.h new file mode 100644 index 00000000..032a9c1a --- /dev/null +++ b/src/messages/MMgrMap.h @@ -0,0 +1,58 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMGRMAP_H +#define CEPH_MMGRMAP_H + +#include "msg/Message.h" +#include "mon/MgrMap.h" + +class MMgrMap : public MessageInstance<MMgrMap> { +public: + friend factory; + +protected: + MgrMap map; + +public: + const MgrMap & get_map() {return map;} + + MMgrMap() : + MessageInstance(MSG_MGR_MAP) {} + MMgrMap(const MgrMap &map_) : + MessageInstance(MSG_MGR_MAP), map(map_) + { + } + +private: + ~MMgrMap() override {} + +public: + std::string_view get_type_name() const override { return "mgrmap"; } + void print(ostream& out) const override { + out << get_type_name() << "(e " << map.epoch << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(map, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(map, payload, features); + } +}; + +#endif diff --git a/src/messages/MMgrOpen.h b/src/messages/MMgrOpen.h new file mode 100644 index 00000000..754daf7d --- /dev/null +++ b/src/messages/MMgrOpen.h @@ -0,0 +1,95 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 John Spray <john.spray@redhat.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + + +#ifndef CEPH_MMGROPEN_H_ +#define CEPH_MMGROPEN_H_ + +#include "msg/Message.h" + +class MMgrOpen : public MessageInstance<MMgrOpen> { +public: + friend factory; +private: + + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + +public: + + std::string daemon_name; + std::string service_name; // optional; otherwise infer from entity type + + bool service_daemon = false; + std::map<std::string,std::string> daemon_metadata; + std::map<std::string,std::string> daemon_status; + + // encode map<string,map<int32_t,string>> of current config + bufferlist config_bl; + + // encode map<string,string> of compiled-in defaults + bufferlist config_defaults_bl; + + void decode_payload() override + { + auto p = payload.cbegin(); + decode(daemon_name, p); + if (header.version >= 2) { + decode(service_name, p); + decode(service_daemon, p); + if (service_daemon) { + decode(daemon_metadata, p); + decode(daemon_status, p); + } + } + if (header.version >= 3) { + decode(config_bl, p); + decode(config_defaults_bl, p); + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(daemon_name, payload); + encode(service_name, payload); + encode(service_daemon, payload); + if (service_daemon) { + encode(daemon_metadata, payload); + encode(daemon_status, payload); + } + encode(config_bl, payload); + encode(config_defaults_bl, payload); + } + + std::string_view get_type_name() const override { return "mgropen"; } + void print(ostream& out) const override { + out << get_type_name() << "("; + if (service_name.length()) { + out << service_name; + } else { + out << ceph_entity_type_name(get_source().type()); + } + out << "." << daemon_name; + if (service_daemon) { + out << " daemon"; + } + out << ")"; + } + + MMgrOpen() + : MessageInstance(MSG_MGR_OPEN, HEAD_VERSION, COMPAT_VERSION) + {} +}; + +#endif + diff --git a/src/messages/MMgrReport.h b/src/messages/MMgrReport.h new file mode 100644 index 00000000..e9887117 --- /dev/null +++ b/src/messages/MMgrReport.h @@ -0,0 +1,186 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 John Spray <john.spray@redhat.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + + +#ifndef CEPH_MMGRREPORT_H_ +#define CEPH_MMGRREPORT_H_ + +#include <boost/optional.hpp> + +#include "msg/Message.h" +#include "mgr/OSDPerfMetricTypes.h" + +#include "common/perf_counters.h" +#include "mgr/DaemonHealthMetric.h" + +class PerfCounterType +{ +public: + std::string path; + std::string description; + std::string nick; + enum perfcounter_type_d type; + + // For older clients that did not send priority, pretend everything + // is "useful" so that mgr plugins filtering on prio will get some + // data (albeit probably more than they wanted) + uint8_t priority = PerfCountersBuilder::PRIO_USEFUL; + enum unit_t unit; + + void encode(bufferlist &bl) const + { + // TODO: decide whether to drop the per-type + // encoding here, we could rely on the MgrReport + // verisoning instead. + ENCODE_START(3, 1, bl); + encode(path, bl); + encode(description, bl); + encode(nick, bl); + static_assert(sizeof(type) == 1, "perfcounter_type_d must be one byte"); + encode((uint8_t)type, bl); + encode(priority, bl); + encode((uint8_t)unit, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::const_iterator &p) + { + DECODE_START(3, p); + decode(path, p); + decode(description, p); + decode(nick, p); + uint8_t raw_type; + decode(raw_type, p); + type = (enum perfcounter_type_d)raw_type; + if (struct_v >= 2) { + decode(priority, p); + } + if (struct_v >= 3) { + uint8_t raw_unit; + decode(raw_unit, p); + unit = (enum unit_t)raw_unit; + } + DECODE_FINISH(p); + } +}; +WRITE_CLASS_ENCODER(PerfCounterType) + +class MMgrReport : public MessageInstance<MMgrReport> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 8; + static constexpr int COMPAT_VERSION = 1; + +public: + /** + * Client is responsible for remembering whether it has introduced + * each perf counter to the server. When first sending a particular + * counter, it must inline the counter's schema here. + */ + std::vector<PerfCounterType> declare_types; + std::vector<std::string> undeclare_types; + + // For all counters present, sorted by idx, output + // as many bytes as are needed to represent them + + // Decode: iterate over the types we know about, sorted by idx, + // and use the current type's type to decide how to decode + // the next bytes from the bufferlist. + bufferlist packed; + + std::string daemon_name; + std::string service_name; // optional; otherwise infer from entity type + + // for service registration + boost::optional<std::map<std::string,std::string>> daemon_status; + boost::optional<std::map<std::string,std::string>> task_status; + + std::vector<DaemonHealthMetric> daemon_health_metrics; + + // encode map<string,map<int32_t,string>> of current config + bufferlist config_bl; + + std::map<OSDPerfMetricQuery, OSDPerfMetricReport> osd_perf_metric_reports; + + void decode_payload() override + { + auto p = payload.cbegin(); + decode(daemon_name, p); + decode(declare_types, p); + decode(packed, p); + if (header.version >= 2) + decode(undeclare_types, p); + if (header.version >= 3) { + decode(service_name, p); + decode(daemon_status, p); + } + if (header.version >= 5) { + decode(daemon_health_metrics, p); + } + if (header.version >= 6) { + decode(config_bl, p); + } + if (header.version >= 7) { + decode(osd_perf_metric_reports, p); + } + if (header.version >= 8) { + decode(task_status, p); + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(daemon_name, payload); + encode(declare_types, payload); + encode(packed, payload); + encode(undeclare_types, payload); + encode(service_name, payload); + encode(daemon_status, payload); + encode(daemon_health_metrics, payload); + encode(config_bl, payload); + encode(osd_perf_metric_reports, payload); + encode(task_status, payload); + } + + std::string_view get_type_name() const override { return "mgrreport"; } + void print(ostream& out) const override { + out << get_type_name() << "("; + if (service_name.length()) { + out << service_name; + } else { + out << ceph_entity_type_name(get_source().type()); + } + out << "." << daemon_name + << " +" << declare_types.size() + << "-" << undeclare_types.size() + << " packed " << packed.length(); + if (daemon_status) { + out << " status=" << daemon_status->size(); + } + if (!daemon_health_metrics.empty()) { + out << " daemon_metrics=" << daemon_health_metrics.size(); + } + if (task_status) { + out << " task_status=" << task_status->size(); + } + out << ")"; + } + + MMgrReport() + : MessageInstance(MSG_MGR_REPORT, HEAD_VERSION, COMPAT_VERSION) + {} +}; + +#endif + diff --git a/src/messages/MMonCommand.h b/src/messages/MMonCommand.h new file mode 100644 index 00000000..18900832 --- /dev/null +++ b/src/messages/MMonCommand.h @@ -0,0 +1,81 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONCOMMAND_H +#define CEPH_MMONCOMMAND_H + +#include "common/cmdparse.h" +#include "messages/PaxosServiceMessage.h" + +#include <vector> +#include <string> + +class MMonCommand : public MessageInstance<MMonCommand, PaxosServiceMessage> { +public: + friend factory; + + uuid_d fsid; + std::vector<std::string> cmd; + + MMonCommand() : MessageInstance(MSG_MON_COMMAND, 0) {} + MMonCommand(const uuid_d &f) + : MessageInstance(MSG_MON_COMMAND, 0), + fsid(f) + { } + +private: + ~MMonCommand() override {} + +public: + std::string_view get_type_name() const override { return "mon_command"; } + void print(ostream& o) const override { + cmdmap_t cmdmap; + stringstream ss; + string prefix; + cmdmap_from_json(cmd, &cmdmap, ss); + cmd_getval(g_ceph_context, cmdmap, "prefix", prefix); + // Some config values contain sensitive data, so don't log them + o << "mon_command("; + if (prefix == "config set") { + string name; + cmd_getval(g_ceph_context, cmdmap, "name", name); + o << "[{prefix=" << prefix << ", name=" << name << "}]"; + } else if (prefix == "config-key set") { + string key; + cmd_getval(g_ceph_context, cmdmap, "key", key); + o << "[{prefix=" << prefix << ", key=" << key << "}]"; + } else { + for (unsigned i=0; i<cmd.size(); i++) { + if (i) o << ' '; + o << cmd[i]; + } + } + o << " v " << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(cmd, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(cmd, p); + } +}; + +#endif diff --git a/src/messages/MMonCommandAck.h b/src/messages/MMonCommandAck.h new file mode 100644 index 00000000..7802e6e0 --- /dev/null +++ b/src/messages/MMonCommandAck.h @@ -0,0 +1,79 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONCOMMANDACK_H +#define CEPH_MMONCOMMANDACK_H + +#include "common/cmdparse.h" +#include "messages/PaxosServiceMessage.h" + +class MMonCommandAck : public MessageInstance<MMonCommandAck, PaxosServiceMessage> { +public: + friend factory; + + vector<string> cmd; + errorcode32_t r; + string rs; + + MMonCommandAck() : MessageInstance(MSG_MON_COMMAND_ACK, 0) {} + MMonCommandAck(vector<string>& c, int _r, string s, version_t v) : + MessageInstance(MSG_MON_COMMAND_ACK, v), + cmd(c), r(_r), rs(s) { } +private: + ~MMonCommandAck() override {} + +public: + std::string_view get_type_name() const override { return "mon_command"; } + void print(ostream& o) const override { + cmdmap_t cmdmap; + stringstream ss; + string prefix; + cmdmap_from_json(cmd, &cmdmap, ss); + cmd_getval(g_ceph_context, cmdmap, "prefix", prefix); + // Some config values contain sensitive data, so don't log them + o << "mon_command_ack("; + if (prefix == "config set") { + string name; + cmd_getval(g_ceph_context, cmdmap, "name", name); + o << "[{prefix=" << prefix + << ", name=" << name << "}]" + << "=" << r << " " << rs << " v" << version << ")"; + } else if (prefix == "config-key set") { + string key; + cmd_getval(g_ceph_context, cmdmap, "key", key); + o << "[{prefix=" << prefix << ", key=" << key << "}]" + << "=" << r << " " << rs << " v" << version << ")"; + } else { + o << cmd; + } + o << "=" << r << " " << rs << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(r, payload); + encode(rs, payload); + encode(cmd, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(r, p); + decode(rs, p); + decode(cmd, p); + } +}; + +#endif diff --git a/src/messages/MMonElection.h b/src/messages/MMonElection.h new file mode 100644 index 00000000..0114ea12 --- /dev/null +++ b/src/messages/MMonElection.h @@ -0,0 +1,132 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMONELECTION_H +#define CEPH_MMONELECTION_H + +#include "msg/Message.h" +#include "mon/MonMap.h" +#include "mon/mon_types.h" + +class MMonElection : public MessageInstance<MMonElection> { +public: + friend factory; + +private: + static constexpr int HEAD_VERSION = 8; + static constexpr int COMPAT_VERSION = 5; + +public: + static constexpr int OP_PROPOSE = 1; + static constexpr int OP_ACK = 2; + static constexpr int OP_NAK = 3; + static constexpr int OP_VICTORY = 4; + static const char *get_opname(int o) { + switch (o) { + case OP_PROPOSE: return "propose"; + case OP_ACK: return "ack"; + case OP_NAK: return "nak"; + case OP_VICTORY: return "victory"; + default: ceph_abort(); return 0; + } + } + + uuid_d fsid; + int32_t op; + epoch_t epoch; + bufferlist monmap_bl; + set<int32_t> quorum; + uint64_t quorum_features; + mon_feature_t mon_features; + uint8_t mon_release = 0; + bufferlist sharing_bl; + map<string,string> metadata; + + MMonElection() : MessageInstance(MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION), + op(0), epoch(0), + quorum_features(0), + mon_features(0) + { } + + MMonElection(int o, epoch_t e, MonMap *m) + : MessageInstance(MSG_MON_ELECTION, HEAD_VERSION, COMPAT_VERSION), + fsid(m->fsid), op(o), epoch(e), + quorum_features(0), + mon_features(0) + { + // encode using full feature set; we will reencode for dest later, + // if necessary + m->encode(monmap_bl, CEPH_FEATURES_ALL); + } +private: + ~MMonElection() override {} + +public: + std::string_view get_type_name() const override { return "election"; } + void print(ostream& out) const override { + out << "election(" << fsid << " " << get_opname(op) + << " rel " << (int)mon_release << " e" << epoch << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + if (monmap_bl.length() && (features != CEPH_FEATURES_ALL)) { + // reencode old-format monmap + MonMap t; + t.decode(monmap_bl); + monmap_bl.clear(); + t.encode(monmap_bl, features); + } + + encode(fsid, payload); + encode(op, payload); + encode(epoch, payload); + encode(monmap_bl, payload); + encode(quorum, payload); + encode(quorum_features, payload); + encode((version_t)0, payload); // defunct + encode((version_t)0, payload); // defunct + encode(sharing_bl, payload); + encode(mon_features, payload); + encode(metadata, payload); + encode(mon_release, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(op, p); + decode(epoch, p); + decode(monmap_bl, p); + decode(quorum, p); + decode(quorum_features, p); + { + version_t v; // defunct fields from old encoding + decode(v, p); + decode(v, p); + } + decode(sharing_bl, p); + if (header.version >= 6) + decode(mon_features, p); + if (header.version >= 7) + decode(metadata, p); + if (header.version >= 8) + decode(mon_release, p); + else + mon_release = infer_ceph_release_from_mon_features(mon_features); + } + +}; + +#endif diff --git a/src/messages/MMonGetMap.h b/src/messages/MMonGetMap.h new file mode 100644 index 00000000..99950ef4 --- /dev/null +++ b/src/messages/MMonGetMap.h @@ -0,0 +1,37 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONGETMAP_H +#define CEPH_MMONGETMAP_H + +#include "msg/Message.h" + +#include "include/types.h" + +class MMonGetMap : public MessageInstance<MMonGetMap> { +public: + friend factory; + + MMonGetMap() : MessageInstance(CEPH_MSG_MON_GET_MAP) { } +private: + ~MMonGetMap() override {} + +public: + std::string_view get_type_name() const override { return "mon_getmap"; } + + void encode_payload(uint64_t features) override { } + void decode_payload() override { } +}; + +#endif diff --git a/src/messages/MMonGetOSDMap.h b/src/messages/MMonGetOSDMap.h new file mode 100644 index 00000000..926a6083 --- /dev/null +++ b/src/messages/MMonGetOSDMap.h @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2014 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONGETOSDMAP_H +#define CEPH_MMONGETOSDMAP_H + +#include "msg/Message.h" + +#include "include/types.h" + +class MMonGetOSDMap : public MessageInstance<MMonGetOSDMap, PaxosServiceMessage> { +public: + friend factory; +private: + + epoch_t full_first, full_last; + epoch_t inc_first, inc_last; + +public: + MMonGetOSDMap() + : MessageInstance(CEPH_MSG_MON_GET_OSDMAP, 0), + full_first(0), + full_last(0), + inc_first(0), + inc_last(0) { } +private: + ~MMonGetOSDMap() override {} + +public: + void request_full(epoch_t first, epoch_t last) { + ceph_assert(last >= first); + full_first = first; + full_last = last; + } + void request_inc(epoch_t first, epoch_t last) { + ceph_assert(last >= first); + inc_first = first; + inc_last = last; + } + epoch_t get_full_first() const { + return full_first; + } + epoch_t get_full_last() const { + return full_last; + } + epoch_t get_inc_first() const { + return inc_first; + } + epoch_t get_inc_last() const { + return inc_last; + } + + std::string_view get_type_name() const override { return "mon_get_osdmap"; } + void print(ostream& out) const override { + out << "mon_get_osdmap("; + if (full_first && full_last) + out << "full " << full_first << "-" << full_last; + if (inc_first && inc_last) + out << " inc" << inc_first << "-" << inc_last; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(full_first, payload); + encode(full_last, payload); + encode(inc_first, payload); + encode(inc_last, payload); + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + paxos_decode(p); + decode(full_first, p); + decode(full_last, p); + decode(inc_first, p); + decode(inc_last, p); + } +}; + +#endif diff --git a/src/messages/MMonGetVersion.h b/src/messages/MMonGetVersion.h new file mode 100644 index 00000000..84a88d26 --- /dev/null +++ b/src/messages/MMonGetVersion.h @@ -0,0 +1,61 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONGETVERSION_H +#define CEPH_MMONGETVERSION_H + +#include "msg/Message.h" + +#include "include/types.h" + +/* + * This message is sent to the monitors to verify that the client's + * version of the map(s) is the latest available. For example, this + * can be used to determine whether a pool actually does not exist, or + * if it may have been created but the map was not received yet. + */ +class MMonGetVersion : public MessageInstance<MMonGetVersion> { +public: + friend factory; + + MMonGetVersion() : MessageInstance(CEPH_MSG_MON_GET_VERSION) {} + + std::string_view get_type_name() const override { + return "mon_get_version"; + } + + void print(ostream& o) const override { + o << "mon_get_version(what=" << what << " handle=" << handle << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(handle, payload); + encode(what, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(handle, p); + decode(what, p); + } + + ceph_tid_t handle = 0; + string what; + +private: + ~MMonGetVersion() override {} +}; + +#endif diff --git a/src/messages/MMonGetVersionReply.h b/src/messages/MMonGetVersionReply.h new file mode 100644 index 00000000..768ea18c --- /dev/null +++ b/src/messages/MMonGetVersionReply.h @@ -0,0 +1,67 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONGETVERSIONREPLY_H +#define CEPH_MMONGETVERSIONREPLY_H + +#include "msg/Message.h" + +#include "include/types.h" + +/* + * This message is sent from the monitors to clients in response to a + * MMonGetVersion. The latest version of the requested thing is sent + * back. + */ +class MMonGetVersionReply : public MessageInstance<MMonGetVersionReply> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + +public: + MMonGetVersionReply() : MessageInstance(CEPH_MSG_MON_GET_VERSION_REPLY, HEAD_VERSION) { } + + std::string_view get_type_name() const override { + return "mon_get_version_reply"; + } + + void print(ostream& o) const override { + o << "mon_get_version_reply(handle=" << handle << " version=" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(handle, payload); + encode(version, payload); + encode(oldest_version, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(handle, p); + decode(version, p); + if (header.version >= 2) + decode(oldest_version, p); + } + + ceph_tid_t handle = 0; + version_t version = 0; + version_t oldest_version = 0; + +private: + ~MMonGetVersionReply() override {} +}; + +#endif diff --git a/src/messages/MMonGlobalID.h b/src/messages/MMonGlobalID.h new file mode 100644 index 00000000..79535a6b --- /dev/null +++ b/src/messages/MMonGlobalID.h @@ -0,0 +1,47 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONGLOBALID_H +#define CEPH_MMONGLOBALID_H + +#include "messages/PaxosServiceMessage.h" + +class MMonGlobalID : public MessageInstance<MMonGlobalID, PaxosServiceMessage> { +public: + friend factory; + + uint64_t old_max_id; + MMonGlobalID() : MessageInstance(MSG_MON_GLOBAL_ID, 0), old_max_id(0) { } +private: + ~MMonGlobalID() override {} + +public: + std::string_view get_type_name() const override { return "global_id"; } + void print(ostream& out) const override { + out << "global_id (" << old_max_id << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(old_max_id, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(old_max_id, payload); + } +}; + +#endif diff --git a/src/messages/MMonHealth.h b/src/messages/MMonHealth.h new file mode 100644 index 00000000..1d837184 --- /dev/null +++ b/src/messages/MMonHealth.h @@ -0,0 +1,65 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2012 Inktank, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#ifndef CEPH_MMON_HEALTH_H +#define CEPH_MMON_HEALTH_H + +#include "msg/Message.h" +#include "messages/MMonQuorumService.h" +#include "mon/mon_types.h" + +class MMonHealth : public MessageInstance<MMonHealth, MMonQuorumService> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + + int service_type = 0; + int service_op = 0; + + // service specific data + DataStats data_stats; + + MMonHealth() : MessageInstance(MSG_MON_HEALTH, HEAD_VERSION) { } + +private: + ~MMonHealth() override { } + +public: + std::string_view get_type_name() const override { return "mon_health"; } + void print(ostream &o) const override { + o << "mon_health(" + << " e " << get_epoch() + << " r " << get_round() + << " )"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + service_decode(p); + decode(service_type, p); + decode(service_op, p); + decode(data_stats, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + service_encode(); + encode(service_type, payload); + encode(service_op, payload); + encode(data_stats, payload); + } + +}; + +#endif /* CEPH_MMON_HEALTH_H */ diff --git a/src/messages/MMonHealthChecks.h b/src/messages/MMonHealthChecks.h new file mode 100644 index 00000000..e9e611b1 --- /dev/null +++ b/src/messages/MMonHealthChecks.h @@ -0,0 +1,50 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MMON_HEALTH_CHECKS_H +#define CEPH_MMON_HEALTH_CHECKS_H + +#include "messages/PaxosServiceMessage.h" +#include "mon/health_check.h" + +class MMonHealthChecks : public MessageInstance<MMonHealthChecks, PaxosServiceMessage> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + health_check_map_t health_checks; + + MMonHealthChecks() + : MessageInstance(MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION) { + } + MMonHealthChecks(health_check_map_t& m) + : MessageInstance(MSG_MON_HEALTH_CHECKS, HEAD_VERSION, COMPAT_VERSION), + health_checks(m) { + } + +private: + ~MMonHealthChecks() override { } + +public: + std::string_view get_type_name() const override { return "mon_health_checks"; } + void print(ostream &o) const override { + o << "mon_health_checks(" << health_checks.checks.size() << " checks)"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(health_checks, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(health_checks, payload); + } + +}; + +#endif diff --git a/src/messages/MMonJoin.h b/src/messages/MMonJoin.h new file mode 100644 index 00000000..15d8ac94 --- /dev/null +++ b/src/messages/MMonJoin.h @@ -0,0 +1,79 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONJOIN_H +#define CEPH_MMONJOIN_H + +#include "messages/PaxosServiceMessage.h" + +#include <vector> +using std::vector; + +class MMonJoin : public MessageInstance<MMonJoin, PaxosServiceMessage> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + + uuid_d fsid; + string name; + entity_addrvec_t addrs; + + MMonJoin() : MessageInstance(MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION) {} + MMonJoin(uuid_d &f, string n, const entity_addrvec_t& av) + : MessageInstance(MSG_MON_JOIN, 0, HEAD_VERSION, COMPAT_VERSION), + fsid(f), name(n), addrs(av) + { } + +private: + ~MMonJoin() override {} + +public: + std::string_view get_type_name() const override { return "mon_join"; } + void print(ostream& o) const override { + o << "mon_join(" << name << " " << addrs << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(name, payload); + if (HAVE_FEATURE(features, SERVER_NAUTILUS)) { + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(addrs, payload, features); + } else { + header.version = 1; + header.compat_version = 1; + encode(addrs.legacy_addr(), payload, features); + } + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(name, p); + if (header.version == 1) { + entity_addr_t addr; + decode(addr, p); + addrs = entity_addrvec_t(addr); + } else { + decode(addrs, p); + } + } +}; + +#endif diff --git a/src/messages/MMonMap.h b/src/messages/MMonMap.h new file mode 100644 index 00000000..57034b8b --- /dev/null +++ b/src/messages/MMonMap.h @@ -0,0 +1,58 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONMAP_H +#define CEPH_MMONMAP_H + +#include "include/ceph_features.h" +#include "msg/Message.h" +#include "mon/MonMap.h" + +class MMonMap : public MessageInstance<MMonMap> { +public: + friend factory; + + bufferlist monmapbl; + + MMonMap() : MessageInstance(CEPH_MSG_MON_MAP) { } + explicit MMonMap(bufferlist &bl) : MessageInstance(CEPH_MSG_MON_MAP) { + monmapbl.claim(bl); + } +private: + ~MMonMap() override {} + +public: + std::string_view get_type_name() const override { return "mon_map"; } + + void encode_payload(uint64_t features) override { + if (monmapbl.length() && + ((features & CEPH_FEATURE_MONENC) == 0 || + (features & CEPH_FEATURE_MSG_ADDR2) == 0)) { + // reencode old-format monmap + MonMap t; + t.decode(monmapbl); + monmapbl.clear(); + t.encode(monmapbl, features); + } + + using ceph::encode; + encode(monmapbl, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(monmapbl, p); + } +}; + +#endif diff --git a/src/messages/MMonMetadata.h b/src/messages/MMonMetadata.h new file mode 100644 index 00000000..70c517b4 --- /dev/null +++ b/src/messages/MMonMetadata.h @@ -0,0 +1,55 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2015 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONMETADATA_H +#define CEPH_MMONMETADATA_H + +#include "mon/mon_types.h" +#include "msg/Message.h" + +class MMonMetadata : public MessageInstance<MMonMetadata> { +public: + friend factory; + + Metadata data; + +private: + static constexpr int HEAD_VERSION = 1; + ~MMonMetadata() override {} + +public: + MMonMetadata() : + MessageInstance(CEPH_MSG_MON_METADATA) + {} + MMonMetadata(const Metadata& metadata) : + MessageInstance(CEPH_MSG_MON_METADATA, HEAD_VERSION), + data(metadata) + {} + + std::string_view get_type_name() const override { + return "mon_metadata"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(data, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(data, p); + } +}; + +#endif diff --git a/src/messages/MMonMgrReport.h b/src/messages/MMonMgrReport.h new file mode 100644 index 00000000..097fa014 --- /dev/null +++ b/src/messages/MMonMgrReport.h @@ -0,0 +1,87 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 Greg Farnum/Red Hat <gfarnum@redhat.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONMGRREPORT_H +#define CEPH_MMONMGRREPORT_H + +#include "messages/PaxosServiceMessage.h" +#include "include/types.h" +#include "include/health.h" +#include "mon/health_check.h" +#include "mon/PGMap.h" + +class MMonMgrReport + : public MessageInstance<MMonMgrReport, PaxosServiceMessage> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + // PGMapDigest is in data payload + health_check_map_t health_checks; + bufferlist service_map_bl; // encoded ServiceMap + std::map<std::string,ProgressEvent> progress_events; + + MMonMgrReport() + : MessageInstance(MSG_MON_MGR_REPORT, 0, HEAD_VERSION, COMPAT_VERSION) + {} +private: + ~MMonMgrReport() override {} + +public: + std::string_view get_type_name() const override { return "monmgrreport"; } + + void print(ostream& out) const override { + out << get_type_name() << "(" << health_checks.checks.size() << " checks, " + << progress_events.size() << " progress events)"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(health_checks, payload); + encode(service_map_bl, payload); + encode(progress_events, payload); + + if (!HAVE_FEATURE(features, SERVER_NAUTILUS) || + !HAVE_FEATURE(features, SERVER_MIMIC)) { + // PGMapDigest had a backwards-incompatible change between + // luminous and mimic, and conditionally encodes based on + // provided features, so reencode the one in our data payload. + // The mgr isn't able to do this at the time the encoded + // PGMapDigest is constructed because we don't know which mon we + // will target. Note that this only triggers if the user + // upgrades ceph-mgr before ceph-mon (tsk tsk). + PGMapDigest digest; + auto p = data.cbegin(); + decode(digest, p); + bufferlist bl; + encode(digest, bl, features); + set_data(bl); + } + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(health_checks, p); + decode(service_map_bl, p); + if (header.version >= 2) { + decode(progress_events, p); + } + } +}; + +#endif diff --git a/src/messages/MMonPaxos.h b/src/messages/MMonPaxos.h new file mode 100644 index 00000000..b0fc1f70 --- /dev/null +++ b/src/messages/MMonPaxos.h @@ -0,0 +1,133 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMONPAXOS_H +#define CEPH_MMONPAXOS_H + +#include "messages/PaxosServiceMessage.h" +#include "mon/mon_types.h" +#include "include/ceph_features.h" + +class MMonPaxos : public MessageInstance<MMonPaxos> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 3; + + public: + // op types + static constexpr int OP_COLLECT = 1; // proposer: propose round + static constexpr int OP_LAST = 2; // voter: accept proposed round + static constexpr int OP_BEGIN = 3; // proposer: value proposed for this round + static constexpr int OP_ACCEPT = 4; // voter: accept propsed value + static constexpr int OP_COMMIT = 5; // proposer: notify learners of agreed value + static constexpr int OP_LEASE = 6; // leader: extend peon lease + static constexpr int OP_LEASE_ACK = 7; // peon: lease ack + static const char *get_opname(int op) { + switch (op) { + case OP_COLLECT: return "collect"; + case OP_LAST: return "last"; + case OP_BEGIN: return "begin"; + case OP_ACCEPT: return "accept"; + case OP_COMMIT: return "commit"; + case OP_LEASE: return "lease"; + case OP_LEASE_ACK: return "lease_ack"; + default: ceph_abort(); return 0; + } + } + + epoch_t epoch = 0; // monitor epoch + __s32 op = 0; // paxos op + + version_t first_committed = 0; // i've committed to + version_t last_committed = 0; // i've committed to + version_t pn_from = 0; // i promise to accept after + version_t pn = 0; // with with proposal + version_t uncommitted_pn = 0; // previous pn, if we are a LAST with an uncommitted value + utime_t lease_timestamp; + utime_t sent_timestamp; + + version_t latest_version = 0; + bufferlist latest_value; + + map<version_t,bufferlist> values; + + bufferlist feature_map; + + MMonPaxos() : MessageInstance(MSG_MON_PAXOS, HEAD_VERSION, COMPAT_VERSION) { } + MMonPaxos(epoch_t e, int o, utime_t now) : + MessageInstance(MSG_MON_PAXOS, HEAD_VERSION, COMPAT_VERSION), + epoch(e), + op(o), + first_committed(0), last_committed(0), pn_from(0), pn(0), uncommitted_pn(0), + sent_timestamp(now), + latest_version(0) { + } + +private: + ~MMonPaxos() override {} + +public: + std::string_view get_type_name() const override { return "paxos"; } + + void print(ostream& out) const override { + out << "paxos(" << get_opname(op) + << " lc " << last_committed + << " fc " << first_committed + << " pn " << pn << " opn " << uncommitted_pn; + if (latest_version) + out << " latest " << latest_version << " (" << latest_value.length() << " bytes)"; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + header.version = HEAD_VERSION; + encode(epoch, payload); + encode(op, payload); + encode(first_committed, payload); + encode(last_committed, payload); + encode(pn_from, payload); + encode(pn, payload); + encode(uncommitted_pn, payload); + encode(lease_timestamp, payload); + encode(sent_timestamp, payload); + encode(latest_version, payload); + encode(latest_value, payload); + encode(values, payload); + encode(feature_map, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(op, p); + decode(first_committed, p); + decode(last_committed, p); + decode(pn_from, p); + decode(pn, p); + decode(uncommitted_pn, p); + decode(lease_timestamp, p); + decode(sent_timestamp, p); + decode(latest_version, p); + decode(latest_value, p); + decode(values, p); + if (header.version >= 4) { + decode(feature_map, p); + } + } +}; + +#endif diff --git a/src/messages/MMonProbe.h b/src/messages/MMonProbe.h new file mode 100644 index 00000000..8b878dfd --- /dev/null +++ b/src/messages/MMonProbe.h @@ -0,0 +1,142 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MMONPROBE_H +#define CEPH_MMONPROBE_H + +#include "include/ceph_features.h" +#include "msg/Message.h" +#include "mon/MonMap.h" + +class MMonProbe : public MessageInstance<MMonProbe> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 7; + static constexpr int COMPAT_VERSION = 5; + + enum { + OP_PROBE = 1, + OP_REPLY = 2, + OP_SLURP = 3, + OP_SLURP_LATEST = 4, + OP_DATA = 5, + OP_MISSING_FEATURES = 6, + }; + + static const char *get_opname(int o) { + switch (o) { + case OP_PROBE: return "probe"; + case OP_REPLY: return "reply"; + case OP_SLURP: return "slurp"; + case OP_SLURP_LATEST: return "slurp_latest"; + case OP_DATA: return "data"; + case OP_MISSING_FEATURES: return "missing_features"; + default: ceph_abort(); return 0; + } + } + + uuid_d fsid; + int32_t op = 0; + string name; + set<int32_t> quorum; + bufferlist monmap_bl; + version_t paxos_first_version = 0; + version_t paxos_last_version = 0; + bool has_ever_joined = 0; + uint64_t required_features = 0; + uint8_t mon_release = 0; + + MMonProbe() + : MessageInstance(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION) {} + MMonProbe(const uuid_d& f, int o, const string& n, bool hej, uint8_t mr) + : MessageInstance(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION), + fsid(f), + op(o), + name(n), + paxos_first_version(0), + paxos_last_version(0), + has_ever_joined(hej), + required_features(0), + mon_release(mr) {} +private: + ~MMonProbe() override {} + +public: + std::string_view get_type_name() const override { return "mon_probe"; } + void print(ostream& out) const override { + out << "mon_probe(" << get_opname(op) << " " << fsid << " name " << name; + if (quorum.size()) + out << " quorum " << quorum; + if (op == OP_REPLY) { + out << " paxos(" + << " fc " << paxos_first_version + << " lc " << paxos_last_version + << " )"; + } + if (!has_ever_joined) + out << " new"; + if (required_features) + out << " required_features " << required_features; + if (mon_release) + out << " mon_release " << (int)mon_release; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + if (monmap_bl.length() && + ((features & CEPH_FEATURE_MONENC) == 0 || + (features & CEPH_FEATURE_MSG_ADDR2) == 0)) { + // reencode old-format monmap + MonMap t; + t.decode(monmap_bl); + monmap_bl.clear(); + t.encode(monmap_bl, features); + } + + encode(fsid, payload); + encode(op, payload); + encode(name, payload); + encode(quorum, payload); + encode(monmap_bl, payload); + encode(has_ever_joined, payload); + encode(paxos_first_version, payload); + encode(paxos_last_version, payload); + encode(required_features, payload); + encode(mon_release, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(op, p); + decode(name, p); + decode(quorum, p); + decode(monmap_bl, p); + decode(has_ever_joined, p); + decode(paxos_first_version, p); + decode(paxos_last_version, p); + if (header.version >= 6) + decode(required_features, p); + else + required_features = 0; + if (header.version >= 7) + decode(mon_release, p); + else + mon_release = 0; + } +}; + +#endif diff --git a/src/messages/MMonQuorumService.h b/src/messages/MMonQuorumService.h new file mode 100644 index 00000000..7ad1eeb5 --- /dev/null +++ b/src/messages/MMonQuorumService.h @@ -0,0 +1,70 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2012 Inktank, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#ifndef CEPH_MMON_QUORUM_SERVICE_H +#define CEPH_MMON_QUORUM_SERVICE_H + +#include "msg/Message.h" + +class MMonQuorumService : public MessageSubType<MMonQuorumService> { +public: + epoch_t epoch = 0; + version_t round = 0; + +protected: +template<typename... Args> + MMonQuorumService(Args&&... args) : MessageSubType(std::forward<Args>(args)...) {} + + ~MMonQuorumService() override { } + +public: + + void set_epoch(epoch_t e) { + epoch = e; + } + + void set_round(version_t r) { + round = r; + } + + epoch_t get_epoch() const { + return epoch; + } + + version_t get_round() const { + return round; + } + + void service_encode() { + using ceph::encode; + encode(epoch, payload); + encode(round, payload); + } + + void service_decode(bufferlist::const_iterator &p) { + decode(epoch, p); + decode(round, p); + } + + void encode_payload(uint64_t features) override { + ceph_abort_msg("MMonQuorumService message must always be a base class"); + } + + void decode_payload() override { + ceph_abort_msg("MMonQuorumService message must always be a base class"); + } + + std::string_view get_type_name() const override { return "quorum_service"; } +}; + +#endif /* CEPH_MMON_QUORUM_SERVICE_H */ diff --git a/src/messages/MMonScrub.h b/src/messages/MMonScrub.h new file mode 100644 index 00000000..8924bad9 --- /dev/null +++ b/src/messages/MMonScrub.h @@ -0,0 +1,90 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2013 Inktank, Inc. +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#ifndef CEPH_MMONSCRUB_H +#define CEPH_MMONSCRUB_H + +#include "msg/Message.h" +#include "mon/mon_types.h" + +class MMonScrub : public MessageInstance<MMonScrub> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + +public: + typedef enum { + OP_SCRUB = 1, // leader->peon: scrub (a range of) keys + OP_RESULT = 2, // peon->leader: result of a scrub + } op_type_t; + + static const char *get_opname(op_type_t op) { + switch (op) { + case OP_SCRUB: return "scrub"; + case OP_RESULT: return "result"; + default: ceph_abort_msg("unknown op type"); return NULL; + } + } + + op_type_t op = OP_SCRUB; + version_t version = 0; + ScrubResult result; + int32_t num_keys; + pair<string,string> key; + + MMonScrub() + : MessageInstance(MSG_MON_SCRUB, HEAD_VERSION, COMPAT_VERSION), + num_keys(-1) + { } + + MMonScrub(op_type_t op, version_t v, int32_t num_keys) + : MessageInstance(MSG_MON_SCRUB, HEAD_VERSION, COMPAT_VERSION), + op(op), version(v), num_keys(num_keys) + { } + + std::string_view get_type_name() const override { return "mon_scrub"; } + + void print(ostream& out) const override { + out << "mon_scrub(" << get_opname((op_type_t)op); + out << " v " << version; + if (op == OP_RESULT) + out << " " << result; + out << " num_keys " << num_keys; + out << " key (" << key << ")"; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + uint8_t o = op; + encode(o, payload); + encode(version, payload); + encode(result, payload); + encode(num_keys, payload); + encode(key, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + uint8_t o; + decode(o, p); + op = (op_type_t)o; + decode(version, p); + decode(result, p); + decode(num_keys, p); + decode(key, p); + } +}; + +#endif /* CEPH_MMONSCRUB_H */ diff --git a/src/messages/MMonSubscribe.h b/src/messages/MMonSubscribe.h new file mode 100644 index 00000000..bbc88334 --- /dev/null +++ b/src/messages/MMonSubscribe.h @@ -0,0 +1,105 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONSUBSCRIBE_H +#define CEPH_MMONSUBSCRIBE_H + +#include "msg/Message.h" +#include "include/ceph_features.h" + +/* + * compatibility with old crap + */ +struct ceph_mon_subscribe_item_old { + ceph_le64 unused; + ceph_le64 have; + __u8 onetime; +} __attribute__ ((packed)); +WRITE_RAW_ENCODER(ceph_mon_subscribe_item_old) + + +class MMonSubscribe : public MessageInstance<MMonSubscribe> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + + string hostname; + map<string, ceph_mon_subscribe_item> what; + + MMonSubscribe() : MessageInstance(CEPH_MSG_MON_SUBSCRIBE, HEAD_VERSION, COMPAT_VERSION) { } +private: + ~MMonSubscribe() override {} + +public: + void sub_want(const char *w, version_t start, unsigned flags) { + what[w].start = start; + what[w].flags = flags; + } + + std::string_view get_type_name() const override { return "mon_subscribe"; } + void print(ostream& o) const override { + o << "mon_subscribe(" << what << ")"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + if (header.version < 2) { + map<string, ceph_mon_subscribe_item_old> oldwhat; + decode(oldwhat, p); + what.clear(); + for (map<string, ceph_mon_subscribe_item_old>::iterator q = oldwhat.begin(); + q != oldwhat.end(); + q++) { + if (q->second.have) + what[q->first].start = q->second.have + 1; + else + what[q->first].start = 0; + what[q->first].flags = 0; + if (q->second.onetime) + what[q->first].flags |= CEPH_SUBSCRIBE_ONETIME; + } + return; + } + decode(what, p); + if (header.version >= 3) { + decode(hostname, p); + } + } + void encode_payload(uint64_t features) override { + using ceph::encode; + if ((features & CEPH_FEATURE_SUBSCRIBE2) == 0) { + header.version = 0; + map<string, ceph_mon_subscribe_item_old> oldwhat; + for (map<string, ceph_mon_subscribe_item>::iterator q = what.begin(); + q != what.end(); + q++) { + if (q->second.start) + // warning: start=1 -> have=0, which was ambiguous + oldwhat[q->first].have = q->second.start - 1; + else + oldwhat[q->first].have = 0; + oldwhat[q->first].onetime = q->second.flags & CEPH_SUBSCRIBE_ONETIME; + } + encode(oldwhat, payload); + return; + } + header.version = HEAD_VERSION; + encode(what, payload); + encode(hostname, payload); + } +}; + +#endif diff --git a/src/messages/MMonSubscribeAck.h b/src/messages/MMonSubscribeAck.h new file mode 100644 index 00000000..087e5069 --- /dev/null +++ b/src/messages/MMonSubscribeAck.h @@ -0,0 +1,53 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MMONSUBSCRIBEACK_H +#define CEPH_MMONSUBSCRIBEACK_H + +#include "msg/Message.h" + +class MMonSubscribeAck : public MessageInstance<MMonSubscribeAck> { +public: + friend factory; + + __u32 interval; + uuid_d fsid; + + MMonSubscribeAck() : MessageInstance(CEPH_MSG_MON_SUBSCRIBE_ACK), + interval(0) { + } + MMonSubscribeAck(uuid_d& f, int i) : MessageInstance(CEPH_MSG_MON_SUBSCRIBE_ACK), + interval(i), fsid(f) { } +private: + ~MMonSubscribeAck() override {} + +public: + std::string_view get_type_name() const override { return "mon_subscribe_ack"; } + void print(ostream& o) const override { + o << "mon_subscribe_ack(" << interval << "s)"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(interval, p); + decode(fsid, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(interval, payload); + encode(fsid, payload); + } +}; + +#endif diff --git a/src/messages/MMonSync.h b/src/messages/MMonSync.h new file mode 100644 index 00000000..a4f82207 --- /dev/null +++ b/src/messages/MMonSync.h @@ -0,0 +1,114 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2012 Inktank, Inc. +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#ifndef CEPH_MMONSYNC_H +#define CEPH_MMONSYNC_H + +#include "msg/Message.h" + +class MMonSync : public MessageInstance<MMonSync> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + +public: + /** + * Operation types + */ + enum { + OP_GET_COOKIE_FULL = 1, // -> start a session (full scan) + OP_GET_COOKIE_RECENT = 2, // -> start a session (only recent paxos events) + OP_COOKIE = 3, // <- pass the iterator cookie, or + OP_GET_CHUNK = 4, // -> get some keys + OP_CHUNK = 5, // <- return some keys + OP_LAST_CHUNK = 6, // <- return the last set of keys + OP_NO_COOKIE = 8, // <- sorry, no cookie + }; + + /** + * Obtain a string corresponding to the operation type @p op + * + * @param op Operation type + * @returns A string + */ + static const char *get_opname(int op) { + switch (op) { + case OP_GET_COOKIE_FULL: return "get_cookie_full"; + case OP_GET_COOKIE_RECENT: return "get_cookie_recent"; + case OP_COOKIE: return "cookie"; + case OP_GET_CHUNK: return "get_chunk"; + case OP_CHUNK: return "chunk"; + case OP_LAST_CHUNK: return "last_chunk"; + case OP_NO_COOKIE: return "no_cookie"; + default: ceph_abort_msg("unknown op type"); return NULL; + } + } + + uint32_t op = 0; + uint64_t cookie = 0; + version_t last_committed = 0; + pair<string,string> last_key; + bufferlist chunk_bl; + entity_inst_t reply_to; + + MMonSync() + : MessageInstance(MSG_MON_SYNC, HEAD_VERSION, COMPAT_VERSION) + { } + + MMonSync(uint32_t op, uint64_t c = 0) + : MessageInstance(MSG_MON_SYNC, HEAD_VERSION, COMPAT_VERSION), + op(op), + cookie(c), + last_committed(0) + { } + + std::string_view get_type_name() const override { return "mon_sync"; } + + void print(ostream& out) const override { + out << "mon_sync(" << get_opname(op); + if (cookie) + out << " cookie " << cookie; + if (last_committed > 0) + out << " lc " << last_committed; + if (chunk_bl.length()) + out << " bl " << chunk_bl.length() << " bytes"; + if (!last_key.first.empty() || !last_key.second.empty()) + out << " last_key " << last_key.first << "," << last_key.second; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(op, payload); + encode(cookie, payload); + encode(last_committed, payload); + encode(last_key.first, payload); + encode(last_key.second, payload); + encode(chunk_bl, payload); + encode(reply_to, payload, features); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(op, p); + decode(cookie, p); + decode(last_committed, p); + decode(last_key.first, p); + decode(last_key.second, p); + decode(chunk_bl, p); + decode(reply_to, p); + } +}; + +#endif /* CEPH_MMONSYNC_H */ diff --git a/src/messages/MNop.h b/src/messages/MNop.h new file mode 100644 index 00000000..452f509c --- /dev/null +++ b/src/messages/MNop.h @@ -0,0 +1,57 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * Portions Copyright (C) 2014 CohortFS, LLC + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MSG_NOP_H +#define CEPH_MSG_NOP_H + +#include "msg/Message.h" +#include "msg/msg_types.h" + +/* + * A message with no (remote) effect. + */ +class MNop : public MessageInstance<MNop> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + __u32 tag; // ignored tag value + + MNop() + : MessageInstance(MSG_NOP, HEAD_VERSION, COMPAT_VERSION) + {} + + ~MNop() {} + + void encode_payload(uint64_t _features) { + using ceph::encode; + encode(tag, payload); + } + + void decode_payload() { + auto p = payload.cbegin(); + decode(tag, p); + } + + std::string_view get_type_name() const { return "MNop"; } + + void print(ostream& out) const { + out << get_type_name() << " "; + } +}; /* MNop */ + +#endif /* CEPH_MSG_NOP_H */ diff --git a/src/messages/MOSDAlive.h b/src/messages/MOSDAlive.h new file mode 100644 index 00000000..47ed5f2a --- /dev/null +++ b/src/messages/MOSDAlive.h @@ -0,0 +1,52 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + + +#ifndef CEPH_MOSDALIVE_H +#define CEPH_MOSDALIVE_H + +#include "messages/PaxosServiceMessage.h" + +class MOSDAlive : public MessageInstance<MOSDAlive, PaxosServiceMessage> { +public: + friend factory; + + epoch_t want = 0; + + MOSDAlive(epoch_t h, epoch_t w) : MessageInstance(MSG_OSD_ALIVE, h), want(w) { } + MOSDAlive() : MessageInstance(MSG_OSD_ALIVE, 0) {} +private: + ~MOSDAlive() override {} + +public: + void encode_payload(uint64_t features) override { + paxos_encode(); + using ceph::encode; + encode(want, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(want, p); + } + + std::string_view get_type_name() const override { return "osd_alive"; } + void print(ostream &out) const override { + out << "osd_alive(want up_thru " << want << " have " << version << ")"; + } + +}; + +#endif diff --git a/src/messages/MOSDBackoff.h b/src/messages/MOSDBackoff.h new file mode 100644 index 00000000..97285420 --- /dev/null +++ b/src/messages/MOSDBackoff.h @@ -0,0 +1,84 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDBACKOFF_H +#define CEPH_MOSDBACKOFF_H + +#include "MOSDFastDispatchOp.h" +#include "osd/osd_types.h" + +class MOSDBackoff : public MessageInstance<MOSDBackoff, MOSDFastDispatchOp> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + spg_t pgid; + epoch_t map_epoch = 0; + uint8_t op = 0; ///< CEPH_OSD_BACKOFF_OP_* + uint64_t id = 0; ///< unique id within this session + hobject_t begin, end; ///< [) range to block, unless ==, block single obj + + spg_t get_spg() const override { + return pgid; + } + epoch_t get_map_epoch() const override { + return map_epoch; + } + + MOSDBackoff() + : MessageInstance(CEPH_MSG_OSD_BACKOFF, HEAD_VERSION, COMPAT_VERSION) {} + MOSDBackoff(spg_t pgid_, epoch_t ep, uint8_t op_, uint64_t id_, + hobject_t begin_, hobject_t end_) + : MessageInstance(CEPH_MSG_OSD_BACKOFF, HEAD_VERSION, COMPAT_VERSION), + pgid(pgid_), + map_epoch(ep), + op(op_), + id(id_), + begin(begin_), + end(end_) { } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(op, payload); + encode(id, payload); + encode(begin, payload); + encode(end, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(op, p); + decode(id, p); + decode(begin, p); + decode(end, p); + } + + std::string_view get_type_name() const override { return "osd_backoff"; } + + void print(ostream& out) const override { + out << "osd_backoff(" << pgid << " " << ceph_osd_backoff_op_name(op) + << " id " << id + << " [" << begin << "," << end << ")" + << " e" << map_epoch << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDBeacon.h b/src/messages/MOSDBeacon.h new file mode 100644 index 00000000..76140119 --- /dev/null +++ b/src/messages/MOSDBeacon.h @@ -0,0 +1,41 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "PaxosServiceMessage.h" + +class MOSDBeacon : public MessageInstance<MOSDBeacon, PaxosServiceMessage> { +public: + friend factory; + + std::vector<pg_t> pgs; + epoch_t min_last_epoch_clean = 0; + + MOSDBeacon() + : MessageInstance(MSG_OSD_BEACON, 0) + {} + MOSDBeacon(epoch_t e, epoch_t min_lec) + : MessageInstance(MSG_OSD_BEACON, e), + min_last_epoch_clean(min_lec) + {} + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(pgs, payload); + encode(min_last_epoch_clean, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(pgs, p); + decode(min_last_epoch_clean, p); + } + std::string_view get_type_name() const override { return "osd_beacon"; } + void print(ostream &out) const { + out << get_type_name() + << "(pgs " << pgs + << " lec " << min_last_epoch_clean + << " v" << version << ")"; + } +}; diff --git a/src/messages/MOSDBoot.h b/src/messages/MOSDBoot.h new file mode 100644 index 00000000..ccd49991 --- /dev/null +++ b/src/messages/MOSDBoot.h @@ -0,0 +1,120 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDBOOT_H +#define CEPH_MOSDBOOT_H + +#include "messages/PaxosServiceMessage.h" + +#include "include/ceph_features.h" +#include "include/types.h" +#include "osd/osd_types.h" + +class MOSDBoot : public MessageInstance<MOSDBoot, PaxosServiceMessage> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 7; + static constexpr int COMPAT_VERSION = 7; + + public: + OSDSuperblock sb; + entity_addrvec_t hb_back_addrs, hb_front_addrs; + entity_addrvec_t cluster_addrs; + epoch_t boot_epoch; // last epoch this daemon was added to the map (if any) + map<string,string> metadata; ///< misc metadata about this osd + uint64_t osd_features; + + MOSDBoot() + : MessageInstance(MSG_OSD_BOOT, 0, HEAD_VERSION, COMPAT_VERSION), + boot_epoch(0), osd_features(0) + { } + MOSDBoot(OSDSuperblock& s, epoch_t e, epoch_t be, + const entity_addrvec_t& hb_back_addr_ref, + const entity_addrvec_t& hb_front_addr_ref, + const entity_addrvec_t& cluster_addr_ref, + uint64_t feat) + : MessageInstance(MSG_OSD_BOOT, e, HEAD_VERSION, COMPAT_VERSION), + sb(s), + hb_back_addrs(hb_back_addr_ref), + hb_front_addrs(hb_front_addr_ref), + cluster_addrs(cluster_addr_ref), + boot_epoch(be), + osd_features(feat) + { } + +private: + ~MOSDBoot() override { } + +public: + std::string_view get_type_name() const override { return "osd_boot"; } + void print(ostream& out) const override { + out << "osd_boot(osd." << sb.whoami << " booted " << boot_epoch + << " features " << osd_features + << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + using ceph::encode; + paxos_encode(); + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + header.version = 6; + header.compat_version = 6; + encode(sb, payload); + hb_back_addrs.legacy_addr().encode(payload, features); + cluster_addrs.legacy_addr().encode(payload, features); + encode(boot_epoch, payload); + hb_front_addrs.legacy_addr().encode(payload, features); + encode(metadata, payload); + encode(osd_features, payload); + return; + } + encode(sb, payload); + encode(hb_back_addrs, payload, features); + encode(cluster_addrs, payload, features); + encode(boot_epoch, payload); + encode(hb_front_addrs, payload, features); + encode(metadata, payload); + encode(osd_features, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + if (header.version < 7) { + entity_addr_t a; + decode(sb, p); + decode(a, p); + hb_back_addrs = entity_addrvec_t(a); + decode(a, p); + cluster_addrs = entity_addrvec_t(a); + decode(boot_epoch, p); + decode(a, p); + hb_front_addrs = entity_addrvec_t(a); + decode(metadata, p); + decode(osd_features, p); + return; + } + decode(sb, p); + decode(hb_back_addrs, p); + decode(cluster_addrs, p); + decode(boot_epoch, p); + decode(hb_front_addrs, p); + decode(metadata, p); + decode(osd_features, p); + } +}; + +#endif diff --git a/src/messages/MOSDECSubOpRead.h b/src/messages/MOSDECSubOpRead.h new file mode 100644 index 00000000..c006a85c --- /dev/null +++ b/src/messages/MOSDECSubOpRead.h @@ -0,0 +1,82 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDECSUBOPREAD_H +#define MOSDECSUBOPREAD_H + +#include "MOSDFastDispatchOp.h" +#include "osd/ECMsgTypes.h" + +class MOSDECSubOpRead : public MessageInstance<MOSDECSubOpRead, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + +public: + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + ECSubRead op; + + int get_cost() const override { + return 0; + } + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDECSubOpRead() + : MessageInstance(MSG_OSD_EC_READ, HEAD_VERSION, COMPAT_VERSION) + {} + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(op, p); + if (header.version >= 3) { + decode(min_epoch, p); + decode_trace(p); + } else { + min_epoch = map_epoch; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(op, payload, features); + encode(min_epoch, payload); + encode_trace(payload, features); + } + + std::string_view get_type_name() const override { return "MOSDECSubOpRead"; } + + void print(ostream& out) const override { + out << "MOSDECSubOpRead(" << pgid + << " " << map_epoch << "/" << min_epoch + << " " << op; + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDECSubOpReadReply.h b/src/messages/MOSDECSubOpReadReply.h new file mode 100644 index 00000000..091e5391 --- /dev/null +++ b/src/messages/MOSDECSubOpReadReply.h @@ -0,0 +1,82 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDECSUBOPREADREPLY_H +#define MOSDECSUBOPREADREPLY_H + +#include "MOSDFastDispatchOp.h" +#include "osd/ECMsgTypes.h" + +class MOSDECSubOpReadReply : public MessageInstance<MOSDECSubOpReadReply, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + ECSubReadReply op; + + int get_cost() const override { + return 0; + } + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDECSubOpReadReply() + : MessageInstance(MSG_OSD_EC_READ_REPLY, HEAD_VERSION, COMPAT_VERSION) + {} + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(op, p); + if (header.version >= 2) { + decode(min_epoch, p); + decode_trace(p); + } else { + min_epoch = map_epoch; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(op, payload); + encode(min_epoch, payload); + encode_trace(payload, features); + } + + std::string_view get_type_name() const override { return "MOSDECSubOpReadReply"; } + + void print(ostream& out) const override { + out << "MOSDECSubOpReadReply(" << pgid + << " " << map_epoch << "/" << min_epoch + << " " << op; + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDECSubOpWrite.h b/src/messages/MOSDECSubOpWrite.h new file mode 100644 index 00000000..5b286cff --- /dev/null +++ b/src/messages/MOSDECSubOpWrite.h @@ -0,0 +1,91 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDECSUBOPWRITE_H +#define MOSDECSUBOPWRITE_H + +#include "MOSDFastDispatchOp.h" +#include "osd/ECMsgTypes.h" + +class MOSDECSubOpWrite : public MessageInstance<MOSDECSubOpWrite, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + ECSubWrite op; + + int get_cost() const override { + return 0; + } + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDECSubOpWrite() + : MessageInstance(MSG_OSD_EC_WRITE, HEAD_VERSION, COMPAT_VERSION) + {} + MOSDECSubOpWrite(ECSubWrite &in_op) + : MessageInstance(MSG_OSD_EC_WRITE, HEAD_VERSION, COMPAT_VERSION) { + op.claim(in_op); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(op, p); + if (header.version >= 2) { + decode(min_epoch, p); + decode_trace(p); + } else { + min_epoch = map_epoch; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(op, payload); + encode(min_epoch, payload); + encode_trace(payload, features); + } + + std::string_view get_type_name() const override { return "MOSDECSubOpWrite"; } + + void print(ostream& out) const override { + out << "MOSDECSubOpWrite(" << pgid + << " " << map_epoch << "/" << min_epoch + << " " << op; + out << ")"; + } + + void clear_buffers() override { + op.t = ObjectStore::Transaction(); + op.log_entries.clear(); + } +}; + +#endif diff --git a/src/messages/MOSDECSubOpWriteReply.h b/src/messages/MOSDECSubOpWriteReply.h new file mode 100644 index 00000000..dfcaf9ae --- /dev/null +++ b/src/messages/MOSDECSubOpWriteReply.h @@ -0,0 +1,82 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDECSUBOPWRITEREPLY_H +#define MOSDECSUBOPWRITEREPLY_H + +#include "MOSDFastDispatchOp.h" +#include "osd/ECMsgTypes.h" + +class MOSDECSubOpWriteReply : public MessageInstance<MOSDECSubOpWriteReply, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + ECSubWriteReply op; + + int get_cost() const override { + return 0; + } + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDECSubOpWriteReply() + : MessageInstance(MSG_OSD_EC_WRITE_REPLY, HEAD_VERSION, COMPAT_VERSION) + {} + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(op, p); + if (header.version >= 2) { + decode(min_epoch, p); + decode_trace(p); + } else { + min_epoch = map_epoch; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(op, payload); + encode(min_epoch, payload); + encode_trace(payload, features); + } + + std::string_view get_type_name() const override { return "MOSDECSubOpWriteReply"; } + + void print(ostream& out) const override { + out << "MOSDECSubOpWriteReply(" << pgid + << " " << map_epoch << "/" << min_epoch + << " " << op; + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDFailure.h b/src/messages/MOSDFailure.h new file mode 100644 index 00000000..27888dd4 --- /dev/null +++ b/src/messages/MOSDFailure.h @@ -0,0 +1,128 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDFAILURE_H +#define CEPH_MOSDFAILURE_H + +#include "messages/PaxosServiceMessage.h" + + +class MOSDFailure : public MessageInstance<MOSDFailure, PaxosServiceMessage> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 4; + + public: + enum { + FLAG_ALIVE = 0, // use this on its own to mark as "I'm still alive" + FLAG_FAILED = 1, // if set, failure; if not, recovery + FLAG_IMMEDIATE = 2, // known failure, not a timeout + }; + + uuid_d fsid; + int32_t target_osd; + entity_addrvec_t target_addrs; + __u8 flags = 0; + epoch_t epoch = 0; + int32_t failed_for = 0; // known to be failed since at least this long + + MOSDFailure() : MessageInstance(MSG_OSD_FAILURE, 0, HEAD_VERSION) { } + MOSDFailure(const uuid_d &fs, int osd, const entity_addrvec_t& av, + int duration, epoch_t e) + : MessageInstance(MSG_OSD_FAILURE, e, HEAD_VERSION, COMPAT_VERSION), + fsid(fs), + target_osd(osd), + target_addrs(av), + flags(FLAG_FAILED), + epoch(e), failed_for(duration) { } + MOSDFailure(const uuid_d &fs, int osd, const entity_addrvec_t& av, + int duration, + epoch_t e, __u8 extra_flags) + : MessageInstance(MSG_OSD_FAILURE, e, HEAD_VERSION, COMPAT_VERSION), + fsid(fs), + target_osd(osd), + target_addrs(av), + flags(extra_flags), + epoch(e), failed_for(duration) { } +private: + ~MOSDFailure() override {} + +public: + int get_target_osd() { return target_osd; } + const entity_addrvec_t& get_target_addrs() { return target_addrs; } + bool if_osd_failed() const { + return flags & FLAG_FAILED; + } + bool is_immediate() const { + return flags & FLAG_IMMEDIATE; + } + epoch_t get_epoch() const { return epoch; } + + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + if (header.version < 4) { + entity_inst_t i; + decode(i, p); + target_osd = i.name.num(); + target_addrs.v.push_back(i.addr); + } else { + decode(target_osd, p); + decode(target_addrs, p); + } + decode(epoch, p); + decode(flags, p); + decode(failed_for, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + header.version = 3; + header.compat_version = 3; + encode(fsid, payload); + encode(entity_inst_t(entity_name_t::OSD(target_osd), + target_addrs.legacy_addr()), payload, features); + encode(epoch, payload); + encode(flags, payload); + encode(failed_for, payload); + return; + } + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(fsid, payload); + encode(target_osd, payload, features); + encode(target_addrs, payload, features); + encode(epoch, payload); + encode(flags, payload); + encode(failed_for, payload); + } + + std::string_view get_type_name() const override { return "osd_failure"; } + void print(ostream& out) const override { + out << "osd_failure(" + << (if_osd_failed() ? "failed " : "recovered ") + << (is_immediate() ? "immediate " : "timeout ") + << "osd." << target_osd << " " << target_addrs + << " for " << failed_for << "sec e" << epoch + << " v" << version << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDFastDispatchOp.h b/src/messages/MOSDFastDispatchOp.h new file mode 100644 index 00000000..1f5f7abe --- /dev/null +++ b/src/messages/MOSDFastDispatchOp.h @@ -0,0 +1,23 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MOSDFASTDISPATCHOP_H +#define CEPH_MOSDFASTDISPATCHOP_H + +#include "msg/Message.h" +#include "osd/osd_types.h" + +class MOSDFastDispatchOp : public MessageSubType<MOSDFastDispatchOp> { +public: + +template<typename... Args> + MOSDFastDispatchOp(Args&&... args) : MessageSubType(std::forward<Args>(args)...) {} + + virtual epoch_t get_map_epoch() const = 0; + virtual epoch_t get_min_epoch() const { + return get_map_epoch(); + } + virtual spg_t get_spg() const = 0; +}; + +#endif diff --git a/src/messages/MOSDForceRecovery.h b/src/messages/MOSDForceRecovery.h new file mode 100644 index 00000000..9ee824a1 --- /dev/null +++ b/src/messages/MOSDForceRecovery.h @@ -0,0 +1,112 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 OVH + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDFORCERECOVERY_H +#define CEPH_MOSDFORCERECOVERY_H + +#include "msg/Message.h" + +/* + * instruct an OSD to boost/unboost recovery/backfill priority of some or all pg(s) + */ + +// boost priority of recovery +static const int OFR_RECOVERY = 1; + +// boost priority of backfill +static const int OFR_BACKFILL = 2; + +// cancel priority boost, requeue if necessary +static const int OFR_CANCEL = 4; + +class MOSDForceRecovery : public MessageInstance<MOSDForceRecovery> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + + uuid_d fsid; + vector<spg_t> forced_pgs; + uint8_t options = 0; + + MOSDForceRecovery() : MessageInstance(MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION) {} + MOSDForceRecovery(const uuid_d& f, char opts) : + MessageInstance(MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION), + fsid(f), options(opts) {} + MOSDForceRecovery(const uuid_d& f, vector<spg_t>& pgs, char opts) : + MessageInstance(MSG_OSD_FORCE_RECOVERY, HEAD_VERSION, COMPAT_VERSION), + fsid(f), forced_pgs(pgs), options(opts) {} +private: + ~MOSDForceRecovery() {} + +public: + std::string_view get_type_name() const { return "force_recovery"; } + void print(ostream& out) const { + out << "force_recovery("; + if (forced_pgs.empty()) + out << "osd"; + else + out << forced_pgs; + if (options & OFR_RECOVERY) + out << " recovery"; + if (options & OFR_BACKFILL) + out << " backfill"; + if (options & OFR_CANCEL) + out << " cancel"; + out << ")"; + } + + void encode_payload(uint64_t features) { + using ceph::encode; + if (!HAVE_FEATURE(features, SERVER_MIMIC)) { + header.version = 1; + header.compat_version = 1; + vector<pg_t> pgs; + for (auto pgid : forced_pgs) { + pgs.push_back(pgid.pgid); + } + encode(fsid, payload); + encode(pgs, payload); + encode(options, payload); + return; + } + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(fsid, payload); + encode(forced_pgs, payload); + encode(options, payload); + } + void decode_payload() { + auto p = payload.cbegin(); + if (header.version == 1) { + vector<pg_t> pgs; + decode(fsid, p); + decode(pgs, p); + decode(options, p); + for (auto pg : pgs) { + // note: this only works with replicated pools. if a pre-mimic mon + // tries to force a mimic+ osd on an ec pool it will not work. + forced_pgs.push_back(spg_t(pg)); + } + return; + } + decode(fsid, p); + decode(forced_pgs, p); + decode(options, p); + } +}; + +#endif /* CEPH_MOSDFORCERECOVERY_H_ */ diff --git a/src/messages/MOSDFull.h b/src/messages/MOSDFull.h new file mode 100644 index 00000000..bfe0c24e --- /dev/null +++ b/src/messages/MOSDFull.h @@ -0,0 +1,53 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MOSDFULL_H +#define CEPH_MOSDFULL_H + +#include "messages/PaxosServiceMessage.h" +#include "osd/OSDMap.h" + +// tell the mon to update the full/nearfull bits. note that in the +// future this message could be generalized to other state bits, but +// for now name it for its sole application. + +class MOSDFull : public MessageInstance<MOSDFull, PaxosServiceMessage> { +public: + friend factory; + + epoch_t map_epoch = 0; + uint32_t state = 0; + +private: + ~MOSDFull() {} + +public: + MOSDFull(epoch_t e, unsigned s) + : MessageInstance(MSG_OSD_FULL, e), map_epoch(e), state(s) { } + MOSDFull() + : MessageInstance(MSG_OSD_FULL, 0) {} + +public: + void encode_payload(uint64_t features) { + using ceph::encode; + paxos_encode(); + encode(map_epoch, payload); + encode(state, payload); + } + void decode_payload() { + auto p = payload.cbegin(); + paxos_decode(p); + decode(map_epoch, p); + decode(state, p); + } + + std::string_view get_type_name() const { return "osd_full"; } + void print(ostream &out) const { + set<string> states; + OSDMap::calc_state_set(state, states); + out << "osd_full(e" << map_epoch << " " << states << " v" << version << ")"; + } + +}; + +#endif diff --git a/src/messages/MOSDMap.h b/src/messages/MOSDMap.h new file mode 100644 index 00000000..9a5062c6 --- /dev/null +++ b/src/messages/MOSDMap.h @@ -0,0 +1,173 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDMAP_H +#define CEPH_MOSDMAP_H + +#include "msg/Message.h" +#include "osd/OSDMap.h" +#include "include/ceph_features.h" + +class MOSDMap : public MessageInstance<MOSDMap> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 3; + + public: + uuid_d fsid; + uint64_t encode_features = 0; + map<epoch_t, bufferlist> maps; + map<epoch_t, bufferlist> incremental_maps; + epoch_t oldest_map =0, newest_map = 0; + + // if we are fetching maps from the mon and have to jump a gap + // (client's next needed map is older than mon's oldest) we can + // share removed snaps from the gap here. + mempool::osdmap::map<int64_t,OSDMap::snap_interval_set_t> gap_removed_snaps; + + epoch_t get_first() const { + epoch_t e = 0; + map<epoch_t, bufferlist>::const_iterator i = maps.begin(); + if (i != maps.end()) e = i->first; + i = incremental_maps.begin(); + if (i != incremental_maps.end() && + (e == 0 || i->first < e)) e = i->first; + return e; + } + epoch_t get_last() const { + epoch_t e = 0; + map<epoch_t, bufferlist>::const_reverse_iterator i = maps.rbegin(); + if (i != maps.rend()) e = i->first; + i = incremental_maps.rbegin(); + if (i != incremental_maps.rend() && + (e == 0 || i->first > e)) e = i->first; + return e; + } + epoch_t get_oldest() { + return oldest_map; + } + epoch_t get_newest() { + return newest_map; + } + + + MOSDMap() : MessageInstance(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION) { } + MOSDMap(const uuid_d &f, const uint64_t features) + : MessageInstance(CEPH_MSG_OSD_MAP, HEAD_VERSION, COMPAT_VERSION), + fsid(f), encode_features(features), + oldest_map(0), newest_map(0) { } +private: + ~MOSDMap() override {} +public: + // marshalling + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(incremental_maps, p); + decode(maps, p); + if (header.version >= 2) { + decode(oldest_map, p); + decode(newest_map, p); + } else { + oldest_map = 0; + newest_map = 0; + } + if (header.version >= 4) { + decode(gap_removed_snaps, p); + } + } + void encode_payload(uint64_t features) override { + using ceph::encode; + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(fsid, payload); + if (OSDMap::get_significant_features(encode_features) != + OSDMap::get_significant_features(features)) { + if ((features & CEPH_FEATURE_PGID64) == 0 || + (features & CEPH_FEATURE_PGPOOL3) == 0) { + header.version = 1; // old old_client version + header.compat_version = 1; + } else if ((features & CEPH_FEATURE_OSDENC) == 0) { + header.version = 2; // old pg_pool_t + header.compat_version = 2; + } + + // reencode maps using old format + // + // FIXME: this can probably be done more efficiently higher up + // the stack, or maybe replaced with something that only + // includes the pools the client cares about. + for (map<epoch_t,bufferlist>::iterator p = incremental_maps.begin(); + p != incremental_maps.end(); + ++p) { + OSDMap::Incremental inc; + auto q = p->second.cbegin(); + inc.decode(q); + // always encode with subset of osdmaps canonical features + uint64_t f = inc.encode_features & features; + p->second.clear(); + if (inc.fullmap.length()) { + // embedded full map? + OSDMap m; + m.decode(inc.fullmap); + inc.fullmap.clear(); + m.encode(inc.fullmap, f | CEPH_FEATURE_RESERVED); + } + if (inc.crush.length()) { + // embedded crush map + CrushWrapper c; + auto p = inc.crush.cbegin(); + c.decode(p); + inc.crush.clear(); + c.encode(inc.crush, f); + } + inc.encode(p->second, f | CEPH_FEATURE_RESERVED); + } + for (map<epoch_t,bufferlist>::iterator p = maps.begin(); + p != maps.end(); + ++p) { + OSDMap m; + m.decode(p->second); + // always encode with subset of osdmaps canonical features + uint64_t f = m.get_encoding_features() & features; + p->second.clear(); + m.encode(p->second, f | CEPH_FEATURE_RESERVED); + } + } + encode(incremental_maps, payload); + encode(maps, payload); + if (header.version >= 2) { + encode(oldest_map, payload); + encode(newest_map, payload); + } + if (header.version >= 4) { + encode(gap_removed_snaps, payload); + } + } + + std::string_view get_type_name() const override { return "osdmap"; } + void print(ostream& out) const override { + out << "osd_map(" << get_first() << ".." << get_last(); + if (oldest_map || newest_map) + out << " src has " << oldest_map << ".." << newest_map; + if (!gap_removed_snaps.empty()) + out << " +gap_removed_snaps"; + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDMarkMeDown.h b/src/messages/MOSDMarkMeDown.h new file mode 100644 index 00000000..89c3d75c --- /dev/null +++ b/src/messages/MOSDMarkMeDown.h @@ -0,0 +1,103 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDMARKMEDOWN_H +#define CEPH_MOSDMARKMEDOWN_H + +#include "messages/PaxosServiceMessage.h" + +class MOSDMarkMeDown : public MessageInstance<MOSDMarkMeDown, PaxosServiceMessage> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 3; + + public: + uuid_d fsid; + int32_t target_osd; + entity_addrvec_t target_addrs; + epoch_t epoch = 0; + bool request_ack = false; // ack requested + + MOSDMarkMeDown() + : MessageInstance(MSG_OSD_MARK_ME_DOWN, 0, + HEAD_VERSION, COMPAT_VERSION) { } + MOSDMarkMeDown(const uuid_d &fs, int osd, const entity_addrvec_t& av, + epoch_t e, bool request_ack) + : MessageInstance(MSG_OSD_MARK_ME_DOWN, e, + HEAD_VERSION, COMPAT_VERSION), + fsid(fs), target_osd(osd), target_addrs(av), + epoch(e), request_ack(request_ack) {} + private: + ~MOSDMarkMeDown() override {} + +public: + epoch_t get_epoch() const { return epoch; } + + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + if (header.version <= 2) { + decode(fsid, p); + entity_inst_t i; + decode(i, p); + target_osd = i.name.num(); + target_addrs = entity_addrvec_t(i.addr); + decode(epoch, p); + decode(request_ack, p); + return; + } + decode(fsid, p); + decode(target_osd, p); + decode(target_addrs, p); + decode(epoch, p); + decode(request_ack, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + header.version = 2; + header.compat_version = 2; + encode(fsid, payload); + encode(entity_inst_t(entity_name_t::OSD(target_osd), + target_addrs.legacy_addr()), + payload, features); + encode(epoch, payload); + encode(request_ack, payload); + return; + } + header.version = HEAD_VERSION; + header.compat_version = COMPAT_VERSION; + encode(fsid, payload); + encode(target_osd, payload, features); + encode(target_addrs, payload, features); + encode(epoch, payload); + encode(request_ack, payload); + } + + std::string_view get_type_name() const override { return "MOSDMarkMeDown"; } + void print(ostream& out) const override { + out << "MOSDMarkMeDown(" + << "request_ack=" << request_ack + << ", osd." << target_osd + << ", " << target_addrs + << ", fsid=" << fsid + << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDOp.h b/src/messages/MOSDOp.h new file mode 100644 index 00000000..c751b53d --- /dev/null +++ b/src/messages/MOSDOp.h @@ -0,0 +1,598 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDOP_H +#define CEPH_MOSDOP_H + +#include "MOSDFastDispatchOp.h" +#include "include/ceph_features.h" +#include "common/hobject.h" +#include <atomic> + +/* + * OSD op + * + * oid - object id + * op - OSD_OP_DELETE, etc. + * + */ + +class OSD; + +class MOSDOp : public MessageInstance<MOSDOp, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 8; + static constexpr int COMPAT_VERSION = 3; + +private: + uint32_t client_inc = 0; + __u32 osdmap_epoch = 0; + __u32 flags = 0; + utime_t mtime; + int32_t retry_attempt = -1; // 0 is first attempt. -1 if we don't know. + + hobject_t hobj; + spg_t pgid; + bufferlist::const_iterator p; + // Decoding flags. Decoding is only needed for messages caught by pipe reader. + // Transition from true -> false without locks being held + // Can never see final_decode_needed == false and partial_decode_needed == true + atomic<bool> partial_decode_needed; + atomic<bool> final_decode_needed; + // +public: + vector<OSDOp> ops; +private: + snapid_t snap_seq; + vector<snapid_t> snaps; + + uint64_t features; + bool bdata_encode; + osd_reqid_t reqid; // reqid explicitly set by sender + +public: + friend class MOSDOpReply; + + ceph_tid_t get_client_tid() { return header.tid; } + void set_snapid(const snapid_t& s) { + hobj.snap = s; + } + void set_snaps(const vector<snapid_t>& i) { + snaps = i; + } + void set_snap_seq(const snapid_t& s) { snap_seq = s; } + void set_reqid(const osd_reqid_t rid) { + reqid = rid; + } + void set_spg(spg_t p) { + pgid = p; + } + + // Fields decoded in partial decoding + pg_t get_pg() const { + ceph_assert(!partial_decode_needed); + return pgid.pgid; + } + spg_t get_spg() const override { + ceph_assert(!partial_decode_needed); + return pgid; + } + pg_t get_raw_pg() const { + ceph_assert(!partial_decode_needed); + return pg_t(hobj.get_hash(), pgid.pgid.pool()); + } + epoch_t get_map_epoch() const override { + ceph_assert(!partial_decode_needed); + return osdmap_epoch; + } + int get_flags() const { + ceph_assert(!partial_decode_needed); + return flags; + } + osd_reqid_t get_reqid() const { + ceph_assert(!partial_decode_needed); + if (reqid.name != entity_name_t() || reqid.tid != 0) { + return reqid; + } else { + if (!final_decode_needed) + ceph_assert(reqid.inc == (int32_t)client_inc); // decode() should have done this + return osd_reqid_t(get_orig_source(), + reqid.inc, + header.tid); + } + } + + // Fields decoded in final decoding + int get_client_inc() const { + ceph_assert(!final_decode_needed); + return client_inc; + } + utime_t get_mtime() const { + ceph_assert(!final_decode_needed); + return mtime; + } + object_locator_t get_object_locator() const { + ceph_assert(!final_decode_needed); + if (hobj.oid.name.empty()) + return object_locator_t(hobj.pool, hobj.nspace, hobj.get_hash()); + else + return object_locator_t(hobj); + } + const object_t& get_oid() const { + ceph_assert(!final_decode_needed); + return hobj.oid; + } + const hobject_t &get_hobj() const { + return hobj; + } + snapid_t get_snapid() const { + ceph_assert(!final_decode_needed); + return hobj.snap; + } + const snapid_t& get_snap_seq() const { + ceph_assert(!final_decode_needed); + return snap_seq; + } + const vector<snapid_t> &get_snaps() const { + ceph_assert(!final_decode_needed); + return snaps; + } + + /** + * get retry attempt + * + * 0 is the first attempt. + * + * @return retry attempt, or -1 if we don't know + */ + int get_retry_attempt() const { + return retry_attempt; + } + uint64_t get_features() const { + if (features) + return features; + return get_connection()->get_features(); + } + + MOSDOp() + : MessageInstance(CEPH_MSG_OSD_OP, HEAD_VERSION, COMPAT_VERSION), + partial_decode_needed(true), + final_decode_needed(true), + bdata_encode(false) { } + MOSDOp(int inc, long tid, const hobject_t& ho, spg_t& _pgid, + epoch_t _osdmap_epoch, + int _flags, uint64_t feat) + : MessageInstance(CEPH_MSG_OSD_OP, HEAD_VERSION, COMPAT_VERSION), + client_inc(inc), + osdmap_epoch(_osdmap_epoch), flags(_flags), retry_attempt(-1), + hobj(ho), + pgid(_pgid), + partial_decode_needed(false), + final_decode_needed(false), + features(feat), + bdata_encode(false) { + set_tid(tid); + + // also put the client_inc in reqid.inc, so that get_reqid() can + // be used before the full message is decoded. + reqid.inc = inc; + } +private: + ~MOSDOp() override {} + +public: + void set_mtime(utime_t mt) { mtime = mt; } + void set_mtime(ceph::real_time mt) { + mtime = ceph::real_clock::to_timespec(mt); + } + + // ops + void add_simple_op(int o, uint64_t off, uint64_t len) { + OSDOp osd_op; + osd_op.op.op = o; + osd_op.op.extent.offset = off; + osd_op.op.extent.length = len; + ops.push_back(osd_op); + } + void write(uint64_t off, uint64_t len, bufferlist& bl) { + add_simple_op(CEPH_OSD_OP_WRITE, off, len); + data.claim(bl); + header.data_off = off; + } + void writefull(bufferlist& bl) { + add_simple_op(CEPH_OSD_OP_WRITEFULL, 0, bl.length()); + data.claim(bl); + header.data_off = 0; + } + void zero(uint64_t off, uint64_t len) { + add_simple_op(CEPH_OSD_OP_ZERO, off, len); + } + void truncate(uint64_t off) { + add_simple_op(CEPH_OSD_OP_TRUNCATE, off, 0); + } + void remove() { + add_simple_op(CEPH_OSD_OP_DELETE, 0, 0); + } + + void read(uint64_t off, uint64_t len) { + add_simple_op(CEPH_OSD_OP_READ, off, len); + } + void stat() { + add_simple_op(CEPH_OSD_OP_STAT, 0, 0); + } + + bool has_flag(__u32 flag) const { return flags & flag; }; + + bool is_retry_attempt() const { return flags & CEPH_OSD_FLAG_RETRY; } + void set_retry_attempt(unsigned a) { + if (a) + flags |= CEPH_OSD_FLAG_RETRY; + else + flags &= ~CEPH_OSD_FLAG_RETRY; + retry_attempt = a; + } + + // marshalling + void encode_payload(uint64_t features) override { + using ceph::encode; + if( false == bdata_encode ) { + OSDOp::merge_osd_op_vector_in_data(ops, data); + bdata_encode = true; + } + + if ((features & CEPH_FEATURE_OBJECTLOCATOR) == 0) { + // here is the old structure we are encoding to: // +#if 0 +struct ceph_osd_request_head { + __le32 client_inc; /* client incarnation */ + struct ceph_object_layout layout; /* pgid */ + __le32 osdmap_epoch; /* client's osdmap epoch */ + + __le32 flags; + + struct ceph_timespec mtime; /* for mutations only */ + struct ceph_eversion reassert_version; /* if we are replaying op */ + + __le32 object_len; /* length of object name */ + + __le64 snapid; /* snapid to read */ + __le64 snap_seq; /* writer's snap context */ + __le32 num_snaps; + + __le16 num_ops; + struct ceph_osd_op ops[]; /* followed by ops[], obj, ticket, snaps */ +} __attribute__ ((packed)); +#endif + header.version = 1; + + encode(client_inc, payload); + + __u32 su = 0; + encode(get_raw_pg(), payload); + encode(su, payload); + + encode(osdmap_epoch, payload); + encode(flags, payload); + encode(mtime, payload); + encode(eversion_t(), payload); // reassert_version + + __u32 oid_len = hobj.oid.name.length(); + encode(oid_len, payload); + encode(hobj.snap, payload); + encode(snap_seq, payload); + __u32 num_snaps = snaps.size(); + encode(num_snaps, payload); + + //::encode(ops, payload); + __u16 num_ops = ops.size(); + encode(num_ops, payload); + for (unsigned i = 0; i < ops.size(); i++) + encode(ops[i].op, payload); + + encode_nohead(hobj.oid.name, payload); + encode_nohead(snaps, payload); + } else if ((features & CEPH_FEATURE_NEW_OSDOP_ENCODING) == 0) { + header.version = 6; + encode(client_inc, payload); + encode(osdmap_epoch, payload); + encode(flags, payload); + encode(mtime, payload); + encode(eversion_t(), payload); // reassert_version + encode(get_object_locator(), payload); + encode(get_raw_pg(), payload); + + encode(hobj.oid, payload); + + __u16 num_ops = ops.size(); + encode(num_ops, payload); + for (unsigned i = 0; i < ops.size(); i++) + encode(ops[i].op, payload); + + encode(hobj.snap, payload); + encode(snap_seq, payload); + encode(snaps, payload); + + encode(retry_attempt, payload); + encode(features, payload); + if (reqid.name != entity_name_t() || reqid.tid != 0) { + encode(reqid, payload); + } else { + // don't include client_inc in the reqid for the legacy v6 + // encoding or else we'll confuse older peers. + encode(osd_reqid_t(), payload); + } + } else if (!HAVE_FEATURE(features, RESEND_ON_SPLIT)) { + // reordered, v7 message encoding + header.version = 7; + encode(get_raw_pg(), payload); + encode(osdmap_epoch, payload); + encode(flags, payload); + encode(eversion_t(), payload); // reassert_version + encode(reqid, payload); + encode(client_inc, payload); + encode(mtime, payload); + encode(get_object_locator(), payload); + encode(hobj.oid, payload); + + __u16 num_ops = ops.size(); + encode(num_ops, payload); + for (unsigned i = 0; i < ops.size(); i++) + encode(ops[i].op, payload); + + encode(hobj.snap, payload); + encode(snap_seq, payload); + encode(snaps, payload); + + encode(retry_attempt, payload); + encode(features, payload); + } else { + // latest v8 encoding with hobject_t hash separate from pgid, no + // reassert version + header.version = HEAD_VERSION; + + encode(pgid, payload); + encode(hobj.get_hash(), payload); + encode(osdmap_epoch, payload); + encode(flags, payload); + encode(reqid, payload); + encode_trace(payload, features); + + // -- above decoded up front; below decoded post-dispatch thread -- + + encode(client_inc, payload); + encode(mtime, payload); + encode(get_object_locator(), payload); + encode(hobj.oid, payload); + + __u16 num_ops = ops.size(); + encode(num_ops, payload); + for (unsigned i = 0; i < ops.size(); i++) + encode(ops[i].op, payload); + + encode(hobj.snap, payload); + encode(snap_seq, payload); + encode(snaps, payload); + + encode(retry_attempt, payload); + encode(features, payload); + } + } + + void decode_payload() override { + ceph_assert(partial_decode_needed && final_decode_needed); + p = std::cbegin(payload); + + // Always keep here the newest version of decoding order/rule + if (header.version == HEAD_VERSION) { + decode(pgid, p); // actual pgid + uint32_t hash; + decode(hash, p); // raw hash value + hobj.set_hash(hash); + decode(osdmap_epoch, p); + decode(flags, p); + decode(reqid, p); + decode_trace(p); + } else if (header.version == 7) { + decode(pgid.pgid, p); // raw pgid + hobj.set_hash(pgid.pgid.ps()); + decode(osdmap_epoch, p); + decode(flags, p); + eversion_t reassert_version; + decode(reassert_version, p); + decode(reqid, p); + } else if (header.version < 2) { + // old decode + decode(client_inc, p); + + old_pg_t opgid; + ::decode_raw(opgid, p); + pgid.pgid = opgid; + + __u32 su; + decode(su, p); + + decode(osdmap_epoch, p); + decode(flags, p); + decode(mtime, p); + eversion_t reassert_version; + decode(reassert_version, p); + + __u32 oid_len; + decode(oid_len, p); + decode(hobj.snap, p); + decode(snap_seq, p); + __u32 num_snaps; + decode(num_snaps, p); + + //::decode(ops, p); + __u16 num_ops; + decode(num_ops, p); + ops.resize(num_ops); + for (unsigned i = 0; i < num_ops; i++) + decode(ops[i].op, p); + + decode_nohead(oid_len, hobj.oid.name, p); + decode_nohead(num_snaps, snaps, p); + + // recalculate pgid hash value + pgid.pgid.set_ps(ceph_str_hash(CEPH_STR_HASH_RJENKINS, + hobj.oid.name.c_str(), + hobj.oid.name.length())); + hobj.pool = pgid.pgid.pool(); + hobj.set_hash(pgid.pgid.ps()); + + retry_attempt = -1; + features = 0; + OSDOp::split_osd_op_vector_in_data(ops, data); + + // we did the full decode + final_decode_needed = false; + + // put client_inc in reqid.inc for get_reqid()'s benefit + reqid = osd_reqid_t(); + reqid.inc = client_inc; + } else if (header.version < 7) { + decode(client_inc, p); + decode(osdmap_epoch, p); + decode(flags, p); + decode(mtime, p); + eversion_t reassert_version; + decode(reassert_version, p); + + object_locator_t oloc; + decode(oloc, p); + + if (header.version < 3) { + old_pg_t opgid; + ::decode_raw(opgid, p); + pgid.pgid = opgid; + } else { + decode(pgid.pgid, p); + } + + decode(hobj.oid, p); + + //::decode(ops, p); + __u16 num_ops; + decode(num_ops, p); + ops.resize(num_ops); + for (unsigned i = 0; i < num_ops; i++) + decode(ops[i].op, p); + + decode(hobj.snap, p); + decode(snap_seq, p); + decode(snaps, p); + + if (header.version >= 4) + decode(retry_attempt, p); + else + retry_attempt = -1; + + if (header.version >= 5) + decode(features, p); + else + features = 0; + + if (header.version >= 6) + decode(reqid, p); + else + reqid = osd_reqid_t(); + + hobj.pool = pgid.pgid.pool(); + hobj.set_key(oloc.key); + hobj.nspace = oloc.nspace; + hobj.set_hash(pgid.pgid.ps()); + + OSDOp::split_osd_op_vector_in_data(ops, data); + + // we did the full decode + final_decode_needed = false; + + // put client_inc in reqid.inc for get_reqid()'s benefit + if (reqid.name == entity_name_t() && reqid.tid == 0) + reqid.inc = client_inc; + } + + partial_decode_needed = false; + } + + bool finish_decode() { + ceph_assert(!partial_decode_needed); // partial decoding required + if (!final_decode_needed) + return false; // Message is already final decoded + ceph_assert(header.version >= 7); + + decode(client_inc, p); + decode(mtime, p); + object_locator_t oloc; + decode(oloc, p); + decode(hobj.oid, p); + + __u16 num_ops; + decode(num_ops, p); + ops.resize(num_ops); + for (unsigned i = 0; i < num_ops; i++) + decode(ops[i].op, p); + + decode(hobj.snap, p); + decode(snap_seq, p); + decode(snaps, p); + + decode(retry_attempt, p); + + decode(features, p); + + hobj.pool = pgid.pgid.pool(); + hobj.set_key(oloc.key); + hobj.nspace = oloc.nspace; + + OSDOp::split_osd_op_vector_in_data(ops, data); + + final_decode_needed = false; + return true; + } + + void clear_buffers() override { + OSDOp::clear_data(ops); + bdata_encode = false; + } + + std::string_view get_type_name() const override { return "osd_op"; } + void print(ostream& out) const override { + out << "osd_op("; + if (!partial_decode_needed) { + out << get_reqid() << ' '; + out << pgid; + if (!final_decode_needed) { + out << ' '; + out << hobj + << " " << ops + << " snapc " << get_snap_seq() << "=" << snaps; + if (is_retry_attempt()) + out << " RETRY=" << get_retry_attempt(); + } else { + out << " " << get_raw_pg() << " (undecoded)"; + } + out << " " << ceph_osd_flag_string(get_flags()); + out << " e" << osdmap_epoch; + } + out << ")"; + } +}; + + +#endif diff --git a/src/messages/MOSDOpReply.h b/src/messages/MOSDOpReply.h new file mode 100644 index 00000000..3649921e --- /dev/null +++ b/src/messages/MOSDOpReply.h @@ -0,0 +1,340 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDOPREPLY_H +#define CEPH_MOSDOPREPLY_H + +#include "msg/Message.h" + +#include "MOSDOp.h" +#include "common/errno.h" + +/* + * OSD op reply + * + * oid - object id + * op - OSD_OP_DELETE, etc. + * + */ + +class MOSDOpReply : public MessageInstance<MOSDOpReply> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 8; + static constexpr int COMPAT_VERSION = 2; + + object_t oid; + pg_t pgid; + vector<OSDOp> ops; + bool bdata_encode; + int64_t flags = 0; + errorcode32_t result; + eversion_t bad_replay_version; + eversion_t replay_version; + version_t user_version = 0; + epoch_t osdmap_epoch = 0; + int32_t retry_attempt = -1; + bool do_redirect; + request_redirect_t redirect; + +public: + const object_t& get_oid() const { return oid; } + const pg_t& get_pg() const { return pgid; } + int get_flags() const { return flags; } + + bool is_ondisk() const { return get_flags() & CEPH_OSD_FLAG_ONDISK; } + bool is_onnvram() const { return get_flags() & CEPH_OSD_FLAG_ONNVRAM; } + + int get_result() const { return result; } + const eversion_t& get_replay_version() const { return replay_version; } + const version_t& get_user_version() const { return user_version; } + + void set_result(int r) { result = r; } + + void set_reply_versions(eversion_t v, version_t uv) { + replay_version = v; + user_version = uv; + /* We go through some shenanigans here for backwards compatibility + * with old clients, who do not look at our replay_version and + * user_version but instead see what we now call the + * bad_replay_version. On pools without caching + * the user_version infrastructure is a slightly-laggy copy of + * the regular pg version/at_version infrastructure; the difference + * being it is not updated on watch ops like that is -- but on updates + * it is set equal to at_version. This means that for non-watch write ops + * on classic pools, all three of replay_version, user_version, and + * bad_replay_version are identical. But for watch ops the replay_version + * has been updated, while the user_at_version has not, and the semantics + * we promised old clients are that the version they see is not an update. + * So set the bad_replay_version to be the same as the user_at_version. */ + bad_replay_version = v; + if (uv) { + bad_replay_version.version = uv; + } + } + + /* Don't fill in replay_version for non-write ops */ + void set_enoent_reply_versions(const eversion_t& v, const version_t& uv) { + user_version = uv; + bad_replay_version = v; + } + + void set_redirect(const request_redirect_t& redir) { redirect = redir; } + const request_redirect_t& get_redirect() const { return redirect; } + bool is_redirect_reply() const { return do_redirect; } + + void add_flags(int f) { flags |= f; } + + void claim_op_out_data(vector<OSDOp>& o) { + ceph_assert(ops.size() == o.size()); + for (unsigned i = 0; i < o.size(); i++) { + ops[i].outdata.claim(o[i].outdata); + } + } + void claim_ops(vector<OSDOp>& o) { + o.swap(ops); + bdata_encode = false; + } + + /** + * get retry attempt + * + * If we don't know the attempt (because the server is old), return -1. + */ + int get_retry_attempt() const { + return retry_attempt; + } + + // osdmap + epoch_t get_map_epoch() const { return osdmap_epoch; } + + /*osd_reqid_t get_reqid() { return osd_reqid_t(get_dest(), + head.client_inc, + head.tid); } + */ + +public: + MOSDOpReply() + : MessageInstance(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION), + bdata_encode(false) { + do_redirect = false; + } + MOSDOpReply(const MOSDOp *req, int r, epoch_t e, int acktype, + bool ignore_out_data) + : MessageInstance(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION), + oid(req->hobj.oid), pgid(req->pgid.pgid), ops(req->ops), + bdata_encode(false) { + + set_tid(req->get_tid()); + result = r; + flags = + (req->flags & ~(CEPH_OSD_FLAG_ONDISK|CEPH_OSD_FLAG_ONNVRAM|CEPH_OSD_FLAG_ACK)) | acktype; + osdmap_epoch = e; + user_version = 0; + retry_attempt = req->get_retry_attempt(); + do_redirect = false; + + // zero out ops payload_len and possibly out data + for (unsigned i = 0; i < ops.size(); i++) { + ops[i].op.payload_len = 0; + if (ignore_out_data) + ops[i].outdata.clear(); + } + } +private: + ~MOSDOpReply() override {} + +public: + void encode_payload(uint64_t features) override { + using ceph::encode; + if(false == bdata_encode) { + OSDOp::merge_osd_op_vector_out_data(ops, data); + bdata_encode = true; + } + + if ((features & CEPH_FEATURE_PGID64) == 0) { + header.version = 1; + ceph_osd_reply_head head; + memset(&head, 0, sizeof(head)); + head.layout.ol_pgid = pgid.get_old_pg().v; + head.flags = flags; + head.osdmap_epoch = osdmap_epoch; + head.reassert_version = bad_replay_version; + head.result = result; + head.num_ops = ops.size(); + head.object_len = oid.name.length(); + encode(head, payload); + for (unsigned i = 0; i < head.num_ops; i++) { + encode(ops[i].op, payload); + } + encode_nohead(oid.name, payload); + } else { + header.version = HEAD_VERSION; + encode(oid, payload); + encode(pgid, payload); + encode(flags, payload); + encode(result, payload); + encode(bad_replay_version, payload); + encode(osdmap_epoch, payload); + + __u32 num_ops = ops.size(); + encode(num_ops, payload); + for (unsigned i = 0; i < num_ops; i++) + encode(ops[i].op, payload); + + encode(retry_attempt, payload); + + for (unsigned i = 0; i < num_ops; i++) + encode(ops[i].rval, payload); + + encode(replay_version, payload); + encode(user_version, payload); + if ((features & CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING) == 0) { + header.version = 6; + encode(redirect, payload); + } else { + do_redirect = !redirect.empty(); + encode(do_redirect, payload); + if (do_redirect) { + encode(redirect, payload); + } + } + encode_trace(payload, features); + } + } + void decode_payload() override { + using ceph::decode; + auto p = payload.cbegin(); + + // Always keep here the newest version of decoding order/rule + if (header.version == HEAD_VERSION) { + decode(oid, p); + decode(pgid, p); + decode(flags, p); + decode(result, p); + decode(bad_replay_version, p); + decode(osdmap_epoch, p); + + __u32 num_ops = ops.size(); + decode(num_ops, p); + ops.resize(num_ops); + for (unsigned i = 0; i < num_ops; i++) + decode(ops[i].op, p); + decode(retry_attempt, p); + + for (unsigned i = 0; i < num_ops; ++i) + decode(ops[i].rval, p); + + OSDOp::split_osd_op_vector_out_data(ops, data); + + decode(replay_version, p); + decode(user_version, p); + decode(do_redirect, p); + if (do_redirect) + decode(redirect, p); + decode_trace(p); + } else if (header.version < 2) { + ceph_osd_reply_head head; + decode(head, p); + ops.resize(head.num_ops); + for (unsigned i = 0; i < head.num_ops; i++) { + decode(ops[i].op, p); + } + decode_nohead(head.object_len, oid.name, p); + pgid = pg_t(head.layout.ol_pgid); + result = (int32_t)head.result; + flags = head.flags; + replay_version = head.reassert_version; + user_version = replay_version.version; + osdmap_epoch = head.osdmap_epoch; + retry_attempt = -1; + } else { + decode(oid, p); + decode(pgid, p); + decode(flags, p); + decode(result, p); + decode(bad_replay_version, p); + decode(osdmap_epoch, p); + + __u32 num_ops = ops.size(); + decode(num_ops, p); + ops.resize(num_ops); + for (unsigned i = 0; i < num_ops; i++) + decode(ops[i].op, p); + + if (header.version >= 3) + decode(retry_attempt, p); + else + retry_attempt = -1; + + if (header.version >= 4) { + for (unsigned i = 0; i < num_ops; ++i) + decode(ops[i].rval, p); + + OSDOp::split_osd_op_vector_out_data(ops, data); + } + + if (header.version >= 5) { + decode(replay_version, p); + decode(user_version, p); + } else { + replay_version = bad_replay_version; + user_version = replay_version.version; + } + + if (header.version == 6) { + decode(redirect, p); + do_redirect = !redirect.empty(); + } + if (header.version >= 7) { + decode(do_redirect, p); + if (do_redirect) { + decode(redirect, p); + } + } + if (header.version >= 8) { + decode_trace(p); + } + } + } + + std::string_view get_type_name() const override { return "osd_op_reply"; } + + void print(ostream& out) const override { + out << "osd_op_reply(" << get_tid() + << " " << oid << " " << ops + << " v" << get_replay_version() + << " uv" << get_user_version(); + if (is_ondisk()) + out << " ondisk"; + else if (is_onnvram()) + out << " onnvram"; + else + out << " ack"; + out << " = " << get_result(); + if (get_result() < 0) { + out << " (" << cpp_strerror(get_result()) << ")"; + } + if (is_redirect_reply()) { + out << " redirect: { " << redirect << " }"; + } + out << ")"; + } + +}; + + +#endif diff --git a/src/messages/MOSDPGBackfill.h b/src/messages/MOSDPGBackfill.h new file mode 100644 index 00000000..47d25b0c --- /dev/null +++ b/src/messages/MOSDPGBackfill.h @@ -0,0 +1,114 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDPGBACKFILL_H +#define CEPH_MOSDPGBACKFILL_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGBackfill : public MessageInstance<MOSDPGBackfill, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 3; +public: + enum { + OP_BACKFILL_PROGRESS = 2, + OP_BACKFILL_FINISH = 3, + OP_BACKFILL_FINISH_ACK = 4, + }; + const char *get_op_name(int o) const { + switch (o) { + case OP_BACKFILL_PROGRESS: return "progress"; + case OP_BACKFILL_FINISH: return "finish"; + case OP_BACKFILL_FINISH_ACK: return "finish_ack"; + default: return "???"; + } + } + + __u32 op = 0; + epoch_t map_epoch = 0, query_epoch = 0; + spg_t pgid; + hobject_t last_backfill; + pg_stat_t stats; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return query_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(op, p); + decode(map_epoch, p); + decode(query_epoch, p); + decode(pgid.pgid, p); + decode(last_backfill, p); + + // For compatibility with version 1 + decode(stats.stats, p); + + decode(stats, p); + + // Handle hobject_t format change + if (!last_backfill.is_max() && + last_backfill.pool == -1) + last_backfill.pool = pgid.pool(); + decode(pgid.shard, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(op, payload); + encode(map_epoch, payload); + encode(query_epoch, payload); + encode(pgid.pgid, payload); + encode(last_backfill, payload); + + // For compatibility with version 1 + encode(stats.stats, payload); + + encode(stats, payload); + + encode(pgid.shard, payload); + } + + MOSDPGBackfill() + : MessageInstance(MSG_OSD_PG_BACKFILL, HEAD_VERSION, COMPAT_VERSION) {} + MOSDPGBackfill(__u32 o, epoch_t e, epoch_t qe, spg_t p) + : MessageInstance(MSG_OSD_PG_BACKFILL, HEAD_VERSION, COMPAT_VERSION), + op(o), + map_epoch(e), query_epoch(e), + pgid(p) {} +private: + ~MOSDPGBackfill() override {} + +public: + std::string_view get_type_name() const override { return "pg_backfill"; } + void print(ostream& out) const override { + out << "pg_backfill(" << get_op_name(op) + << " " << pgid + << " e " << map_epoch << "/" << query_epoch + << " lb " << last_backfill + << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGBackfillRemove.h b/src/messages/MOSDPGBackfillRemove.h new file mode 100644 index 00000000..35914518 --- /dev/null +++ b/src/messages/MOSDPGBackfillRemove.h @@ -0,0 +1,78 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 Sage Weil <sage@redhat.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDPGBACKFILLREMOVE_H +#define CEPH_MOSDPGBACKFILLREMOVE_H + +#include "MOSDFastDispatchOp.h" + +/* + * instruct non-primary to remove some objects during backfill + */ + +class MOSDPGBackfillRemove : public MessageInstance<MOSDPGBackfillRemove, MOSDFastDispatchOp> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + spg_t pgid; ///< target spg_t + epoch_t map_epoch = 0; + list<pair<hobject_t,eversion_t>> ls; ///< objects to remove + + epoch_t get_map_epoch() const override { + return map_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDPGBackfillRemove() + : MessageInstance(MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION, + COMPAT_VERSION) {} + + MOSDPGBackfillRemove(spg_t pgid, epoch_t map_epoch) + : MessageInstance(MSG_OSD_PG_BACKFILL_REMOVE, HEAD_VERSION, + COMPAT_VERSION), + pgid(pgid), + map_epoch(map_epoch) {} + +private: + ~MOSDPGBackfillRemove() {} + +public: + std::string_view get_type_name() const override { return "backfill_remove"; } + void print(ostream& out) const override { + out << "backfill_remove(" << pgid << " e" << map_epoch + << " " << ls << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(ls, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(ls, p); + } +}; + + + +#endif diff --git a/src/messages/MOSDPGCreate.h b/src/messages/MOSDPGCreate.h new file mode 100644 index 00000000..eef056ab --- /dev/null +++ b/src/messages/MOSDPGCreate.h @@ -0,0 +1,72 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGCREATE_H +#define CEPH_MOSDPGCREATE_H + +#include "msg/Message.h" +#include "osd/osd_types.h" + +/* + * PGCreate - instruct an OSD to create a pg, if it doesn't already exist + */ + +class MOSDPGCreate : public MessageInstance<MOSDPGCreate> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 3; + + version_t epoch = 0; + map<pg_t,pg_create_t> mkpg; + map<pg_t,utime_t> ctimes; + + MOSDPGCreate() + : MessageInstance(MSG_OSD_PG_CREATE, HEAD_VERSION, COMPAT_VERSION) {} + MOSDPGCreate(epoch_t e) + : MessageInstance(MSG_OSD_PG_CREATE, HEAD_VERSION, COMPAT_VERSION), + epoch(e) { } +private: + ~MOSDPGCreate() override {} + +public: + std::string_view get_type_name() const override { return "pg_create"; } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(mkpg, payload); + encode(ctimes, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(mkpg, p); + decode(ctimes, p); + } + + void print(ostream& out) const override { + out << "osd_pg_create(e" << epoch; + for (map<pg_t,pg_create_t>::const_iterator i = mkpg.begin(); + i != mkpg.end(); + ++i) { + out << " " << i->first << ":" << i->second.created; + } + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGCreate2.h b/src/messages/MOSDPGCreate2.h new file mode 100644 index 00000000..f232483f --- /dev/null +++ b/src/messages/MOSDPGCreate2.h @@ -0,0 +1,50 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" +#include "osd/osd_types.h" + +/* + * PGCreate2 - instruct an OSD to create some pgs + */ + +class MOSDPGCreate2 : public MessageInstance<MOSDPGCreate2> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + epoch_t epoch = 0; + map<spg_t,pair<epoch_t,utime_t>> pgs; + + MOSDPGCreate2() + : MessageInstance(MSG_OSD_PG_CREATE2, HEAD_VERSION, COMPAT_VERSION) {} + MOSDPGCreate2(epoch_t e) + : MessageInstance(MSG_OSD_PG_CREATE2, HEAD_VERSION, COMPAT_VERSION), + epoch(e) { } +private: + ~MOSDPGCreate2() override {} + +public: + std::string_view get_type_name() const override { + return "pg_create2"; + } + void print(ostream& out) const override { + out << "pg_create2(e" << epoch << " " << pgs << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(pgs, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + using ceph::decode; + decode(epoch, p); + decode(pgs, p); + } +}; diff --git a/src/messages/MOSDPGCreated.h b/src/messages/MOSDPGCreated.h new file mode 100644 index 00000000..6ccb9f97 --- /dev/null +++ b/src/messages/MOSDPGCreated.h @@ -0,0 +1,35 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "osd/osd_types.h" +#include "messages/PaxosServiceMessage.h" + +class MOSDPGCreated : public MessageInstance<MOSDPGCreated, PaxosServiceMessage> { +public: + friend factory; + + pg_t pgid; + MOSDPGCreated() + : MessageInstance(MSG_OSD_PG_CREATED, 0) + {} + MOSDPGCreated(pg_t pgid) + : MessageInstance(MSG_OSD_PG_CREATED, 0), + pgid(pgid) + {} + std::string_view get_type_name() const override { return "pg_created"; } + void print(ostream& out) const override { + out << "osd_pg_created(" << pgid << ")"; + } + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(pgid, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(pgid, p); + } +}; diff --git a/src/messages/MOSDPGInfo.h b/src/messages/MOSDPGInfo.h new file mode 100644 index 00000000..461a0fa6 --- /dev/null +++ b/src/messages/MOSDPGInfo.h @@ -0,0 +1,75 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGINFO_H +#define CEPH_MOSDPGINFO_H + +#include "msg/Message.h" +#include "osd/osd_types.h" + +class MOSDPGInfo : public MessageInstance<MOSDPGInfo> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 5; + static constexpr int COMPAT_VERSION = 5; + + epoch_t epoch = 0; + +public: + vector<pair<pg_notify_t,PastIntervals> > pg_list; + + epoch_t get_epoch() const { return epoch; } + + MOSDPGInfo() + : MessageInstance(MSG_OSD_PG_INFO, HEAD_VERSION, COMPAT_VERSION) { + set_priority(CEPH_MSG_PRIO_HIGH); + } + MOSDPGInfo(version_t mv) + : MessageInstance(MSG_OSD_PG_INFO, HEAD_VERSION, COMPAT_VERSION), + epoch(mv) { + set_priority(CEPH_MSG_PRIO_HIGH); + } +private: + ~MOSDPGInfo() override {} + +public: + std::string_view get_type_name() const override { return "pg_info"; } + void print(ostream& out) const override { + out << "pg_info("; + for (auto i = pg_list.begin(); + i != pg_list.end(); + ++i) { + if (i != pg_list.begin()) + out << " "; + out << i->first << "=" << i->second; + } + out << " epoch " << epoch + << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(pg_list, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(pg_list, p); + } +}; + +#endif diff --git a/src/messages/MOSDPGLog.h b/src/messages/MOSDPGLog.h new file mode 100644 index 00000000..6c9728ef --- /dev/null +++ b/src/messages/MOSDPGLog.h @@ -0,0 +1,124 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGLOG_H +#define CEPH_MOSDPGLOG_H + +#include "messages/MOSDPeeringOp.h" + +class MOSDPGLog : public MessageInstance<MOSDPGLog, MOSDPeeringOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 5; + static constexpr int COMPAT_VERSION = 5; + + epoch_t epoch = 0; + /// query_epoch is the epoch of the query being responded to, or + /// the current epoch if this is not being sent in response to a + /// query. This allows the recipient to disregard responses to old + /// queries. + epoch_t query_epoch = 0; + +public: + shard_id_t to; + shard_id_t from; + pg_info_t info; + pg_log_t log; + pg_missing_t missing; + PastIntervals past_intervals; + + epoch_t get_epoch() const { return epoch; } + spg_t get_pgid() const { return spg_t(info.pgid.pgid, to); } + epoch_t get_query_epoch() const { return query_epoch; } + + spg_t get_spg() const override { + return spg_t(info.pgid.pgid, to); + } + epoch_t get_map_epoch() const override { + return epoch; + } + epoch_t get_min_epoch() const override { + return query_epoch; + } + + PGPeeringEvent *get_event() override { + return new PGPeeringEvent( + epoch, query_epoch, + MLogRec(pg_shard_t(get_source().num(), from), + this), + true, + new PGCreateInfo( + get_spg(), + query_epoch, + info.history, + past_intervals, + false)); + } + + MOSDPGLog() : MessageInstance(MSG_OSD_PG_LOG, HEAD_VERSION, COMPAT_VERSION) { + set_priority(CEPH_MSG_PRIO_HIGH); + } + MOSDPGLog(shard_id_t to, shard_id_t from, + version_t mv, pg_info_t& i, epoch_t query_epoch) + : MessageInstance(MSG_OSD_PG_LOG, HEAD_VERSION, COMPAT_VERSION), + epoch(mv), query_epoch(query_epoch), + to(to), from(from), + info(i) { + set_priority(CEPH_MSG_PRIO_HIGH); + } + +private: + ~MOSDPGLog() override {} + +public: + std::string_view get_type_name() const override { return "PGlog"; } + void inner_print(ostream& out) const override { + // NOTE: log is not const, but operator<< doesn't touch fields + // swapped out by OSD code. + out << "log " << log + << " pi " << past_intervals; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(info, payload); + encode(log, payload); + encode(missing, payload); + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + // pre-nautilus OSDs do not set last_peering_reset properly + encode(epoch, payload); + } else { + encode(query_epoch, payload); + } + encode(past_intervals, payload); + encode(to, payload); + encode(from, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(info, p); + log.decode(p, info.pgid.pool()); + missing.decode(p, info.pgid.pool()); + decode(query_epoch, p); + decode(past_intervals, p); + decode(to, p); + decode(from, p); + } +}; + +#endif diff --git a/src/messages/MOSDPGNotify.h b/src/messages/MOSDPGNotify.h new file mode 100644 index 00000000..4370eae3 --- /dev/null +++ b/src/messages/MOSDPGNotify.h @@ -0,0 +1,87 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDPGPEERNOTIFY_H +#define CEPH_MOSDPGPEERNOTIFY_H + +#include "msg/Message.h" + +#include "osd/osd_types.h" + +/* + * PGNotify - notify primary of my PGs and versions. + */ + +class MOSDPGNotify : public MessageInstance<MOSDPGNotify> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 6; + static constexpr int COMPAT_VERSION = 6; + + epoch_t epoch = 0; + /// query_epoch is the epoch of the query being responded to, or + /// the current epoch if this is not being sent in response to a + /// query. This allows the recipient to disregard responses to old + /// queries. + vector<pair<pg_notify_t,PastIntervals> > pg_list; // pgid -> version + + public: + version_t get_epoch() const { return epoch; } + const vector<pair<pg_notify_t,PastIntervals> >& get_pg_list() const { + return pg_list; + } + + MOSDPGNotify() + : MessageInstance(MSG_OSD_PG_NOTIFY, HEAD_VERSION, COMPAT_VERSION) { + set_priority(CEPH_MSG_PRIO_HIGH); + } + MOSDPGNotify(epoch_t e, vector<pair<pg_notify_t,PastIntervals> >& l) + : MessageInstance(MSG_OSD_PG_NOTIFY, HEAD_VERSION, COMPAT_VERSION), + epoch(e) { + pg_list.swap(l); + set_priority(CEPH_MSG_PRIO_HIGH); + } +private: + ~MOSDPGNotify() override {} + +public: + std::string_view get_type_name() const override { return "PGnot"; } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(pg_list, payload); + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(pg_list, p); + } + void print(ostream& out) const override { + out << "pg_notify("; + for (auto i = pg_list.begin(); + i != pg_list.end(); + ++i) { + if (i != pg_list.begin()) + out << " "; + out << i->first << "=" << i->second; + } + out << " epoch " << epoch + << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGPull.h b/src/messages/MOSDPGPull.h new file mode 100644 index 00000000..16eeca7e --- /dev/null +++ b/src/messages/MOSDPGPull.h @@ -0,0 +1,106 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDPGPULL_H +#define MOSDPGPULL_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGPull : public MessageInstance<MOSDPGPull, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 2; + + vector<PullOp> pulls; + +public: + pg_shard_t from; + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + uint64_t cost; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + void take_pulls(vector<PullOp> *outpulls) { + outpulls->swap(pulls); + } + void set_pulls(vector<PullOp> *inpulls) { + inpulls->swap(pulls); + } + + MOSDPGPull() + : MessageInstance(MSG_OSD_PG_PULL, HEAD_VERSION, COMPAT_VERSION), + cost(0) + {} + + void compute_cost(CephContext *cct) { + cost = 0; + for (vector<PullOp>::iterator i = pulls.begin(); + i != pulls.end(); + ++i) { + cost += i->cost(cct); + } + } + + int get_cost() const override { + return cost; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(map_epoch, p); + decode(pulls, p); + decode(cost, p); + decode(pgid.shard, p); + decode(from, p); + if (header.version >= 3) { + decode(min_epoch, p); + } else { + min_epoch = map_epoch; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid.pgid, payload); + encode(map_epoch, payload); + encode(pulls, payload, features); + encode(cost, payload); + encode(pgid.shard, payload); + encode(from, payload); + encode(min_epoch, payload); + } + + std::string_view get_type_name() const override { return "MOSDPGPull"; } + + void print(ostream& out) const override { + out << "MOSDPGPull(" << pgid + << " e" << map_epoch << "/" << min_epoch + << " cost " << cost + << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGPush.h b/src/messages/MOSDPGPush.h new file mode 100644 index 00000000..3960ad70 --- /dev/null +++ b/src/messages/MOSDPGPush.h @@ -0,0 +1,112 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDPGPUSH_H +#define MOSDPGPUSH_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGPush : public MessageInstance<MOSDPGPush, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 2; + +public: + pg_shard_t from; + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + vector<PushOp> pushes; + bool is_repair = false; + +private: + uint64_t cost; + +public: + void compute_cost(CephContext *cct) { + cost = 0; + for (vector<PushOp>::iterator i = pushes.begin(); + i != pushes.end(); + ++i) { + cost += i->cost(cct); + } + } + + int get_cost() const override { + return cost; + } + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + void set_cost(uint64_t c) { + cost = c; + } + + MOSDPGPush() + : MessageInstance(MSG_OSD_PG_PUSH, HEAD_VERSION, COMPAT_VERSION), + cost(0) + {} + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(map_epoch, p); + decode(pushes, p); + decode(cost, p); + decode(pgid.shard, p); + decode(from, p); + if (header.version >= 3) { + decode(min_epoch, p); + } else { + min_epoch = map_epoch; + } + if (header.version >= 4) { + decode(is_repair, p); + } else { + is_repair = false; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid.pgid, payload); + encode(map_epoch, payload); + encode(pushes, payload, features); + encode(cost, payload); + encode(pgid.shard, payload); + encode(from, payload); + encode(min_epoch, payload); + encode(is_repair, payload); + } + + std::string_view get_type_name() const override { return "MOSDPGPush"; } + + void print(ostream& out) const override { + out << "MOSDPGPush(" << pgid + << " " << map_epoch << "/" << min_epoch + << " " << pushes; + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGPushReply.h b/src/messages/MOSDPGPushReply.h new file mode 100644 index 00000000..b9b7687e --- /dev/null +++ b/src/messages/MOSDPGPushReply.h @@ -0,0 +1,98 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 Inktank Storage, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef MOSDPGPUSHREPLY_H +#define MOSDPGPUSHREPLY_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGPushReply : public MessageInstance<MOSDPGPushReply, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 2; + +public: + pg_shard_t from; + spg_t pgid; + epoch_t map_epoch = 0, min_epoch = 0; + vector<PushReplyOp> replies; + uint64_t cost; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDPGPushReply() + : MessageInstance(MSG_OSD_PG_PUSH_REPLY, HEAD_VERSION, COMPAT_VERSION), + cost(0) + {} + + void compute_cost(CephContext *cct) { + cost = 0; + for (vector<PushReplyOp>::iterator i = replies.begin(); + i != replies.end(); + ++i) { + cost += i->cost(cct); + } + } + + int get_cost() const override { + return cost; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(map_epoch, p); + decode(replies, p); + decode(cost, p); + decode(pgid.shard, p); + decode(from, p); + if (header.version >= 3) { + decode(min_epoch, p); + } else { + min_epoch = map_epoch; + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid.pgid, payload); + encode(map_epoch, payload); + encode(replies, payload); + encode(cost, payload); + encode(pgid.shard, payload); + encode(from, payload); + encode(min_epoch, payload); + } + + void print(ostream& out) const override { + out << "MOSDPGPushReply(" << pgid + << " " << map_epoch << "/" << min_epoch + << " " << replies; + out << ")"; + } + + std::string_view get_type_name() const override { return "MOSDPGPushReply"; } +}; + +#endif diff --git a/src/messages/MOSDPGQuery.h b/src/messages/MOSDPGQuery.h new file mode 100644 index 00000000..d1d9ecd9 --- /dev/null +++ b/src/messages/MOSDPGQuery.h @@ -0,0 +1,80 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGQUERY_H +#define CEPH_MOSDPGQUERY_H + +#include "common/hobject.h" +#include "msg/Message.h" + +/* + * PGQuery - query another OSD as to the contents of their PGs + */ + +class MOSDPGQuery : public MessageInstance<MOSDPGQuery> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 4; + + version_t epoch = 0; + + public: + version_t get_epoch() const { return epoch; } + map<spg_t, pg_query_t> pg_list; + + MOSDPGQuery() : MessageInstance(MSG_OSD_PG_QUERY, + HEAD_VERSION, + COMPAT_VERSION) { + set_priority(CEPH_MSG_PRIO_HIGH); + } + MOSDPGQuery(epoch_t e, map<spg_t,pg_query_t>& ls) : + MessageInstance(MSG_OSD_PG_QUERY, + HEAD_VERSION, + COMPAT_VERSION), + epoch(e) { + pg_list.swap(ls); + set_priority(CEPH_MSG_PRIO_HIGH); + } +private: + ~MOSDPGQuery() override {} + +public: + std::string_view get_type_name() const override { return "pg_query"; } + void print(ostream& out) const override { + out << "pg_query("; + for (map<spg_t,pg_query_t>::const_iterator p = pg_list.begin(); + p != pg_list.end(); ++p) { + if (p != pg_list.begin()) + out << ","; + out << p->first; + } + out << " epoch " << epoch << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(pg_list, payload, features); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(pg_list, p); + } +}; + +#endif diff --git a/src/messages/MOSDPGReadyToMerge.h b/src/messages/MOSDPGReadyToMerge.h new file mode 100644 index 00000000..b8c18095 --- /dev/null +++ b/src/messages/MOSDPGReadyToMerge.h @@ -0,0 +1,58 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +class MOSDPGReadyToMerge + : public MessageInstance<MOSDPGReadyToMerge, PaxosServiceMessage> { +public: + pg_t pgid; + eversion_t source_version, target_version; + epoch_t last_epoch_started = 0; + epoch_t last_epoch_clean = 0; + bool ready = true; + + MOSDPGReadyToMerge() + : MessageInstance(MSG_OSD_PG_READY_TO_MERGE, 0) + {} + MOSDPGReadyToMerge(pg_t p, eversion_t sv, eversion_t tv, + epoch_t les, epoch_t lec, bool r, epoch_t v) + : MessageInstance(MSG_OSD_PG_READY_TO_MERGE, v), + pgid(p), + source_version(sv), + target_version(tv), + last_epoch_started(les), + last_epoch_clean(lec), + ready(r) + {} + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(pgid, payload); + encode(source_version, payload); + encode(target_version, payload); + encode(last_epoch_started, payload); + encode(last_epoch_clean, payload); + encode(ready, payload); + } + void decode_payload() override { + bufferlist::const_iterator p = payload.begin(); + paxos_decode(p); + decode(pgid, p); + decode(source_version, p); + decode(target_version, p); + decode(last_epoch_started, p); + decode(last_epoch_clean, p); + decode(ready, p); + } + std::string_view get_type_name() const override { return "osd_pg_ready_to_merge"; } + void print(ostream &out) const { + out << get_type_name() + << "(" << pgid + << " sv " << source_version + << " tv " << target_version + << " les/c " << last_epoch_started << "/" << last_epoch_clean + << (ready ? " ready" : " NOT READY") + << " v" << version << ")"; + } +}; diff --git a/src/messages/MOSDPGRecoveryDelete.h b/src/messages/MOSDPGRecoveryDelete.h new file mode 100644 index 00000000..c6fa1366 --- /dev/null +++ b/src/messages/MOSDPGRecoveryDelete.h @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MOSDPGRECOVERYDELETE_H +#define CEPH_MOSDPGRECOVERYDELETE_H + +#include "MOSDFastDispatchOp.h" + +/* + * instruct non-primary to remove some objects during recovery + */ + +class MOSDPGRecoveryDelete : public MessageInstance<MOSDPGRecoveryDelete, MOSDFastDispatchOp> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + + pg_shard_t from; + spg_t pgid; ///< target spg_t + epoch_t map_epoch, min_epoch; + list<pair<hobject_t, eversion_t> > objects; ///< objects to remove + +private: + uint64_t cost; + +public: + int get_cost() const override { + return cost; + } + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + void set_cost(uint64_t c) { + cost = c; + } + + MOSDPGRecoveryDelete() + : MessageInstance(MSG_OSD_PG_RECOVERY_DELETE, HEAD_VERSION, + COMPAT_VERSION), cost(0) {} + + MOSDPGRecoveryDelete(pg_shard_t from, spg_t pgid, epoch_t map_epoch, + epoch_t min_epoch) + : MessageInstance(MSG_OSD_PG_RECOVERY_DELETE, HEAD_VERSION, + COMPAT_VERSION), + from(from), + pgid(pgid), + map_epoch(map_epoch), + min_epoch(min_epoch), + cost(0) {} + +private: + ~MOSDPGRecoveryDelete() {} + +public: + std::string_view get_type_name() const { return "recovery_delete"; } + void print(ostream& out) const { + out << "MOSDPGRecoveryDelete(" << pgid << " e" << map_epoch << "," + << min_epoch << " " << objects << ")"; + } + + void encode_payload(uint64_t features) { + using ceph::encode; + encode(from, payload); + encode(pgid, payload); + encode(map_epoch, payload); + encode(min_epoch, payload); + encode(cost, payload); + encode(objects, payload); + } + void decode_payload() { + auto p = payload.cbegin(); + decode(from, p); + decode(pgid, p); + decode(map_epoch, p); + decode(min_epoch, p); + decode(cost, p); + decode(objects, p); + } +}; + + + +#endif diff --git a/src/messages/MOSDPGRecoveryDeleteReply.h b/src/messages/MOSDPGRecoveryDeleteReply.h new file mode 100644 index 00000000..e6401774 --- /dev/null +++ b/src/messages/MOSDPGRecoveryDeleteReply.h @@ -0,0 +1,64 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef MOSDRECOVERYDELETEREPLY_H +#define MOSDRECOVERYDELETEREPLY_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGRecoveryDeleteReply : public MessageInstance<MOSDPGRecoveryDeleteReply, MOSDFastDispatchOp> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + + pg_shard_t from; + spg_t pgid; + epoch_t map_epoch, min_epoch; + list<pair<hobject_t, eversion_t> > objects; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDPGRecoveryDeleteReply() + : MessageInstance(MSG_OSD_PG_RECOVERY_DELETE_REPLY, HEAD_VERSION, COMPAT_VERSION), + map_epoch(0), min_epoch(0) + {} + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(map_epoch, p); + decode(min_epoch, p); + decode(objects, p); + decode(pgid.shard, p); + decode(from, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid.pgid, payload); + encode(map_epoch, payload); + encode(min_epoch, payload); + encode(objects, payload); + encode(pgid.shard, payload); + encode(from, payload); + } + + void print(ostream& out) const override { + out << "MOSDPGRecoveryDeleteReply(" << pgid + << " e" << map_epoch << "," << min_epoch << " " << objects << ")"; + } + + std::string_view get_type_name() const override { return "recovery_delete_reply"; } +}; + +#endif diff --git a/src/messages/MOSDPGRemove.h b/src/messages/MOSDPGRemove.h new file mode 100644 index 00000000..94e9885e --- /dev/null +++ b/src/messages/MOSDPGRemove.h @@ -0,0 +1,71 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGREMOVE_H +#define CEPH_MOSDPGREMOVE_H + +#include "common/hobject.h" +#include "msg/Message.h" + + +class MOSDPGRemove : public MessageInstance<MOSDPGRemove> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 3; + + epoch_t epoch = 0; + + public: + vector<spg_t> pg_list; + + epoch_t get_epoch() const { return epoch; } + + MOSDPGRemove() : + MessageInstance(MSG_OSD_PG_REMOVE, HEAD_VERSION, COMPAT_VERSION) {} + MOSDPGRemove(epoch_t e, vector<spg_t>& l) : + MessageInstance(MSG_OSD_PG_REMOVE, HEAD_VERSION, COMPAT_VERSION) { + this->epoch = e; + pg_list.swap(l); + } +private: + ~MOSDPGRemove() override {} + +public: + std::string_view get_type_name() const override { return "PGrm"; } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(pg_list, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(pg_list, p); + } + void print(ostream& out) const override { + out << "osd pg remove(" << "epoch " << epoch << "; "; + for (vector<spg_t>::const_iterator i = pg_list.begin(); + i != pg_list.end(); + ++i) { + out << "pg" << *i << "; "; + } + out << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGScan.h b/src/messages/MOSDPGScan.h new file mode 100644 index 00000000..99f0b0bd --- /dev/null +++ b/src/messages/MOSDPGScan.h @@ -0,0 +1,117 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDPGSCAN_H +#define CEPH_MOSDPGSCAN_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGScan : public MessageInstance<MOSDPGScan, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + +public: + enum { + OP_SCAN_GET_DIGEST = 1, // just objects and versions + OP_SCAN_DIGEST = 2, // result + }; + const char *get_op_name(int o) const { + switch (o) { + case OP_SCAN_GET_DIGEST: return "get_digest"; + case OP_SCAN_DIGEST: return "digest"; + default: return "???"; + } + } + + __u32 op = 0; + epoch_t map_epoch = 0, query_epoch = 0; + pg_shard_t from; + spg_t pgid; + hobject_t begin, end; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return query_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(op, p); + decode(map_epoch, p); + decode(query_epoch, p); + decode(pgid.pgid, p); + decode(begin, p); + decode(end, p); + + // handle hobject_t format upgrade + if (!begin.is_max() && begin.pool == -1) + begin.pool = pgid.pool(); + if (!end.is_max() && end.pool == -1) + end.pool = pgid.pool(); + + decode(from, p); + decode(pgid.shard, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(op, payload); + encode(map_epoch, payload); + if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) { + // pre-nautilus OSDs do not set last_peering_reset properly + encode(map_epoch, payload); + } else { + encode(query_epoch, payload); + } + encode(pgid.pgid, payload); + encode(begin, payload); + encode(end, payload); + encode(from, payload); + encode(pgid.shard, payload); + } + + MOSDPGScan() + : MessageInstance(MSG_OSD_PG_SCAN, HEAD_VERSION, COMPAT_VERSION) {} + MOSDPGScan(__u32 o, pg_shard_t from, + epoch_t e, epoch_t qe, spg_t p, hobject_t be, hobject_t en) + : MessageInstance(MSG_OSD_PG_SCAN, HEAD_VERSION, COMPAT_VERSION), + op(o), + map_epoch(e), query_epoch(qe), + from(from), + pgid(p), + begin(be), end(en) { + } +private: + ~MOSDPGScan() override {} + +public: + std::string_view get_type_name() const override { return "pg_scan"; } + void print(ostream& out) const override { + out << "pg_scan(" << get_op_name(op) + << " " << pgid + << " " << begin << "-" << end + << " e " << map_epoch << "/" << query_epoch + << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDPGTemp.h b/src/messages/MOSDPGTemp.h new file mode 100644 index 00000000..22a8602b --- /dev/null +++ b/src/messages/MOSDPGTemp.h @@ -0,0 +1,67 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + + +#ifndef CEPH_MOSDPGTEMP_H +#define CEPH_MOSDPGTEMP_H + +#include "messages/PaxosServiceMessage.h" + +class MOSDPGTemp : public MessageInstance<MOSDPGTemp, PaxosServiceMessage> { +public: + friend factory; + + epoch_t map_epoch = 0; + map<pg_t, vector<int32_t> > pg_temp; + bool forced = false; + + MOSDPGTemp(epoch_t e) + : MessageInstance(MSG_OSD_PGTEMP, e, HEAD_VERSION, COMPAT_VERSION), + map_epoch(e) + {} + MOSDPGTemp() + : MOSDPGTemp(0) + {} +private: + ~MOSDPGTemp() override {} + +public: + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(map_epoch, payload); + encode(pg_temp, payload); + encode(forced, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(map_epoch, p); + decode(pg_temp, p); + if (header.version >= 2) { + decode(forced, p); + } + } + + std::string_view get_type_name() const override { return "osd_pgtemp"; } + void print(ostream &out) const override { + out << "osd_pgtemp(e" << map_epoch << " " << pg_temp << " v" << version << ")"; + } +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; +}; + +#endif diff --git a/src/messages/MOSDPGTrim.h b/src/messages/MOSDPGTrim.h new file mode 100644 index 00000000..e596d12b --- /dev/null +++ b/src/messages/MOSDPGTrim.h @@ -0,0 +1,79 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDPGTRIM_H +#define CEPH_MOSDPGTRIM_H + +#include "msg/Message.h" +#include "messages/MOSDPeeringOp.h" + +class MOSDPGTrim : public MessageInstance<MOSDPGTrim, MOSDPeeringOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + +public: + epoch_t epoch = 0; + spg_t pgid; + eversion_t trim_to; + + epoch_t get_epoch() const { return epoch; } + spg_t get_spg() const { + return pgid; + } + epoch_t get_map_epoch() const { + return epoch; + } + epoch_t get_min_epoch() const { + return epoch; + } + PGPeeringEvent *get_event() override { + return new PGPeeringEvent( + epoch, + epoch, + MTrim(epoch, get_source().num(), pgid.shard, trim_to)); + } + + MOSDPGTrim() : MessageInstance(MSG_OSD_PG_TRIM, HEAD_VERSION, COMPAT_VERSION) {} + MOSDPGTrim(version_t mv, spg_t p, eversion_t tt) : + MessageInstance(MSG_OSD_PG_TRIM, HEAD_VERSION, COMPAT_VERSION), + epoch(mv), pgid(p), trim_to(tt) { } +private: + ~MOSDPGTrim() override {} + +public: + std::string_view get_type_name() const override { return "pg_trim"; } + void inner_print(ostream& out) const override { + out << trim_to; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(epoch, payload); + encode(pgid.pgid, payload); + encode(trim_to, payload); + encode(pgid.shard, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(epoch, p); + decode(pgid.pgid, p); + decode(trim_to, p); + decode(pgid.shard, p); + } +}; + +#endif diff --git a/src/messages/MOSDPGUpdateLogMissing.h b/src/messages/MOSDPGUpdateLogMissing.h new file mode 100644 index 00000000..cbf9485e --- /dev/null +++ b/src/messages/MOSDPGUpdateLogMissing.h @@ -0,0 +1,123 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGUPDATELOGMISSING_H +#define CEPH_MOSDPGUPDATELOGMISSING_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGUpdateLogMissing : public MessageInstance<MOSDPGUpdateLogMissing, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + + +public: + epoch_t map_epoch = 0, min_epoch = 0; + spg_t pgid; + shard_id_t from; + ceph_tid_t rep_tid = 0; + mempool::osd_pglog::list<pg_log_entry_t> entries; + // piggybacked osd/pg state + eversion_t pg_trim_to; // primary->replica: trim to here + eversion_t pg_roll_forward_to; // primary->replica: trim rollback info to here + + epoch_t get_epoch() const { return map_epoch; } + spg_t get_pgid() const { return pgid; } + epoch_t get_query_epoch() const { return map_epoch; } + ceph_tid_t get_tid() const { return rep_tid; } + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDPGUpdateLogMissing() + : MessageInstance(MSG_OSD_PG_UPDATE_LOG_MISSING, HEAD_VERSION, + COMPAT_VERSION) { } + MOSDPGUpdateLogMissing( + const mempool::osd_pglog::list<pg_log_entry_t> &entries, + spg_t pgid, + shard_id_t from, + epoch_t epoch, + epoch_t min_epoch, + ceph_tid_t rep_tid, + eversion_t pg_trim_to, + eversion_t pg_roll_forward_to) + : MessageInstance(MSG_OSD_PG_UPDATE_LOG_MISSING, HEAD_VERSION, + COMPAT_VERSION), + map_epoch(epoch), + min_epoch(min_epoch), + pgid(pgid), + from(from), + rep_tid(rep_tid), + entries(entries), + pg_trim_to(pg_trim_to), + pg_roll_forward_to(pg_roll_forward_to) + {} + +private: + ~MOSDPGUpdateLogMissing() override {} + +public: + std::string_view get_type_name() const override { return "PGUpdateLogMissing"; } + void print(ostream& out) const override { + out << "pg_update_log_missing(" << pgid << " epoch " << map_epoch + << "/" << min_epoch + << " rep_tid " << rep_tid + << " entries " << entries + << " trim_to " << pg_trim_to + << " roll_forward_to " << pg_roll_forward_to + << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(map_epoch, payload); + encode(pgid, payload); + encode(from, payload); + encode(rep_tid, payload); + encode(entries, payload); + encode(min_epoch, payload); + encode(pg_trim_to, payload); + encode(pg_roll_forward_to, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(map_epoch, p); + decode(pgid, p); + decode(from, p); + decode(rep_tid, p); + decode(entries, p); + if (header.version >= 2) { + decode(min_epoch, p); + } else { + min_epoch = map_epoch; + } + if (header.version >= 3) { + decode(pg_trim_to, p); + decode(pg_roll_forward_to, p); + } + } +}; + +#endif diff --git a/src/messages/MOSDPGUpdateLogMissingReply.h b/src/messages/MOSDPGUpdateLogMissingReply.h new file mode 100644 index 00000000..8d7050f2 --- /dev/null +++ b/src/messages/MOSDPGUpdateLogMissingReply.h @@ -0,0 +1,117 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDPGUPDATELOGMISSINGREPLY_H +#define CEPH_MOSDPGUPDATELOGMISSINGREPLY_H + +#include "MOSDFastDispatchOp.h" + +class MOSDPGUpdateLogMissingReply : public MessageInstance<MOSDPGUpdateLogMissingReply, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + + +public: + epoch_t map_epoch = 0, min_epoch = 0; + spg_t pgid; + shard_id_t from; + ceph_tid_t rep_tid = 0; + // piggybacked osd state + eversion_t last_complete_ondisk; + + epoch_t get_epoch() const { return map_epoch; } + spg_t get_pgid() const { return pgid; } + epoch_t get_query_epoch() const { return map_epoch; } + ceph_tid_t get_tid() const { return rep_tid; } + pg_shard_t get_from() const { + return pg_shard_t(get_source().num(), from); + } + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDPGUpdateLogMissingReply() + : MessageInstance( + MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY, + HEAD_VERSION, + COMPAT_VERSION) + {} + MOSDPGUpdateLogMissingReply( + spg_t pgid, + shard_id_t from, + epoch_t epoch, + epoch_t min_epoch, + ceph_tid_t rep_tid, + eversion_t last_complete_ondisk) + : MessageInstance( + MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY, + HEAD_VERSION, + COMPAT_VERSION), + map_epoch(epoch), + min_epoch(min_epoch), + pgid(pgid), + from(from), + rep_tid(rep_tid), + last_complete_ondisk(last_complete_ondisk) + {} + +private: + ~MOSDPGUpdateLogMissingReply() override {} + +public: + std::string_view get_type_name() const override { return "PGUpdateLogMissingReply"; } + void print(ostream& out) const override { + out << "pg_update_log_missing_reply(" << pgid << " epoch " << map_epoch + << "/" << min_epoch + << " rep_tid " << rep_tid + << " lcod " << last_complete_ondisk << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(map_epoch, payload); + encode(pgid, payload); + encode(from, payload); + encode(rep_tid, payload); + encode(min_epoch, payload); + encode(last_complete_ondisk, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(map_epoch, p); + decode(pgid, p); + decode(from, p); + decode(rep_tid, p); + if (header.version >= 2) { + decode(min_epoch, p); + } else { + min_epoch = map_epoch; + } + if (header.version >= 3) { + decode(last_complete_ondisk, p); + } + } +}; + +#endif diff --git a/src/messages/MOSDPeeringOp.h b/src/messages/MOSDPeeringOp.h new file mode 100644 index 00000000..25487488 --- /dev/null +++ b/src/messages/MOSDPeeringOp.h @@ -0,0 +1,28 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" +#include "osd/osd_types.h" +#include "osd/PGPeeringEvent.h" + +class MOSDPeeringOp : public MessageSubType<MOSDPeeringOp> { +public: + +template<typename... Args> + MOSDPeeringOp(Args&&... args) : MessageSubType(std::forward<Args>(args)...) {} + + void print(ostream& out) const override final { + out << get_type_name() << "(" + << get_spg() << " "; + inner_print(out); + out << " e" << get_map_epoch() << "/" << get_min_epoch() << ")"; + } + + virtual spg_t get_spg() const = 0; + virtual epoch_t get_map_epoch() const = 0; + virtual epoch_t get_min_epoch() const = 0; + virtual PGPeeringEvent *get_event() = 0; + virtual void inner_print(ostream& out) const = 0; +}; diff --git a/src/messages/MOSDPing.h b/src/messages/MOSDPing.h new file mode 100644 index 00000000..6a2693a0 --- /dev/null +++ b/src/messages/MOSDPing.h @@ -0,0 +1,130 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +/** + * This is used to send pings between daemons (so far, the OSDs) for + * heartbeat purposes. We include a timestamp and distinguish between + * outgoing pings and responses to those. If you set the + * min_message in the constructor, the message will inflate itself + * to the specified size -- this is good for dealing with network + * issues with jumbo frames. See http://tracker.ceph.com/issues/20087 + * + */ + +#ifndef CEPH_MOSDPING_H +#define CEPH_MOSDPING_H + +#include "common/Clock.h" + +#include "msg/Message.h" +#include "osd/osd_types.h" + + +class MOSDPing : public MessageInstance<MOSDPing> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 4; + + public: + enum { + HEARTBEAT = 0, + START_HEARTBEAT = 1, + YOU_DIED = 2, + STOP_HEARTBEAT = 3, + PING = 4, + PING_REPLY = 5, + }; + const char *get_op_name(int op) const { + switch (op) { + case HEARTBEAT: return "heartbeat"; + case START_HEARTBEAT: return "start_heartbeat"; + case STOP_HEARTBEAT: return "stop_heartbeat"; + case YOU_DIED: return "you_died"; + case PING: return "ping"; + case PING_REPLY: return "ping_reply"; + default: return "???"; + } + } + + uuid_d fsid; + epoch_t map_epoch = 0; + __u8 op = 0; + utime_t stamp; + uint32_t min_message_size; + + MOSDPing(const uuid_d& f, epoch_t e, __u8 o, utime_t s, uint32_t min_message) + : MessageInstance(MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION), + fsid(f), map_epoch(e), op(o), stamp(s), min_message_size(min_message) + { } + MOSDPing() + : MessageInstance(MSG_OSD_PING, HEAD_VERSION, COMPAT_VERSION), min_message_size(0) + {} +private: + ~MOSDPing() override {} + +public: + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(map_epoch, p); + decode(op, p); + decode(stamp, p); + + int payload_mid_length = p.get_off(); + uint32_t size; + decode(size, p); + p.advance(size); + min_message_size = size + payload_mid_length; + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(fsid, payload); + encode(map_epoch, payload); + encode(op, payload); + encode(stamp, payload); + + size_t s = 0; + if (min_message_size > payload.length()) { + s = min_message_size - payload.length(); + } + encode((uint32_t)s, payload); + if (s) { + // this should be big enough for normal min_message padding sizes. since + // we are targeting jumbo ethernet frames around 9000 bytes, 16k should + // be more than sufficient! the compiler will statically zero this so + // that at runtime we are only adding a bufferptr reference to it. + static char zeros[16384] = {}; + while (s > sizeof(zeros)) { + payload.append(buffer::create_static(sizeof(zeros), zeros)); + s -= sizeof(zeros); + } + if (s) { + payload.append(buffer::create_static(s, zeros)); + } + } + } + + std::string_view get_type_name() const override { return "osd_ping"; } + void print(ostream& out) const override { + out << "osd_ping(" << get_op_name(op) + << " e" << map_epoch + << " stamp " << stamp + << ")"; + } +}; + +#endif diff --git a/src/messages/MOSDRepOp.h b/src/messages/MOSDRepOp.h new file mode 100644 index 00000000..9d087f39 --- /dev/null +++ b/src/messages/MOSDRepOp.h @@ -0,0 +1,180 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDREPOP_H +#define CEPH_MOSDREPOP_H + +#include "MOSDFastDispatchOp.h" + +/* + * OSD sub op - for internal ops on pobjects between primary and replicas(/stripes/whatever) + */ + +class MOSDRepOp : public MessageInstance<MOSDRepOp, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + epoch_t map_epoch, min_epoch; + + // metadata from original request + osd_reqid_t reqid; + + spg_t pgid; + + bufferlist::const_iterator p; + // Decoding flags. Decoding is only needed for messages caught by pipe reader. + bool final_decode_needed; + + // subop + pg_shard_t from; + hobject_t poid; + + __u8 acks_wanted; + + // transaction to exec + bufferlist logbl; + pg_stat_t pg_stats; + + // subop metadata + eversion_t version; + + // piggybacked osd/og state + eversion_t pg_trim_to; // primary->replica: trim to here + eversion_t pg_roll_forward_to; // primary->replica: trim rollback + // info to here + + hobject_t new_temp_oid; ///< new temp object that we must now start tracking + hobject_t discard_temp_oid; ///< previously used temp object that we can now stop tracking + + /// non-empty if this transaction involves a hit_set history update + boost::optional<pg_hit_set_history_t> updated_hit_set_history; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + int get_cost() const override { + return data.length(); + } + + void decode_payload() override { + p = payload.cbegin(); + // split to partial and final + decode(map_epoch, p); + if (header.version >= 2) { + decode(min_epoch, p); + decode_trace(p); + } else { + min_epoch = map_epoch; + } + decode(reqid, p); + decode(pgid, p); + } + + void finish_decode() { + if (!final_decode_needed) + return; // Message is already final decoded + decode(poid, p); + + decode(acks_wanted, p); + decode(version, p); + decode(logbl, p); + decode(pg_stats, p); + decode(pg_trim_to, p); + + + decode(new_temp_oid, p); + decode(discard_temp_oid, p); + + decode(from, p); + decode(updated_hit_set_history, p); + decode(pg_roll_forward_to, p); + final_decode_needed = false; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(map_epoch, payload); + if (HAVE_FEATURE(features, SERVER_LUMINOUS)) { + header.version = HEAD_VERSION; + encode(min_epoch, payload); + encode_trace(payload, features); + } else { + header.version = 1; + } + encode(reqid, payload); + encode(pgid, payload); + encode(poid, payload); + + encode(acks_wanted, payload); + encode(version, payload); + encode(logbl, payload); + encode(pg_stats, payload); + encode(pg_trim_to, payload); + encode(new_temp_oid, payload); + encode(discard_temp_oid, payload); + encode(from, payload); + encode(updated_hit_set_history, payload); + encode(pg_roll_forward_to, payload); + } + + MOSDRepOp() + : MessageInstance(MSG_OSD_REPOP, HEAD_VERSION, COMPAT_VERSION), + map_epoch(0), + final_decode_needed(true), acks_wanted (0) {} + MOSDRepOp(osd_reqid_t r, pg_shard_t from, + spg_t p, const hobject_t& po, int aw, + epoch_t mape, epoch_t min_epoch, ceph_tid_t rtid, eversion_t v) + : MessageInstance(MSG_OSD_REPOP, HEAD_VERSION, COMPAT_VERSION), + map_epoch(mape), + min_epoch(min_epoch), + reqid(r), + pgid(p), + final_decode_needed(false), + from(from), + poid(po), + acks_wanted(aw), + version(v) { + set_tid(rtid); + } +private: + ~MOSDRepOp() override {} + +public: + std::string_view get_type_name() const override { return "osd_repop"; } + void print(ostream& out) const override { + out << "osd_repop(" << reqid + << " " << pgid << " e" << map_epoch << "/" << min_epoch; + if (!final_decode_needed) { + out << " " << poid << " v " << version; + if (updated_hit_set_history) + out << ", has_updated_hit_set_history"; + } + out << ")"; + } +}; + + +#endif diff --git a/src/messages/MOSDRepOpReply.h b/src/messages/MOSDRepOpReply.h new file mode 100644 index 00000000..9ca3a54f --- /dev/null +++ b/src/messages/MOSDRepOpReply.h @@ -0,0 +1,161 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDREPOPREPLY_H +#define CEPH_MOSDREPOPREPLY_H + +#include "MOSDFastDispatchOp.h" + +/* + * OSD Client Subop reply + * + * oid - object id + * op - OSD_OP_DELETE, etc. + * + */ + +class MOSDRepOpReply : public MessageInstance<MOSDRepOpReply, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; +public: + epoch_t map_epoch, min_epoch; + + // subop metadata + osd_reqid_t reqid; + pg_shard_t from; + spg_t pgid; + + // result + __u8 ack_type; + int32_t result; + + // piggybacked osd state + eversion_t last_complete_ondisk; + + bufferlist::const_iterator p; + // Decoding flags. Decoding is only needed for messages caught by pipe reader. + bool final_decode_needed; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + void decode_payload() override { + p = payload.cbegin(); + decode(map_epoch, p); + if (header.version >= 2) { + decode(min_epoch, p); + decode_trace(p); + } else { + min_epoch = map_epoch; + } + decode(reqid, p); + decode(pgid, p); + } + + void finish_decode() { + if (!final_decode_needed) + return; // Message is already final decoded + decode(ack_type, p); + decode(result, p); + decode(last_complete_ondisk, p); + + decode(from, p); + final_decode_needed = false; + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(map_epoch, payload); + if (HAVE_FEATURE(features, SERVER_LUMINOUS)) { + header.version = HEAD_VERSION; + encode(min_epoch, payload); + encode_trace(payload, features); + } else { + header.version = 1; + } + encode(reqid, payload); + encode(pgid, payload); + encode(ack_type, payload); + encode(result, payload); + encode(last_complete_ondisk, payload); + encode(from, payload); + } + + spg_t get_pg() { return pgid; } + + int get_ack_type() { return ack_type; } + bool is_ondisk() { return ack_type & CEPH_OSD_FLAG_ONDISK; } + bool is_onnvram() { return ack_type & CEPH_OSD_FLAG_ONNVRAM; } + + int get_result() { return result; } + + void set_last_complete_ondisk(eversion_t v) { last_complete_ondisk = v; } + eversion_t get_last_complete_ondisk() const { return last_complete_ondisk; } + +public: + MOSDRepOpReply( + const MOSDRepOp *req, pg_shard_t from, int result_, epoch_t e, epoch_t mine, + int at) : + MessageInstance(MSG_OSD_REPOPREPLY, HEAD_VERSION, COMPAT_VERSION), + map_epoch(e), + min_epoch(mine), + reqid(req->reqid), + from(from), + pgid(req->pgid.pgid, req->from.shard), + ack_type(at), + result(result_), + final_decode_needed(false) { + set_tid(req->get_tid()); + } + MOSDRepOpReply() + : MessageInstance(MSG_OSD_REPOPREPLY, HEAD_VERSION, COMPAT_VERSION), + map_epoch(0), + min_epoch(0), + ack_type(0), result(0), + final_decode_needed(true) {} +private: + ~MOSDRepOpReply() override {} + +public: + std::string_view get_type_name() const override { return "osd_repop_reply"; } + + void print(ostream& out) const override { + out << "osd_repop_reply(" << reqid + << " " << pgid << " e" << map_epoch << "/" << min_epoch; + if (!final_decode_needed) { + if (ack_type & CEPH_OSD_FLAG_ONDISK) + out << " ondisk"; + if (ack_type & CEPH_OSD_FLAG_ONNVRAM) + out << " onnvram"; + if (ack_type & CEPH_OSD_FLAG_ACK) + out << " ack"; + out << ", result = " << result; + } + out << ")"; + } + +}; + + +#endif diff --git a/src/messages/MOSDRepScrub.h b/src/messages/MOSDRepScrub.h new file mode 100644 index 00000000..40867bed --- /dev/null +++ b/src/messages/MOSDRepScrub.h @@ -0,0 +1,143 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDREPSCRUB_H +#define CEPH_MOSDREPSCRUB_H + +#include "MOSDFastDispatchOp.h" + +/* + * instruct an OSD initiate a replica scrub on a specific PG + */ + +class MOSDRepScrub : public MessageInstance<MOSDRepScrub, MOSDFastDispatchOp> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 9; + static constexpr int COMPAT_VERSION = 6; + + spg_t pgid; // PG to scrub + eversion_t scrub_from; // only scrub log entries after scrub_from + eversion_t scrub_to; // last_update_applied when message sent + epoch_t map_epoch = 0, min_epoch = 0; + bool chunky; // true for chunky scrubs + hobject_t start; // lower bound of scrub, inclusive + hobject_t end; // upper bound of scrub, exclusive + bool deep; // true if scrub should be deep + bool allow_preemption = false; + int32_t priority = 0; + bool high_priority = false; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + epoch_t get_min_epoch() const override { + return min_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDRepScrub() + : MessageInstance(MSG_OSD_REP_SCRUB, HEAD_VERSION, COMPAT_VERSION), + chunky(false), + deep(false) { } + + MOSDRepScrub(spg_t pgid, eversion_t scrub_to, epoch_t map_epoch, epoch_t min_epoch, + hobject_t start, hobject_t end, bool deep, + bool preemption, int prio, bool highprio) + : MessageInstance(MSG_OSD_REP_SCRUB, HEAD_VERSION, COMPAT_VERSION), + pgid(pgid), + scrub_to(scrub_to), + map_epoch(map_epoch), + min_epoch(min_epoch), + chunky(true), + start(start), + end(end), + deep(deep), + allow_preemption(preemption), + priority(prio), + high_priority(highprio) { } + + +private: + ~MOSDRepScrub() override {} + +public: + std::string_view get_type_name() const override { return "replica scrub"; } + void print(ostream& out) const override { + out << "replica_scrub(pg: " << pgid + << ",from:" << scrub_from + << ",to:" << scrub_to + << ",epoch:" << map_epoch << "/" << min_epoch + << ",start:" << start << ",end:" << end + << ",chunky:" << chunky + << ",deep:" << deep + << ",version:" << header.version + << ",allow_preemption:" << (int)allow_preemption + << ",priority=" << priority + << (high_priority ? " (high)":"") + << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid.pgid, payload); + encode(scrub_from, payload); + encode(scrub_to, payload); + encode(map_epoch, payload); + encode(chunky, payload); + encode(start, payload); + encode(end, payload); + encode(deep, payload); + encode(pgid.shard, payload); + encode((uint32_t)-1, payload); // seed + encode(min_epoch, payload); + encode(allow_preemption, payload); + encode(priority, payload); + encode(high_priority, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(scrub_from, p); + decode(scrub_to, p); + decode(map_epoch, p); + decode(chunky, p); + decode(start, p); + decode(end, p); + decode(deep, p); + decode(pgid.shard, p); + { + uint32_t seed; + decode(seed, p); + } + if (header.version >= 7) { + decode(min_epoch, p); + } else { + min_epoch = map_epoch; + } + if (header.version >= 8) { + decode(allow_preemption, p); + } + if (header.version >= 9) { + decode(priority, p); + decode(high_priority, p); + } + } +}; + +#endif diff --git a/src/messages/MOSDRepScrubMap.h b/src/messages/MOSDRepScrubMap.h new file mode 100644 index 00000000..984ebb4f --- /dev/null +++ b/src/messages/MOSDRepScrubMap.h @@ -0,0 +1,83 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2017 Sage Weil <sage@redhat.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDREPSCRUBMAP_H +#define CEPH_MOSDREPSCRUBMAP_H + +#include "MOSDFastDispatchOp.h" + +/* + * pass a ScrubMap from a shard back to the primary + */ + +class MOSDRepScrubMap : public MessageInstance<MOSDRepScrubMap, MOSDFastDispatchOp> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + + spg_t pgid; // primary spg_t + epoch_t map_epoch = 0; + pg_shard_t from; // whose scrubmap this is + bufferlist scrub_map_bl; + bool preempted = false; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDRepScrubMap() + : MessageInstance(MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION) {} + + MOSDRepScrubMap(spg_t pgid, epoch_t map_epoch, pg_shard_t from) + : MessageInstance(MSG_OSD_REP_SCRUBMAP, HEAD_VERSION, COMPAT_VERSION), + pgid(pgid), + map_epoch(map_epoch), + from(from) {} + +private: + ~MOSDRepScrubMap() {} + +public: + std::string_view get_type_name() const override { return "rep_scrubmap"; } + void print(ostream& out) const override { + out << "rep_scrubmap(" << pgid << " e" << map_epoch + << " from shard " << from + << (preempted ? " PREEMPTED":"") << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(from, payload); + encode(preempted, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(from, p); + if (header.version >= 2) { + decode(preempted, p); + } + } +}; + + +#endif diff --git a/src/messages/MOSDScrub.h b/src/messages/MOSDScrub.h new file mode 100644 index 00000000..8df54670 --- /dev/null +++ b/src/messages/MOSDScrub.h @@ -0,0 +1,78 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MOSDSCRUB_H +#define CEPH_MOSDSCRUB_H + +#include "msg/Message.h" + +/* + * instruct an OSD to scrub some or all pg(s) + */ + +class MOSDScrub : public MessageInstance<MOSDScrub> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 2; + + uuid_d fsid; + vector<pg_t> scrub_pgs; + bool repair = false; + bool deep = false; + + MOSDScrub() : MessageInstance(MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION) {} + MOSDScrub(const uuid_d& f, bool r, bool d) : + MessageInstance(MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION), + fsid(f), repair(r), deep(d) {} + MOSDScrub(const uuid_d& f, vector<pg_t>& pgs, bool r, bool d) : + MessageInstance(MSG_OSD_SCRUB, HEAD_VERSION, COMPAT_VERSION), + fsid(f), scrub_pgs(pgs), repair(r), deep(d) {} +private: + ~MOSDScrub() override {} + +public: + std::string_view get_type_name() const override { return "scrub"; } + void print(ostream& out) const override { + out << "scrub("; + if (scrub_pgs.empty()) + out << "osd"; + else + out << scrub_pgs; + if (repair) + out << " repair"; + if (deep) + out << " deep"; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(fsid, payload); + encode(scrub_pgs, payload); + encode(repair, payload); + encode(deep, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(scrub_pgs, p); + decode(repair, p); + decode(deep, p); + } +}; + +#endif diff --git a/src/messages/MOSDScrub2.h b/src/messages/MOSDScrub2.h new file mode 100644 index 00000000..98fb0f31 --- /dev/null +++ b/src/messages/MOSDScrub2.h @@ -0,0 +1,59 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" + +/* + * instruct an OSD to scrub some or all pg(s) + */ + +class MOSDScrub2 : public MessageInstance<MOSDScrub2> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + uuid_d fsid; + epoch_t epoch; + vector<spg_t> scrub_pgs; + bool repair = false; + bool deep = false; + + MOSDScrub2() : MessageInstance(MSG_OSD_SCRUB2, HEAD_VERSION, COMPAT_VERSION) {} + MOSDScrub2(const uuid_d& f, epoch_t e, vector<spg_t>& pgs, bool r, bool d) : + MessageInstance(MSG_OSD_SCRUB2, HEAD_VERSION, COMPAT_VERSION), + fsid(f), epoch(e), scrub_pgs(pgs), repair(r), deep(d) {} +private: + ~MOSDScrub2() override {} + +public: + std::string_view get_type_name() const override { return "scrub2"; } + void print(ostream& out) const override { + out << "scrub2(" << scrub_pgs; + if (repair) + out << " repair"; + if (deep) + out << " deep"; + out << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(fsid, payload); + encode(epoch, payload); + encode(scrub_pgs, payload); + encode(repair, payload); + encode(deep, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(fsid, p); + decode(epoch, p); + decode(scrub_pgs, p); + decode(repair, p); + decode(deep, p); + } +}; diff --git a/src/messages/MOSDScrubReserve.h b/src/messages/MOSDScrubReserve.h new file mode 100644 index 00000000..a75796f9 --- /dev/null +++ b/src/messages/MOSDScrubReserve.h @@ -0,0 +1,97 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MOSDSCRUBRESERVE_H +#define CEPH_MOSDSCRUBRESERVE_H + +#include "MOSDFastDispatchOp.h" + +class MOSDScrubReserve : public MessageInstance<MOSDScrubReserve, MOSDFastDispatchOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; +public: + spg_t pgid; + epoch_t map_epoch; + enum { + REQUEST = 0, + GRANT = 1, + RELEASE = 2, + REJECT = 3, + }; + int32_t type; + pg_shard_t from; + + epoch_t get_map_epoch() const override { + return map_epoch; + } + spg_t get_spg() const override { + return pgid; + } + + MOSDScrubReserve() + : MessageInstance(MSG_OSD_SCRUB_RESERVE, HEAD_VERSION, COMPAT_VERSION), + map_epoch(0), type(-1) {} + MOSDScrubReserve(spg_t pgid, + epoch_t map_epoch, + int type, + pg_shard_t from) + : MessageInstance(MSG_OSD_SCRUB_RESERVE, HEAD_VERSION, COMPAT_VERSION), + pgid(pgid), map_epoch(map_epoch), + type(type), from(from) {} + + std::string_view get_type_name() const { + return "MOSDScrubReserve"; + } + + void print(ostream& out) const { + out << "MOSDScrubReserve(" << pgid << " "; + switch (type) { + case REQUEST: + out << "REQUEST "; + break; + case GRANT: + out << "GRANT "; + break; + case REJECT: + out << "REJECT "; + break; + case RELEASE: + out << "RELEASE "; + break; + } + out << "e" << map_epoch << ")"; + return; + } + + void decode_payload() { + auto p = payload.cbegin(); + decode(pgid, p); + decode(map_epoch, p); + decode(type, p); + decode(from, p); + } + + void encode_payload(uint64_t features) { + using ceph::encode; + encode(pgid, payload); + encode(map_epoch, payload); + encode(type, payload); + encode(from, payload); + } +}; + +#endif diff --git a/src/messages/MPGStats.h b/src/messages/MPGStats.h new file mode 100644 index 00000000..e0a299eb --- /dev/null +++ b/src/messages/MPGStats.h @@ -0,0 +1,78 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MPGSTATS_H +#define CEPH_MPGSTATS_H + +#include "osd/osd_types.h" +#include "messages/PaxosServiceMessage.h" + +class MPGStats : public MessageInstance<MPGStats, PaxosServiceMessage> { + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; +public: + friend factory; + + uuid_d fsid; + map<pg_t, pg_stat_t> pg_stat; + osd_stat_t osd_stat; + map<int64_t, store_statfs_t> pool_stat; + epoch_t epoch = 0; + utime_t had_map_for; + + MPGStats() : MessageInstance(MSG_PGSTATS, 0, HEAD_VERSION, COMPAT_VERSION) {} + MPGStats(const uuid_d& f, epoch_t e, utime_t had) + : MessageInstance(MSG_PGSTATS, 0, HEAD_VERSION, COMPAT_VERSION), + fsid(f), + epoch(e), + had_map_for(had) + {} + +private: + ~MPGStats() override {} + +public: + std::string_view get_type_name() const override { return "pg_stats"; } + void print(ostream& out) const override { + out << "pg_stats(" << pg_stat.size() << " pgs tid " << get_tid() << " v " << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(osd_stat, payload, features); + encode(pg_stat, payload); + encode(epoch, payload); + encode(had_map_for, payload); + encode(pool_stat, payload, features); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(osd_stat, p); + if (osd_stat.num_osds == 0) { + // for the benefit of legacy OSDs who don't set this field + osd_stat.num_osds = 1; + } + decode(pg_stat, p); + decode(epoch, p); + decode(had_map_for, p); + if (header.version >= 2) + decode(pool_stat, p); + } +}; + +#endif diff --git a/src/messages/MPGStatsAck.h b/src/messages/MPGStatsAck.h new file mode 100644 index 00000000..5fe78bfc --- /dev/null +++ b/src/messages/MPGStatsAck.h @@ -0,0 +1,47 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MPGSTATSACK_H +#define CEPH_MPGSTATSACK_H + +#include "osd/osd_types.h" + +class MPGStatsAck : public MessageInstance<MPGStatsAck> { +public: + friend factory; + + map<pg_t,pair<version_t,epoch_t> > pg_stat; + + MPGStatsAck() : MessageInstance(MSG_PGSTATSACK) {} + +private: + ~MPGStatsAck() override {} + +public: + std::string_view get_type_name() const override { return "pg_stats_ack"; } + void print(ostream& out) const override { + out << "pg_stats_ack(" << pg_stat.size() << " pgs tid " << get_tid() << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pg_stat, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(pg_stat, p); + } +}; + +#endif diff --git a/src/messages/MPing.h b/src/messages/MPing.h new file mode 100644 index 00000000..4175a1d5 --- /dev/null +++ b/src/messages/MPing.h @@ -0,0 +1,35 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MPING_H +#define CEPH_MPING_H + +#include "msg/Message.h" + +class MPing : public MessageInstance<MPing> { +public: + friend factory; + + MPing() : MessageInstance(CEPH_MSG_PING) {} +private: + ~MPing() override {} + +public: + void decode_payload() override { } + void encode_payload(uint64_t features) override { } + std::string_view get_type_name() const override { return "ping"; } +}; + +#endif diff --git a/src/messages/MPoolOp.h b/src/messages/MPoolOp.h new file mode 100644 index 00000000..d13c8771 --- /dev/null +++ b/src/messages/MPoolOp.h @@ -0,0 +1,96 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MPOOLOP_H +#define CEPH_MPOOLOP_H + +#include "messages/PaxosServiceMessage.h" + + +class MPoolOp : public MessageInstance<MPoolOp, PaxosServiceMessage> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 4; + static constexpr int COMPAT_VERSION = 2; + +public: + uuid_d fsid; + __u32 pool = 0; + string name; + __u32 op = 0; + snapid_t snapid; + __s16 crush_rule = 0; + + MPoolOp() + : MessageInstance(CEPH_MSG_POOLOP, 0, HEAD_VERSION, COMPAT_VERSION) { } + MPoolOp(const uuid_d& f, ceph_tid_t t, int p, string& n, int o, version_t v) + : MessageInstance(CEPH_MSG_POOLOP, v, HEAD_VERSION, COMPAT_VERSION), + fsid(f), pool(p), name(n), op(o), + snapid(0), crush_rule(0) { + set_tid(t); + } + +private: + ~MPoolOp() override {} + +public: + std::string_view get_type_name() const override { return "poolop"; } + void print(ostream& out) const override { + out << "pool_op(" << ceph_pool_op_name(op) << " pool " << pool + << " tid " << get_tid() + << " name " << name + << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(pool, payload); + encode(op, payload); + encode((uint64_t)0, payload); + encode(snapid, payload); + encode(name, payload); + __u8 pad = 0; + encode(pad, payload); /* for v3->v4 encoding change */ + encode(crush_rule, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(pool, p); + if (header.version < 2) + decode(name, p); + decode(op, p); + uint64_t old_auid; + decode(old_auid, p); + decode(snapid, p); + if (header.version >= 2) + decode(name, p); + + if (header.version >= 3) { + __u8 pad; + decode(pad, p); + if (header.version >= 4) + decode(crush_rule, p); + else + crush_rule = pad; + } else + crush_rule = -1; + } +}; + +#endif diff --git a/src/messages/MPoolOpReply.h b/src/messages/MPoolOpReply.h new file mode 100644 index 00000000..41a6dfbb --- /dev/null +++ b/src/messages/MPoolOpReply.h @@ -0,0 +1,83 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MPOOLOPREPLY_H +#define CEPH_MPOOLOPREPLY_H + +#include "common/errno.h" + +class MPoolOpReply : public MessageInstance<MPoolOpReply, PaxosServiceMessage> { +public: + friend factory; + + uuid_d fsid; + __u32 replyCode = 0; + epoch_t epoch = 0; + bufferlist response_data; + + MPoolOpReply() : MessageInstance(CEPH_MSG_POOLOP_REPLY, 0) + {} + MPoolOpReply( uuid_d& f, ceph_tid_t t, int rc, int e, version_t v) : + MessageInstance(CEPH_MSG_POOLOP_REPLY, v), + fsid(f), + replyCode(rc), + epoch(e) { + set_tid(t); + } + MPoolOpReply( uuid_d& f, ceph_tid_t t, int rc, int e, version_t v, + bufferlist *blp) : + MessageInstance(CEPH_MSG_POOLOP_REPLY, v), + fsid(f), + replyCode(rc), + epoch(e) { + set_tid(t); + if (blp) + response_data.claim(*blp); + } + + std::string_view get_type_name() const override { return "poolopreply"; } + + void print(ostream& out) const override { + out << "pool_op_reply(tid " << get_tid() + << " " << cpp_strerror(-replyCode) + << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(replyCode, payload); + encode(epoch, payload); + if (response_data.length()) { + encode(true, payload); + encode(response_data, payload); + } else + encode(false, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + decode(replyCode, p); + decode(epoch, p); + bool has_response_data; + decode(has_response_data, p); + if (has_response_data) { + decode(response_data, p); + } + } +}; + +#endif diff --git a/src/messages/MRecoveryReserve.h b/src/messages/MRecoveryReserve.h new file mode 100644 index 00000000..2dc7d6c3 --- /dev/null +++ b/src/messages/MRecoveryReserve.h @@ -0,0 +1,130 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MRECOVERY_H +#define CEPH_MRECOVERY_H + +#include "msg/Message.h" +#include "messages/MOSDPeeringOp.h" + +class MRecoveryReserve : public MessageInstance<MRecoveryReserve, MOSDPeeringOp> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 2; +public: + spg_t pgid; + epoch_t query_epoch; + enum { + REQUEST = 0, // primary->replica: please reserve slot + GRANT = 1, // replica->primary: ok, i reserved it + RELEASE = 2, // primary->replica: release the slot i reserved before + REVOKE = 3, // replica->primary: i'm taking back the slot i gave you + }; + uint32_t type; + uint32_t priority = 0; + + spg_t get_spg() const { + return pgid; + } + epoch_t get_map_epoch() const { + return query_epoch; + } + epoch_t get_min_epoch() const { + return query_epoch; + } + + PGPeeringEvent *get_event() override { + switch (type) { + case REQUEST: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RequestRecoveryPrio(priority)); + case GRANT: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RemoteRecoveryReserved()); + case RELEASE: + return new PGPeeringEvent( + query_epoch, + query_epoch, + RecoveryDone()); + case REVOKE: + return new PGPeeringEvent( + query_epoch, + query_epoch, + DeferRecovery(0.0)); + default: + ceph_abort(); + } + } + + MRecoveryReserve() + : MessageInstance(MSG_OSD_RECOVERY_RESERVE, HEAD_VERSION, COMPAT_VERSION), + query_epoch(0), type(-1) {} + MRecoveryReserve(int type, + spg_t pgid, + epoch_t query_epoch, + unsigned prio = 0) + : MessageInstance(MSG_OSD_RECOVERY_RESERVE, HEAD_VERSION, COMPAT_VERSION), + pgid(pgid), query_epoch(query_epoch), + type(type), priority(prio) {} + + std::string_view get_type_name() const override { + return "MRecoveryReserve"; + } + + void inner_print(ostream& out) const override { + switch (type) { + case REQUEST: + out << "REQUEST"; + break; + case GRANT: + out << "GRANT"; + break; + case RELEASE: + out << "RELEASE"; + break; + case REVOKE: + out << "REVOKE"; + break; + } + if (type == REQUEST) out << " prio: " << priority; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(pgid.pgid, p); + decode(query_epoch, p); + decode(type, p); + decode(pgid.shard, p); + if (header.version >= 3) { + decode(priority, p); + } + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(pgid.pgid, payload); + encode(query_epoch, payload); + encode(type, payload); + encode(pgid.shard, payload); + encode(priority, payload); + } +}; + +#endif diff --git a/src/messages/MRemoveSnaps.h b/src/messages/MRemoveSnaps.h new file mode 100644 index 00000000..96f1f2df --- /dev/null +++ b/src/messages/MRemoveSnaps.h @@ -0,0 +1,55 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MREMOVESNAPS_H +#define CEPH_MREMOVESNAPS_H + +#include "messages/PaxosServiceMessage.h" + +class MRemoveSnaps : public MessageInstance<MRemoveSnaps, PaxosServiceMessage> { +public: + friend factory; + + map<int, vector<snapid_t> > snaps; + +protected: + MRemoveSnaps() : + MessageInstance(MSG_REMOVE_SNAPS, 0) { } + MRemoveSnaps(map<int, vector<snapid_t> >& s) : + MessageInstance(MSG_REMOVE_SNAPS, 0) { + snaps.swap(s); + } + ~MRemoveSnaps() override {} + +public: + std::string_view get_type_name() const override { return "remove_snaps"; } + void print(ostream& out) const override { + out << "remove_snaps(" << snaps << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(snaps, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(snaps, p); + ceph_assert(p.end()); + } + +}; + +#endif diff --git a/src/messages/MRoute.h b/src/messages/MRoute.h new file mode 100644 index 00000000..d0cf441e --- /dev/null +++ b/src/messages/MRoute.h @@ -0,0 +1,88 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + + +#ifndef CEPH_MROUTE_H +#define CEPH_MROUTE_H + +#include "msg/Message.h" +#include "include/encoding.h" + +class MRoute : public MessageInstance<MRoute> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 3; + + uint64_t session_mon_tid; + Message *msg; + epoch_t send_osdmap_first; + + MRoute() : MessageInstance(MSG_ROUTE, HEAD_VERSION, COMPAT_VERSION), + session_mon_tid(0), + msg(NULL), + send_osdmap_first(0) {} + MRoute(uint64_t t, Message *m) + : MessageInstance(MSG_ROUTE, HEAD_VERSION, COMPAT_VERSION), + session_mon_tid(t), + msg(m), + send_osdmap_first(0) {} +private: + ~MRoute() override { + if (msg) + msg->put(); + } + +public: + void decode_payload() override { + auto p = payload.cbegin(); + decode(session_mon_tid, p); + entity_inst_t dest_unused; + decode(dest_unused, p); + bool m; + decode(m, p); + if (m) + msg = decode_message(NULL, 0, p); + decode(send_osdmap_first, p); + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(session_mon_tid, payload); + entity_inst_t dest_unused; + encode(dest_unused, payload, features); + bool m = msg ? true : false; + encode(m, payload); + if (msg) + encode_message(msg, features, payload); + encode(send_osdmap_first, payload); + } + + std::string_view get_type_name() const override { return "route"; } + void print(ostream& o) const override { + if (msg) + o << "route(" << *msg; + else + o << "route(no-reply"; + if (send_osdmap_first) + o << " send_osdmap_first " << send_osdmap_first; + if (session_mon_tid) + o << " tid " << session_mon_tid << ")"; + else + o << " tid (none)"; + } +}; + +#endif diff --git a/src/messages/MServiceMap.h b/src/messages/MServiceMap.h new file mode 100644 index 00000000..275acfcd --- /dev/null +++ b/src/messages/MServiceMap.h @@ -0,0 +1,37 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" +#include "mgr/ServiceMap.h" + +class MServiceMap : public MessageInstance<MServiceMap> { +public: + friend factory; + + ServiceMap service_map; + + MServiceMap() : MessageInstance(MSG_SERVICE_MAP) { } + explicit MServiceMap(const ServiceMap& sm) + : MessageInstance(MSG_SERVICE_MAP), + service_map(sm) { + } +private: + ~MServiceMap() override {} + +public: + std::string_view get_type_name() const override { return "service_map"; } + void print(ostream& out) const override { + out << "service_map(e" << service_map.epoch << " " + << service_map.services.size() << " svc)"; + } + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(service_map, payload, features); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(service_map, p); + } +}; diff --git a/src/messages/MStatfs.h b/src/messages/MStatfs.h new file mode 100644 index 00000000..f68d6728 --- /dev/null +++ b/src/messages/MStatfs.h @@ -0,0 +1,69 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MSTATFS_H +#define CEPH_MSTATFS_H + +#include <sys/statvfs.h> /* or <sys/statfs.h> */ +#include "messages/PaxosServiceMessage.h" + +class MStatfs : public MessageInstance<MStatfs, PaxosServiceMessage> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 2; + static constexpr int COMPAT_VERSION = 1; + +public: + uuid_d fsid; + boost::optional<int64_t> data_pool; + + MStatfs() : MessageInstance(CEPH_MSG_STATFS, 0, HEAD_VERSION, COMPAT_VERSION) {} + MStatfs(const uuid_d& f, ceph_tid_t t, boost::optional<int64_t> _data_pool, + version_t v) : MessageInstance(CEPH_MSG_STATFS, v, + HEAD_VERSION, COMPAT_VERSION), + fsid(f), data_pool(_data_pool) { + set_tid(t); + } + +private: + ~MStatfs() override {} + +public: + std::string_view get_type_name() const override { return "statfs"; } + void print(ostream& out) const override { + out << "statfs(" << get_tid() << " pool " + << (data_pool ? *data_pool : -1) << " v" << version << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + paxos_encode(); + encode(fsid, payload); + encode(data_pool, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + paxos_decode(p); + decode(fsid, p); + if (header.version >= 2) { + decode(data_pool, p); + } else { + data_pool = boost::optional<int64_t> (); + } + } +}; + +#endif diff --git a/src/messages/MStatfsReply.h b/src/messages/MStatfsReply.h new file mode 100644 index 00000000..4dd6b40e --- /dev/null +++ b/src/messages/MStatfsReply.h @@ -0,0 +1,47 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MSTATFSREPLY_H +#define CEPH_MSTATFSREPLY_H + +class MStatfsReply : public MessageInstance<MStatfsReply> { +public: + friend factory; + + struct ceph_mon_statfs_reply h{}; + + MStatfsReply() : MessageInstance(CEPH_MSG_STATFS_REPLY) {} + MStatfsReply(uuid_d &f, ceph_tid_t t, epoch_t epoch) : MessageInstance(CEPH_MSG_STATFS_REPLY) { + memcpy(&h.fsid, f.bytes(), sizeof(h.fsid)); + header.tid = t; + h.version = epoch; + } + + std::string_view get_type_name() const override { return "statfs_reply"; } + void print(ostream& out) const override { + out << "statfs_reply(" << header.tid << ")"; + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(h, payload); + } + void decode_payload() override { + auto p = payload.cbegin(); + decode(h, p); + } +}; + +#endif diff --git a/src/messages/MTimeCheck.h b/src/messages/MTimeCheck.h new file mode 100644 index 00000000..994c6dd8 --- /dev/null +++ b/src/messages/MTimeCheck.h @@ -0,0 +1,90 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2012 Inktank, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MTIMECHECK_H +#define CEPH_MTIMECHECK_H + +class MTimeCheck : public MessageInstance<MTimeCheck> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + + enum { + OP_PING = 1, + OP_PONG = 2, + OP_REPORT = 3, + }; + + int op = 0; + version_t epoch = 0; + version_t round = 0; + + utime_t timestamp; + map<entity_inst_t, double> skews; + map<entity_inst_t, double> latencies; + + MTimeCheck() : MessageInstance(MSG_TIMECHECK, HEAD_VERSION) { } + MTimeCheck(int op) : + MessageInstance(MSG_TIMECHECK, HEAD_VERSION), + op(op) + { } + +private: + ~MTimeCheck() override { } + +public: + std::string_view get_type_name() const override { return "time_check"; } + const char *get_op_name() const { + switch (op) { + case OP_PING: return "ping"; + case OP_PONG: return "pong"; + case OP_REPORT: return "report"; + } + return "???"; + } + void print(ostream &o) const override { + o << "time_check( " << get_op_name() + << " e " << epoch << " r " << round; + if (op == OP_PONG) { + o << " ts " << timestamp; + } else if (op == OP_REPORT) { + o << " #skews " << skews.size() + << " #latencies " << latencies.size(); + } + o << " )"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(op, p); + decode(epoch, p); + decode(round, p); + decode(timestamp, p); + decode(skews, p); + decode(latencies, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(op, payload); + encode(epoch, payload); + encode(round, payload); + encode(timestamp, payload); + encode(skews, payload, features); + encode(latencies, payload, features); + } +}; + +#endif /* CEPH_MTIMECHECK_H */ diff --git a/src/messages/MTimeCheck2.h b/src/messages/MTimeCheck2.h new file mode 100644 index 00000000..1d93fcc9 --- /dev/null +++ b/src/messages/MTimeCheck2.h @@ -0,0 +1,88 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2012 Inktank, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#pragma once + +class MTimeCheck2 : public MessageInstance<MTimeCheck2> { +public: + friend factory; + + static constexpr int HEAD_VERSION = 1; + static constexpr int COMPAT_VERSION = 1; + + enum { + OP_PING = 1, + OP_PONG = 2, + OP_REPORT = 3, + }; + + int op = 0; + version_t epoch = 0; + version_t round = 0; + + utime_t timestamp; + map<int, double> skews; + map<int, double> latencies; + + MTimeCheck2() : MessageInstance(MSG_TIMECHECK2, HEAD_VERSION, COMPAT_VERSION) { } + MTimeCheck2(int op) : + MessageInstance(MSG_TIMECHECK2, HEAD_VERSION, COMPAT_VERSION), + op(op) + { } + +private: + ~MTimeCheck2() override { } + +public: + std::string_view get_type_name() const override { return "time_check2"; } + const char *get_op_name() const { + switch (op) { + case OP_PING: return "ping"; + case OP_PONG: return "pong"; + case OP_REPORT: return "report"; + } + return "???"; + } + void print(ostream &o) const override { + o << "time_check( " << get_op_name() + << " e " << epoch << " r " << round; + if (op == OP_PONG) { + o << " ts " << timestamp; + } else if (op == OP_REPORT) { + o << " #skews " << skews.size() + << " #latencies " << latencies.size(); + } + o << " )"; + } + + void decode_payload() override { + auto p = payload.cbegin(); + decode(op, p); + decode(epoch, p); + decode(round, p); + decode(timestamp, p); + decode(skews, p); + decode(latencies, p); + } + + void encode_payload(uint64_t features) override { + using ceph::encode; + encode(op, payload); + encode(epoch, payload); + encode(round, payload); + encode(timestamp, payload); + encode(skews, payload, features); + encode(latencies, payload, features); + } +}; diff --git a/src/messages/MWatchNotify.h b/src/messages/MWatchNotify.h new file mode 100644 index 00000000..b3a46d3e --- /dev/null +++ b/src/messages/MWatchNotify.h @@ -0,0 +1,96 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#ifndef CEPH_MWATCHNOTIFY_H +#define CEPH_MWATCHNOTIFY_H + +#include "msg/Message.h" + + +class MWatchNotify : public MessageInstance<MWatchNotify> { +public: + friend factory; +private: + static constexpr int HEAD_VERSION = 3; + static constexpr int COMPAT_VERSION = 1; + + public: + uint64_t cookie; ///< client unique id for this watch or notify + uint64_t ver; ///< unused + uint64_t notify_id; ///< osd unique id for a notify notification + uint8_t opcode; ///< CEPH_WATCH_EVENT_* + bufferlist bl; ///< notify payload (osd->client) + errorcode32_t return_code; ///< notify result (osd->client) + uint64_t notifier_gid; ///< who sent the notify + + MWatchNotify() + : MessageInstance(CEPH_MSG_WATCH_NOTIFY, HEAD_VERSION, COMPAT_VERSION) { } + MWatchNotify(uint64_t c, uint64_t v, uint64_t i, uint8_t o, bufferlist b) + : MessageInstance(CEPH_MSG_WATCH_NOTIFY, HEAD_VERSION, COMPAT_VERSION), + cookie(c), + ver(v), + notify_id(i), + opcode(o), + bl(b), + return_code(0), + notifier_gid(0) { } +private: + ~MWatchNotify() override {} + +public: + void decode_payload() override { + uint8_t msg_ver; + auto p = payload.cbegin(); + decode(msg_ver, p); + decode(opcode, p); + decode(cookie, p); + decode(ver, p); + decode(notify_id, p); + if (msg_ver >= 1) + decode(bl, p); + if (header.version >= 2) + decode(return_code, p); + else + return_code = 0; + if (header.version >= 3) + decode(notifier_gid, p); + else + notifier_gid = 0; + } + void encode_payload(uint64_t features) override { + using ceph::encode; + uint8_t msg_ver = 1; + encode(msg_ver, payload); + encode(opcode, payload); + encode(cookie, payload); + encode(ver, payload); + encode(notify_id, payload); + encode(bl, payload); + encode(return_code, payload); + encode(notifier_gid, payload); + } + + std::string_view get_type_name() const override { return "watch-notify"; } + void print(ostream& out) const override { + out << "watch-notify(" + << ceph_watch_event_name(opcode) << " (" << (int)opcode << ")" + << " cookie " << cookie + << " notify " << notify_id + << " ret " << return_code + << ")"; + } +}; + +#endif diff --git a/src/messages/PaxosServiceMessage.h b/src/messages/PaxosServiceMessage.h new file mode 100644 index 00000000..5b0b1bf5 --- /dev/null +++ b/src/messages/PaxosServiceMessage.h @@ -0,0 +1,56 @@ +#ifndef CEPH_PAXOSSERVICEMESSAGE_H +#define CEPH_PAXOSSERVICEMESSAGE_H + +#include "msg/Message.h" +#include "mon/Session.h" + +class PaxosServiceMessage : public MessageSubType<PaxosServiceMessage> { +public: + version_t version; + __s16 deprecated_session_mon; + uint64_t deprecated_session_mon_tid; + + // track which epoch the leader received a forwarded request in, so we can + // discard forwarded requests appropriately on election boundaries. + epoch_t rx_election_epoch; + + PaxosServiceMessage() + : MessageSubType(MSG_PAXOS), + version(0), deprecated_session_mon(-1), deprecated_session_mon_tid(0), + rx_election_epoch(0) { } + PaxosServiceMessage(int type, version_t v, int enc_version=1, int compat_enc_version=0) + : MessageSubType(type, enc_version, compat_enc_version), + version(v), deprecated_session_mon(-1), deprecated_session_mon_tid(0), + rx_election_epoch(0) { } + protected: + virtual ~PaxosServiceMessage() override {} + + public: + void paxos_encode() { + using ceph::encode; + encode(version, payload); + encode(deprecated_session_mon, payload); + encode(deprecated_session_mon_tid, payload); + } + + void paxos_decode(bufferlist::const_iterator& p ) { + decode(version, p); + decode(deprecated_session_mon, p); + decode(deprecated_session_mon_tid, p); + } + + void encode_payload(uint64_t features) override { + ceph_abort(); + paxos_encode(); + } + + void decode_payload() override { + ceph_abort(); + auto p = payload.cbegin(); + paxos_decode(p); + } + + std::string_view get_type_name() const override { return "PaxosServiceMessage"; } +}; + +#endif |