summaryrefslogtreecommitdiffstats
path: root/src/cls/rbd/cls_rbd_types.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/cls/rbd/cls_rbd_types.cc
parentInitial commit. (diff)
downloadceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz
ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/cls/rbd/cls_rbd_types.cc1359
1 files changed, 1359 insertions, 0 deletions
diff --git a/src/cls/rbd/cls_rbd_types.cc b/src/cls/rbd/cls_rbd_types.cc
new file mode 100644
index 000000000..e47f22777
--- /dev/null
+++ b/src/cls/rbd/cls_rbd_types.cc
@@ -0,0 +1,1359 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <boost/variant.hpp>
+#include "cls/rbd/cls_rbd_types.h"
+#include "common/Formatter.h"
+
+namespace cls {
+namespace rbd {
+
+using std::istringstream;
+using std::ostringstream;
+using std::string;
+
+using ceph::bufferlist;
+using ceph::Formatter;
+
+std::ostream& operator<<(std::ostream& os,
+ MirrorPeerDirection mirror_peer_direction) {
+ switch (mirror_peer_direction) {
+ case MIRROR_PEER_DIRECTION_RX:
+ os << "RX";
+ break;
+ case MIRROR_PEER_DIRECTION_TX:
+ os << "TX";
+ break;
+ case MIRROR_PEER_DIRECTION_RX_TX:
+ os << "RX/TX";
+ break;
+ default:
+ os << "unknown";
+ break;
+ }
+ return os;
+}
+
+void MirrorPeer::encode(bufferlist &bl) const {
+ ENCODE_START(2, 1, bl);
+ encode(uuid, bl);
+ encode(site_name, bl);
+ encode(client_name, bl);
+ int64_t pool_id = -1;
+ encode(pool_id, bl);
+
+ // v2
+ encode(static_cast<uint8_t>(mirror_peer_direction), bl);
+ encode(mirror_uuid, bl);
+ encode(last_seen, bl);
+ ENCODE_FINISH(bl);
+}
+
+void MirrorPeer::decode(bufferlist::const_iterator &it) {
+ DECODE_START(2, it);
+ decode(uuid, it);
+ decode(site_name, it);
+ decode(client_name, it);
+ int64_t pool_id;
+ decode(pool_id, it);
+
+ if (struct_v >= 2) {
+ uint8_t mpd;
+ decode(mpd, it);
+ mirror_peer_direction = static_cast<MirrorPeerDirection>(mpd);
+ decode(mirror_uuid, it);
+ decode(last_seen, it);
+ }
+
+ DECODE_FINISH(it);
+}
+
+void MirrorPeer::dump(Formatter *f) const {
+ f->dump_string("uuid", uuid);
+ f->dump_stream("direction") << mirror_peer_direction;
+ f->dump_string("site_name", site_name);
+ f->dump_string("mirror_uuid", mirror_uuid);
+ f->dump_string("client_name", client_name);
+ f->dump_stream("last_seen") << last_seen;
+}
+
+void MirrorPeer::generate_test_instances(std::list<MirrorPeer*> &o) {
+ o.push_back(new MirrorPeer());
+ o.push_back(new MirrorPeer("uuid-123", MIRROR_PEER_DIRECTION_RX, "site A",
+ "client name", ""));
+ o.push_back(new MirrorPeer("uuid-234", MIRROR_PEER_DIRECTION_TX, "site B",
+ "", "mirror_uuid"));
+ o.push_back(new MirrorPeer("uuid-345", MIRROR_PEER_DIRECTION_RX_TX, "site C",
+ "client name", "mirror_uuid"));
+}
+
+bool MirrorPeer::operator==(const MirrorPeer &rhs) const {
+ return (uuid == rhs.uuid &&
+ mirror_peer_direction == rhs.mirror_peer_direction &&
+ site_name == rhs.site_name &&
+ client_name == rhs.client_name &&
+ mirror_uuid == rhs.mirror_uuid &&
+ last_seen == rhs.last_seen);
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode) {
+ switch (mirror_mode) {
+ case MIRROR_MODE_DISABLED:
+ os << "disabled";
+ break;
+ case MIRROR_MODE_IMAGE:
+ os << "image";
+ break;
+ case MIRROR_MODE_POOL:
+ os << "pool";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")";
+ break;
+ }
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer) {
+ os << "["
+ << "uuid=" << peer.uuid << ", "
+ << "direction=" << peer.mirror_peer_direction << ", "
+ << "site_name=" << peer.site_name << ", "
+ << "client_name=" << peer.client_name << ", "
+ << "mirror_uuid=" << peer.mirror_uuid << ", "
+ << "last_seen=" << peer.last_seen
+ << "]";
+ return os;
+}
+
+void MirrorImage::encode(bufferlist &bl) const {
+ ENCODE_START(2, 1, bl);
+ encode(global_image_id, bl);
+ encode(static_cast<uint8_t>(state), bl);
+ encode(static_cast<uint8_t>(mode), bl);
+ ENCODE_FINISH(bl);
+}
+
+void MirrorImage::decode(bufferlist::const_iterator &it) {
+ uint8_t int_state;
+ DECODE_START(2, it);
+ decode(global_image_id, it);
+ decode(int_state, it);
+ state = static_cast<MirrorImageState>(int_state);
+ if (struct_v >= 2) {
+ uint8_t int_mode;
+ decode(int_mode, it);
+ mode = static_cast<MirrorImageMode>(int_mode);
+ }
+ DECODE_FINISH(it);
+}
+
+void MirrorImage::dump(Formatter *f) const {
+ f->dump_stream("mode") << mode;
+ f->dump_string("global_image_id", global_image_id);
+ f->dump_stream("state") << state;
+}
+
+void MirrorImage::generate_test_instances(std::list<MirrorImage*> &o) {
+ o.push_back(new MirrorImage());
+ o.push_back(new MirrorImage(MIRROR_IMAGE_MODE_JOURNAL, "uuid-123",
+ MIRROR_IMAGE_STATE_ENABLED));
+ o.push_back(new MirrorImage(MIRROR_IMAGE_MODE_SNAPSHOT, "uuid-abc",
+ MIRROR_IMAGE_STATE_DISABLING));
+}
+
+bool MirrorImage::operator==(const MirrorImage &rhs) const {
+ return mode == rhs.mode && global_image_id == rhs.global_image_id &&
+ state == rhs.state;
+}
+
+bool MirrorImage::operator<(const MirrorImage &rhs) const {
+ if (mode != rhs.mode) {
+ return mode < rhs.mode;
+ }
+ if (global_image_id != rhs.global_image_id) {
+ return global_image_id < rhs.global_image_id;
+ }
+ return state < rhs.state;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorImageMode& mirror_mode) {
+ switch (mirror_mode) {
+ case MIRROR_IMAGE_MODE_JOURNAL:
+ os << "journal";
+ break;
+ case MIRROR_IMAGE_MODE_SNAPSHOT:
+ os << "snapshot";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")";
+ break;
+ }
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state) {
+ switch (mirror_state) {
+ case MIRROR_IMAGE_STATE_DISABLING:
+ os << "disabling";
+ break;
+ case MIRROR_IMAGE_STATE_ENABLED:
+ os << "enabled";
+ break;
+ case MIRROR_IMAGE_STATE_DISABLED:
+ os << "disabled";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(mirror_state) << ")";
+ break;
+ }
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image) {
+ os << "["
+ << "mode=" << mirror_image.mode << ", "
+ << "global_image_id=" << mirror_image.global_image_id << ", "
+ << "state=" << mirror_image.state << "]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MirrorImageStatusState& state) {
+ switch (state) {
+ case MIRROR_IMAGE_STATUS_STATE_UNKNOWN:
+ os << "unknown";
+ break;
+ case MIRROR_IMAGE_STATUS_STATE_ERROR:
+ os << "error";
+ break;
+ case MIRROR_IMAGE_STATUS_STATE_SYNCING:
+ os << "syncing";
+ break;
+ case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY:
+ os << "starting_replay";
+ break;
+ case MIRROR_IMAGE_STATUS_STATE_REPLAYING:
+ os << "replaying";
+ break;
+ case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY:
+ os << "stopping_replay";
+ break;
+ case MIRROR_IMAGE_STATUS_STATE_STOPPED:
+ os << "stopped";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(state) << ")";
+ break;
+ }
+ return os;
+}
+
+const std::string MirrorImageSiteStatus::LOCAL_MIRROR_UUID(""); // empty mirror uuid
+
+void MirrorImageSiteStatus::encode_meta(uint8_t version, bufferlist &bl) const {
+ if (version >= 2) {
+ ceph::encode(mirror_uuid, bl);
+ }
+ cls::rbd::encode(state, bl);
+ ceph::encode(description, bl);
+ ceph::encode(last_update, bl);
+ ceph::encode(up, bl);
+}
+
+void MirrorImageSiteStatus::decode_meta(uint8_t version,
+ bufferlist::const_iterator &it) {
+ if (version < 2) {
+ mirror_uuid = LOCAL_MIRROR_UUID;
+ } else {
+ ceph::decode(mirror_uuid, it);
+ }
+
+ cls::rbd::decode(state, it);
+ ceph::decode(description, it);
+ ::decode(last_update, it);
+ ceph::decode(up, it);
+}
+
+void MirrorImageSiteStatus::encode(bufferlist &bl) const {
+ // break compatibility when site-name is provided
+ uint8_t version = (mirror_uuid == LOCAL_MIRROR_UUID ? 1 : 2);
+ ENCODE_START(version, version, bl);
+ encode_meta(version, bl);
+ ENCODE_FINISH(bl);
+}
+
+void MirrorImageSiteStatus::decode(bufferlist::const_iterator &it) {
+ DECODE_START(2, it);
+ decode_meta(struct_v, it);
+ DECODE_FINISH(it);
+}
+
+void MirrorImageSiteStatus::dump(Formatter *f) const {
+ f->dump_string("state", state_to_string());
+ f->dump_string("description", description);
+ f->dump_stream("last_update") << last_update;
+}
+
+std::string MirrorImageSiteStatus::state_to_string() const {
+ std::stringstream ss;
+ ss << (up ? "up+" : "down+") << state;
+ return ss.str();
+}
+
+void MirrorImageSiteStatus::generate_test_instances(
+ std::list<MirrorImageSiteStatus*> &o) {
+ o.push_back(new MirrorImageSiteStatus());
+ o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_REPLAYING,
+ ""));
+ o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_ERROR,
+ "error"));
+ o.push_back(new MirrorImageSiteStatus("2fb68ca9-1ba0-43b3-8cdf-8c5a9db71e65",
+ MIRROR_IMAGE_STATUS_STATE_STOPPED, ""));
+}
+
+bool MirrorImageSiteStatus::operator==(const MirrorImageSiteStatus &rhs) const {
+ return state == rhs.state && description == rhs.description && up == rhs.up;
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MirrorImageSiteStatus& status) {
+ os << "{"
+ << "state=" << status.state_to_string() << ", "
+ << "description=" << status.description << ", "
+ << "last_update=" << status.last_update << "]}";
+ return os;
+}
+
+void MirrorImageSiteStatusOnDisk::encode_meta(bufferlist &bl,
+ uint64_t features) const {
+ ENCODE_START(1, 1, bl);
+ auto sanitized_origin = origin;
+ sanitize_entity_inst(&sanitized_origin);
+ encode(sanitized_origin, bl, features);
+ ENCODE_FINISH(bl);
+}
+
+void MirrorImageSiteStatusOnDisk::encode(bufferlist &bl,
+ uint64_t features) const {
+ encode_meta(bl, features);
+ cls::rbd::MirrorImageSiteStatus::encode(bl);
+}
+
+void MirrorImageSiteStatusOnDisk::decode_meta(bufferlist::const_iterator &it) {
+ DECODE_START(1, it);
+ decode(origin, it);
+ sanitize_entity_inst(&origin);
+ DECODE_FINISH(it);
+}
+
+void MirrorImageSiteStatusOnDisk::decode(bufferlist::const_iterator &it) {
+ decode_meta(it);
+ cls::rbd::MirrorImageSiteStatus::decode(it);
+}
+
+void MirrorImageSiteStatusOnDisk::generate_test_instances(
+ std::list<MirrorImageSiteStatusOnDisk*> &o) {
+ o.push_back(new MirrorImageSiteStatusOnDisk());
+ o.push_back(new MirrorImageSiteStatusOnDisk(
+ {"", MIRROR_IMAGE_STATUS_STATE_ERROR, "error"}));
+ o.push_back(new MirrorImageSiteStatusOnDisk(
+ {"siteA", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""}));
+}
+
+int MirrorImageStatus::get_local_mirror_image_site_status(
+ MirrorImageSiteStatus* status) const {
+ auto it = std::find_if(
+ mirror_image_site_statuses.begin(),
+ mirror_image_site_statuses.end(),
+ [](const MirrorImageSiteStatus& status) {
+ return status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID;
+ });
+ if (it == mirror_image_site_statuses.end()) {
+ return -ENOENT;
+ }
+
+ *status = *it;
+ return 0;
+}
+
+void MirrorImageStatus::encode(bufferlist &bl) const {
+ // don't break compatibility for extra site statuses
+ ENCODE_START(2, 1, bl);
+
+ // local site status
+ MirrorImageSiteStatus local_status;
+ int r = get_local_mirror_image_site_status(&local_status);
+ local_status.encode_meta(1, bl);
+
+ bool local_status_valid = (r >= 0);
+ encode(local_status_valid, bl);
+
+ // remote site statuses
+ __u32 n = mirror_image_site_statuses.size();
+ if (local_status_valid) {
+ --n;
+ }
+ encode(n, bl);
+
+ for (auto& status : mirror_image_site_statuses) {
+ if (status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) {
+ continue;
+ }
+ status.encode_meta(2, bl);
+ }
+ ENCODE_FINISH(bl);
+}
+
+void MirrorImageStatus::decode(bufferlist::const_iterator &it) {
+ DECODE_START(2, it);
+
+ // local site status
+ MirrorImageSiteStatus local_status;
+ local_status.decode_meta(1, it);
+
+ if (struct_v < 2) {
+ mirror_image_site_statuses.push_back(local_status);
+ } else {
+ bool local_status_valid;
+ decode(local_status_valid, it);
+
+ __u32 n;
+ decode(n, it);
+ if (local_status_valid) {
+ ++n;
+ }
+
+ mirror_image_site_statuses.resize(n);
+ for (auto status_it = mirror_image_site_statuses.begin();
+ status_it != mirror_image_site_statuses.end(); ++status_it) {
+ if (local_status_valid &&
+ status_it == mirror_image_site_statuses.begin()) {
+ *status_it = local_status;
+ continue;
+ }
+
+ // remote site status
+ status_it->decode_meta(struct_v, it);
+ }
+ }
+ DECODE_FINISH(it);
+}
+
+void MirrorImageStatus::dump(Formatter *f) const {
+ MirrorImageSiteStatus local_status;
+ int r = get_local_mirror_image_site_status(&local_status);
+ if (r >= 0) {
+ local_status.dump(f);
+ }
+
+ f->open_array_section("remotes");
+ for (auto& status : mirror_image_site_statuses) {
+ if (status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) {
+ continue;
+ }
+
+ f->open_object_section("remote");
+ status.dump(f);
+ f->close_section();
+ }
+ f->close_section();
+}
+
+bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const {
+ return (mirror_image_site_statuses == rhs.mirror_image_site_statuses);
+}
+
+void MirrorImageStatus::generate_test_instances(
+ std::list<MirrorImageStatus*> &o) {
+ o.push_back(new MirrorImageStatus());
+ o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_ERROR, ""}}));
+ o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""},
+ {"siteA", MIRROR_IMAGE_STATUS_STATE_REPLAYING, ""}}));
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MirrorImageStatus& status) {
+ os << "{";
+ MirrorImageSiteStatus local_status;
+ int r = status.get_local_mirror_image_site_status(&local_status);
+ if (r >= 0) {
+ os << "state=" << local_status.state_to_string() << ", "
+ << "description=" << local_status.description << ", "
+ << "last_update=" << local_status.last_update << ", ";
+ }
+
+ os << "remotes=[";
+ for (auto& remote_status : status.mirror_image_site_statuses) {
+ if (remote_status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) {
+ continue;
+ }
+
+ os << "{"
+ << "mirror_uuid=" << remote_status.mirror_uuid<< ", "
+ << "state=" << remote_status.state_to_string() << ", "
+ << "description=" << remote_status.description << ", "
+ << "last_update=" << remote_status.last_update
+ << "}";
+ }
+ os << "]}";
+ return os;
+}
+
+void ParentImageSpec::encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(pool_id, bl);
+ encode(pool_namespace, bl);
+ encode(image_id, bl);
+ encode(snap_id, bl);
+ ENCODE_FINISH(bl);
+}
+
+void ParentImageSpec::decode(bufferlist::const_iterator& bl) {
+ DECODE_START(1, bl);
+ decode(pool_id, bl);
+ decode(pool_namespace, bl);
+ decode(image_id, bl);
+ decode(snap_id, bl);
+ DECODE_FINISH(bl);
+}
+
+void ParentImageSpec::dump(Formatter *f) const {
+ f->dump_int("pool_id", pool_id);
+ f->dump_string("pool_namespace", pool_namespace);
+ f->dump_string("image_id", image_id);
+ f->dump_unsigned("snap_id", snap_id);
+}
+
+void ParentImageSpec::generate_test_instances(std::list<ParentImageSpec*>& o) {
+ o.push_back(new ParentImageSpec{});
+ o.push_back(new ParentImageSpec{1, "", "foo", 3});
+ o.push_back(new ParentImageSpec{1, "ns", "foo", 3});
+}
+
+std::ostream& operator<<(std::ostream& os, const ParentImageSpec& rhs) {
+ os << "["
+ << "pool_id=" << rhs.pool_id << ", "
+ << "pool_namespace=" << rhs.pool_namespace << ", "
+ << "image_id=" << rhs.image_id << ", "
+ << "snap_id=" << rhs.snap_id
+ << "]";
+ return os;
+}
+
+void ChildImageSpec::encode(bufferlist &bl) const {
+ ENCODE_START(2, 1, bl);
+ encode(pool_id, bl);
+ encode(image_id, bl);
+ encode(pool_namespace, bl);
+ ENCODE_FINISH(bl);
+}
+
+void ChildImageSpec::decode(bufferlist::const_iterator &it) {
+ DECODE_START(2, it);
+ decode(pool_id, it);
+ decode(image_id, it);
+ if (struct_v >= 2) {
+ decode(pool_namespace, it);
+ }
+ DECODE_FINISH(it);
+}
+
+void ChildImageSpec::dump(Formatter *f) const {
+ f->dump_int("pool_id", pool_id);
+ f->dump_string("pool_namespace", pool_namespace);
+ f->dump_string("image_id", image_id);
+}
+
+void ChildImageSpec::generate_test_instances(std::list<ChildImageSpec*> &o) {
+ o.push_back(new ChildImageSpec());
+ o.push_back(new ChildImageSpec(123, "", "abc"));
+ o.push_back(new ChildImageSpec(123, "ns", "abc"));
+}
+
+std::ostream& operator<<(std::ostream& os, const ChildImageSpec& rhs) {
+ os << "["
+ << "pool_id=" << rhs.pool_id << ", "
+ << "pool_namespace=" << rhs.pool_namespace << ", "
+ << "image_id=" << rhs.image_id
+ << "]";
+ return os;
+}
+
+void GroupImageSpec::encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(image_id, bl);
+ encode(pool_id, bl);
+ ENCODE_FINISH(bl);
+}
+
+void GroupImageSpec::decode(bufferlist::const_iterator &it) {
+ DECODE_START(1, it);
+ decode(image_id, it);
+ decode(pool_id, it);
+ DECODE_FINISH(it);
+}
+
+void GroupImageSpec::dump(Formatter *f) const {
+ f->dump_string("image_id", image_id);
+ f->dump_int("pool_id", pool_id);
+}
+
+int GroupImageSpec::from_key(const std::string &image_key,
+ GroupImageSpec *spec) {
+ if (nullptr == spec) return -EINVAL;
+ int prefix_len = cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX.size();
+ std::string data_string = image_key.substr(prefix_len,
+ image_key.size() - prefix_len);
+ size_t p = data_string.find("_");
+ if (std::string::npos == p) {
+ return -EIO;
+ }
+ data_string[p] = ' ';
+
+ istringstream iss(data_string);
+ uint64_t pool_id;
+ string image_id;
+ iss >> std::hex >> pool_id >> image_id;
+
+ spec->image_id = image_id;
+ spec->pool_id = pool_id;
+ return 0;
+}
+
+std::string GroupImageSpec::image_key() {
+ if (-1 == pool_id)
+ return "";
+ else {
+ ostringstream oss;
+ oss << RBD_GROUP_IMAGE_KEY_PREFIX << std::setw(16)
+ << std::setfill('0') << std::hex << pool_id << "_" << image_id;
+ return oss.str();
+ }
+}
+
+void GroupImageSpec::generate_test_instances(std::list<GroupImageSpec*> &o) {
+ o.push_back(new GroupImageSpec("10152ae8944a", 0));
+ o.push_back(new GroupImageSpec("1018643c9869", 3));
+}
+
+void GroupImageStatus::encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(spec, bl);
+ encode(state, bl);
+ ENCODE_FINISH(bl);
+}
+
+void GroupImageStatus::decode(bufferlist::const_iterator &it) {
+ DECODE_START(1, it);
+ decode(spec, it);
+ decode(state, it);
+ DECODE_FINISH(it);
+}
+
+std::string GroupImageStatus::state_to_string() const {
+ std::stringstream ss;
+ if (state == GROUP_IMAGE_LINK_STATE_INCOMPLETE) {
+ ss << "incomplete";
+ }
+ if (state == GROUP_IMAGE_LINK_STATE_ATTACHED) {
+ ss << "attached";
+ }
+ return ss.str();
+}
+
+void GroupImageStatus::dump(Formatter *f) const {
+ spec.dump(f);
+ f->dump_string("state", state_to_string());
+}
+
+void GroupImageStatus::generate_test_instances(std::list<GroupImageStatus*> &o) {
+ o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_ATTACHED));
+ o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_ATTACHED));
+ o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_INCOMPLETE));
+ o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_INCOMPLETE));
+}
+
+
+void GroupSpec::encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(pool_id, bl);
+ encode(group_id, bl);
+ ENCODE_FINISH(bl);
+}
+
+void GroupSpec::decode(bufferlist::const_iterator &it) {
+ DECODE_START(1, it);
+ decode(pool_id, it);
+ decode(group_id, it);
+ DECODE_FINISH(it);
+}
+
+void GroupSpec::dump(Formatter *f) const {
+ f->dump_string("group_id", group_id);
+ f->dump_int("pool_id", pool_id);
+}
+
+bool GroupSpec::is_valid() const {
+ return (!group_id.empty()) && (pool_id != -1);
+}
+
+void GroupSpec::generate_test_instances(std::list<GroupSpec *> &o) {
+ o.push_back(new GroupSpec("10152ae8944a", 0));
+ o.push_back(new GroupSpec("1018643c9869", 3));
+}
+
+void GroupSnapshotNamespace::encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(group_pool, bl);
+ encode(group_id, bl);
+ encode(group_snapshot_id, bl);
+}
+
+void GroupSnapshotNamespace::decode(bufferlist::const_iterator& it) {
+ using ceph::decode;
+ decode(group_pool, it);
+ decode(group_id, it);
+ decode(group_snapshot_id, it);
+}
+
+void GroupSnapshotNamespace::dump(Formatter *f) const {
+ f->dump_int("group_pool", group_pool);
+ f->dump_string("group_id", group_id);
+ f->dump_string("group_snapshot_id", group_snapshot_id);
+}
+
+void TrashSnapshotNamespace::encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(original_name, bl);
+ encode(static_cast<uint32_t>(original_snapshot_namespace_type), bl);
+}
+
+void TrashSnapshotNamespace::decode(bufferlist::const_iterator& it) {
+ using ceph::decode;
+ decode(original_name, it);
+ uint32_t snap_type;
+ decode(snap_type, it);
+ original_snapshot_namespace_type = static_cast<SnapshotNamespaceType>(
+ snap_type);
+}
+
+void TrashSnapshotNamespace::dump(Formatter *f) const {
+ f->dump_string("original_name", original_name);
+ f->dump_stream("original_snapshot_namespace")
+ << original_snapshot_namespace_type;
+}
+
+void MirrorSnapshotNamespace::encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(state, bl);
+ encode(complete, bl);
+ encode(mirror_peer_uuids, bl);
+ encode(primary_mirror_uuid, bl);
+ encode(primary_snap_id, bl);
+ encode(last_copied_object_number, bl);
+ encode(snap_seqs, bl);
+}
+
+void MirrorSnapshotNamespace::decode(bufferlist::const_iterator& it) {
+ using ceph::decode;
+ decode(state, it);
+ decode(complete, it);
+ decode(mirror_peer_uuids, it);
+ decode(primary_mirror_uuid, it);
+ decode(primary_snap_id, it);
+ decode(last_copied_object_number, it);
+ decode(snap_seqs, it);
+}
+
+void MirrorSnapshotNamespace::dump(Formatter *f) const {
+ f->dump_stream("state") << state;
+ f->dump_bool("complete", complete);
+ f->open_array_section("mirror_peer_uuids");
+ for (auto &peer : mirror_peer_uuids) {
+ f->dump_string("mirror_peer_uuid", peer);
+ }
+ f->close_section();
+ if (is_primary()) {
+ f->dump_unsigned("clean_since_snap_id", clean_since_snap_id);
+ } else {
+ f->dump_string("primary_mirror_uuid", primary_mirror_uuid);
+ f->dump_unsigned("primary_snap_id", primary_snap_id);
+ f->dump_unsigned("last_copied_object_number", last_copied_object_number);
+ f->dump_stream("snap_seqs") << snap_seqs;
+ }
+}
+
+class EncodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
+public:
+ explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) {
+ }
+
+ template <typename T>
+ inline void operator()(const T& t) const {
+ using ceph::encode;
+ encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE), m_bl);
+ t.encode(m_bl);
+ }
+
+private:
+ bufferlist &m_bl;
+};
+
+class DecodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
+public:
+ DecodeSnapshotNamespaceVisitor(bufferlist::const_iterator &iter)
+ : m_iter(iter) {
+ }
+
+ template <typename T>
+ inline void operator()(T& t) const {
+ t.decode(m_iter);
+ }
+private:
+ bufferlist::const_iterator &m_iter;
+};
+
+class DumpSnapshotNamespaceVisitor : public boost::static_visitor<void> {
+public:
+ explicit DumpSnapshotNamespaceVisitor(Formatter *formatter, const std::string &key)
+ : m_formatter(formatter), m_key(key) {}
+
+ template <typename T>
+ inline void operator()(const T& t) const {
+ auto type = T::SNAPSHOT_NAMESPACE_TYPE;
+ m_formatter->dump_string(m_key.c_str(), stringify(type));
+ t.dump(m_formatter);
+ }
+private:
+ ceph::Formatter *m_formatter;
+ std::string m_key;
+};
+
+class GetTypeVisitor : public boost::static_visitor<SnapshotNamespaceType> {
+public:
+ template <typename T>
+ inline SnapshotNamespaceType operator()(const T&) const {
+ return static_cast<SnapshotNamespaceType>(T::SNAPSHOT_NAMESPACE_TYPE);
+ }
+};
+
+SnapshotNamespaceType get_snap_namespace_type(
+ const SnapshotNamespace& snapshot_namespace) {
+ return static_cast<SnapshotNamespaceType>(boost::apply_visitor(
+ GetTypeVisitor(), snapshot_namespace));
+}
+
+void SnapshotInfo::encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(id, bl);
+ encode(snapshot_namespace, bl);
+ encode(name, bl);
+ encode(image_size, bl);
+ encode(timestamp, bl);
+ encode(child_count, bl);
+ ENCODE_FINISH(bl);
+}
+
+void SnapshotInfo::decode(bufferlist::const_iterator& it) {
+ DECODE_START(1, it);
+ decode(id, it);
+ decode(snapshot_namespace, it);
+ decode(name, it);
+ decode(image_size, it);
+ decode(timestamp, it);
+ decode(child_count, it);
+ DECODE_FINISH(it);
+}
+
+void SnapshotInfo::dump(Formatter *f) const {
+ f->dump_unsigned("id", id);
+ f->open_object_section("namespace");
+ boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "type"),
+ snapshot_namespace);
+ f->close_section();
+ f->dump_string("name", name);
+ f->dump_unsigned("image_size", image_size);
+ f->dump_stream("timestamp") << timestamp;
+}
+
+void SnapshotInfo::generate_test_instances(std::list<SnapshotInfo*> &o) {
+ o.push_back(new SnapshotInfo(1ULL, UserSnapshotNamespace{}, "snap1", 123,
+ {123456, 0}, 12));
+ o.push_back(new SnapshotInfo(2ULL,
+ GroupSnapshotNamespace{567, "group1", "snap1"},
+ "snap1", 123, {123456, 0}, 987));
+ o.push_back(new SnapshotInfo(3ULL,
+ TrashSnapshotNamespace{
+ SNAPSHOT_NAMESPACE_TYPE_USER, "snap1"},
+ "12345", 123, {123456, 0}, 429));
+ o.push_back(new SnapshotInfo(1ULL,
+ MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_PRIMARY,
+ {"1", "2"}, "", CEPH_NOSNAP},
+ "snap1", 123, {123456, 0}, 12));
+ o.push_back(new SnapshotInfo(1ULL,
+ MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_NON_PRIMARY,
+ {"1", "2"}, "uuid", 123},
+ "snap1", 123, {123456, 0}, 12));
+}
+
+void SnapshotNamespace::encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl), *this);
+ ENCODE_FINISH(bl);
+}
+
+void SnapshotNamespace::decode(bufferlist::const_iterator &p)
+{
+ DECODE_START(1, p);
+ uint32_t snap_type;
+ decode(snap_type, p);
+ switch (snap_type) {
+ case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER:
+ *this = UserSnapshotNamespace();
+ break;
+ case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP:
+ *this = GroupSnapshotNamespace();
+ break;
+ case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH:
+ *this = TrashSnapshotNamespace();
+ break;
+ case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR:
+ *this = MirrorSnapshotNamespace();
+ break;
+ default:
+ *this = UnknownSnapshotNamespace();
+ break;
+ }
+ boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p), *this);
+ DECODE_FINISH(p);
+}
+
+void SnapshotNamespace::dump(Formatter *f) const {
+ boost::apply_visitor(
+ DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), *this);
+}
+
+void SnapshotNamespace::generate_test_instances(std::list<SnapshotNamespace*> &o) {
+ o.push_back(new SnapshotNamespace(UserSnapshotNamespace()));
+ o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a",
+ "2118643c9732")));
+ o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869",
+ "33352be8933c")));
+ o.push_back(new SnapshotNamespace(TrashSnapshotNamespace()));
+ o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY,
+ {"peer uuid"},
+ "", CEPH_NOSNAP)));
+ o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED,
+ {"peer uuid"},
+ "", CEPH_NOSNAP)));
+ o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY,
+ {"peer uuid"},
+ "uuid", 123)));
+ o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED,
+ {"peer uuid"},
+ "uuid", 123)));
+}
+
+std::ostream& operator<<(std::ostream& os, const SnapshotNamespaceType& type) {
+ switch (type) {
+ case SNAPSHOT_NAMESPACE_TYPE_USER:
+ os << "user";
+ break;
+ case SNAPSHOT_NAMESPACE_TYPE_GROUP:
+ os << "group";
+ break;
+ case SNAPSHOT_NAMESPACE_TYPE_TRASH:
+ os << "trash";
+ break;
+ case SNAPSHOT_NAMESPACE_TYPE_MIRROR:
+ os << "mirror";
+ break;
+ default:
+ os << "unknown";
+ break;
+ }
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) {
+ os << "[" << SNAPSHOT_NAMESPACE_TYPE_USER << "]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns) {
+ os << "[" << SNAPSHOT_NAMESPACE_TYPE_GROUP << " "
+ << "group_pool=" << ns.group_pool << ", "
+ << "group_id=" << ns.group_id << ", "
+ << "group_snapshot_id=" << ns.group_snapshot_id << "]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns) {
+ os << "[" << SNAPSHOT_NAMESPACE_TYPE_TRASH << " "
+ << "original_name=" << ns.original_name << ", "
+ << "original_snapshot_namespace=" << ns.original_snapshot_namespace_type
+ << "]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorSnapshotNamespace& ns) {
+ os << "[" << SNAPSHOT_NAMESPACE_TYPE_MIRROR << " "
+ << "state=" << ns.state << ", "
+ << "complete=" << ns.complete << ", "
+ << "mirror_peer_uuids=" << ns.mirror_peer_uuids << ", ";
+ if (ns.is_primary()) {
+ os << "clean_since_snap_id=" << ns.clean_since_snap_id;
+ } else {
+ os << "primary_mirror_uuid=" << ns.primary_mirror_uuid << ", "
+ << "primary_snap_id=" << ns.primary_snap_id << ", "
+ << "last_copied_object_number=" << ns.last_copied_object_number << ", "
+ << "snap_seqs=" << ns.snap_seqs;
+ }
+ os << "]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) {
+ os << "[unknown]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, MirrorSnapshotState type) {
+ switch (type) {
+ case MIRROR_SNAPSHOT_STATE_PRIMARY:
+ os << "primary";
+ break;
+ case MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED:
+ os << "primary (demoted)";
+ break;
+ case MIRROR_SNAPSHOT_STATE_NON_PRIMARY:
+ os << "non-primary";
+ break;
+ case MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED:
+ os << "non-primary (demoted)";
+ break;
+ default:
+ os << "unknown";
+ break;
+ }
+ return os;
+}
+
+void ImageSnapshotSpec::encode(bufferlist& bl) const {
+ using ceph::encode;
+ ENCODE_START(1, 1, bl);
+ encode(pool, bl);
+ encode(image_id, bl);
+ encode(snap_id, bl);
+ ENCODE_FINISH(bl);
+}
+
+void ImageSnapshotSpec::decode(bufferlist::const_iterator& it) {
+ using ceph::decode;
+ DECODE_START(1, it);
+ decode(pool, it);
+ decode(image_id, it);
+ decode(snap_id, it);
+ DECODE_FINISH(it);
+}
+
+void ImageSnapshotSpec::dump(Formatter *f) const {
+ f->dump_int("pool", pool);
+ f->dump_string("image_id", image_id);
+ f->dump_int("snap_id", snap_id);
+}
+
+void ImageSnapshotSpec::generate_test_instances(std::list<ImageSnapshotSpec *> &o) {
+ o.push_back(new ImageSnapshotSpec(0, "myimage", 2));
+ o.push_back(new ImageSnapshotSpec(1, "testimage", 7));
+}
+
+void GroupSnapshot::encode(bufferlist& bl) const {
+ using ceph::encode;
+ ENCODE_START(1, 1, bl);
+ encode(id, bl);
+ encode(name, bl);
+ encode(state, bl);
+ encode(snaps, bl);
+ ENCODE_FINISH(bl);
+}
+
+void GroupSnapshot::decode(bufferlist::const_iterator& it) {
+ using ceph::decode;
+ DECODE_START(1, it);
+ decode(id, it);
+ decode(name, it);
+ decode(state, it);
+ decode(snaps, it);
+ DECODE_FINISH(it);
+}
+
+void GroupSnapshot::dump(Formatter *f) const {
+ f->dump_string("id", id);
+ f->dump_string("name", name);
+ f->dump_int("state", state);
+}
+
+void GroupSnapshot::generate_test_instances(std::list<GroupSnapshot *> &o) {
+ o.push_back(new GroupSnapshot("10152ae8944a", "groupsnapshot1", GROUP_SNAPSHOT_STATE_INCOMPLETE));
+ o.push_back(new GroupSnapshot("1018643c9869", "groupsnapshot2", GROUP_SNAPSHOT_STATE_COMPLETE));
+}
+void TrashImageSpec::encode(bufferlist& bl) const {
+ ENCODE_START(2, 1, bl);
+ encode(source, bl);
+ encode(name, bl);
+ encode(deletion_time, bl);
+ encode(deferment_end_time, bl);
+ encode(state, bl);
+ ENCODE_FINISH(bl);
+}
+
+void TrashImageSpec::decode(bufferlist::const_iterator &it) {
+ DECODE_START(2, it);
+ decode(source, it);
+ decode(name, it);
+ decode(deletion_time, it);
+ decode(deferment_end_time, it);
+ if (struct_v >= 2) {
+ decode(state, it);
+ }
+ DECODE_FINISH(it);
+}
+
+void TrashImageSpec::dump(Formatter *f) const {
+ f->dump_stream("source") << source;
+ f->dump_string("name", name);
+ f->dump_unsigned("deletion_time", deletion_time);
+ f->dump_unsigned("deferment_end_time", deferment_end_time);
+}
+
+void MirrorImageMap::encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ encode(instance_id, bl);
+ encode(mapped_time, bl);
+ encode(data, bl);
+ ENCODE_FINISH(bl);
+}
+
+void MirrorImageMap::decode(bufferlist::const_iterator &it) {
+ DECODE_START(1, it);
+ decode(instance_id, it);
+ decode(mapped_time, it);
+ decode(data, it);
+ DECODE_FINISH(it);
+}
+
+void MirrorImageMap::dump(Formatter *f) const {
+ f->dump_string("instance_id", instance_id);
+ f->dump_stream("mapped_time") << mapped_time;
+
+ std::stringstream data_ss;
+ data.hexdump(data_ss);
+ f->dump_string("data", data_ss.str());
+}
+
+void MirrorImageMap::generate_test_instances(
+ std::list<MirrorImageMap*> &o) {
+ bufferlist data;
+ data.append(std::string(128, '1'));
+
+ o.push_back(new MirrorImageMap("uuid-123", utime_t(), data));
+ o.push_back(new MirrorImageMap("uuid-abc", utime_t(), data));
+}
+
+bool MirrorImageMap::operator==(const MirrorImageMap &rhs) const {
+ return instance_id == rhs.instance_id && mapped_time == rhs.mapped_time &&
+ data.contents_equal(rhs.data);
+}
+
+bool MirrorImageMap::operator<(const MirrorImageMap &rhs) const {
+ return instance_id < rhs.instance_id ||
+ (instance_id == rhs.instance_id && mapped_time < rhs.mapped_time);
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MirrorImageMap &image_map) {
+ return os << "[" << "instance_id=" << image_map.instance_id << ", mapped_time="
+ << image_map.mapped_time << "]";
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MigrationHeaderType& type) {
+ switch (type) {
+ case MIGRATION_HEADER_TYPE_SRC:
+ os << "source";
+ break;
+ case MIGRATION_HEADER_TYPE_DST:
+ os << "destination";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(type) << ")";
+ break;
+ }
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MigrationState& migration_state) {
+ switch (migration_state) {
+ case MIGRATION_STATE_ERROR:
+ os << "error";
+ break;
+ case MIGRATION_STATE_PREPARING:
+ os << "preparing";
+ break;
+ case MIGRATION_STATE_PREPARED:
+ os << "prepared";
+ break;
+ case MIGRATION_STATE_EXECUTING:
+ os << "executing";
+ break;
+ case MIGRATION_STATE_EXECUTED:
+ os << "executed";
+ break;
+ case MIGRATION_STATE_ABORTING:
+ os << "aborting";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(migration_state) << ")";
+ break;
+ }
+ return os;
+}
+
+void MigrationSpec::encode(bufferlist& bl) const {
+ uint8_t min_version = 1;
+ if (!source_spec.empty()) {
+ min_version = 3;
+ }
+
+ ENCODE_START(3, min_version, bl);
+ encode(header_type, bl);
+ encode(pool_id, bl);
+ encode(pool_namespace, bl);
+ encode(image_name, bl);
+ encode(image_id, bl);
+ encode(snap_seqs, bl);
+ encode(overlap, bl);
+ encode(flatten, bl);
+ encode(mirroring, bl);
+ encode(state, bl);
+ encode(state_description, bl);
+ encode(static_cast<uint8_t>(mirror_image_mode), bl);
+ encode(source_spec, bl);
+ ENCODE_FINISH(bl);
+}
+
+void MigrationSpec::decode(bufferlist::const_iterator& bl) {
+ DECODE_START(3, bl);
+ decode(header_type, bl);
+ decode(pool_id, bl);
+ decode(pool_namespace, bl);
+ decode(image_name, bl);
+ decode(image_id, bl);
+ decode(snap_seqs, bl);
+ decode(overlap, bl);
+ decode(flatten, bl);
+ decode(mirroring, bl);
+ decode(state, bl);
+ decode(state_description, bl);
+ if (struct_v >= 2) {
+ uint8_t int_mode;
+ decode(int_mode, bl);
+ mirror_image_mode = static_cast<MirrorImageMode>(int_mode);
+ }
+ if (struct_v >= 3) {
+ decode(source_spec, bl);
+ }
+ DECODE_FINISH(bl);
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const std::map<uint64_t, uint64_t>& snap_seqs) {
+ os << "{";
+ size_t count = 0;
+ for (auto &it : snap_seqs) {
+ os << (count++ > 0 ? ", " : "") << "(" << it.first << ", " << it.second
+ << ")";
+ }
+ os << "}";
+ return os;
+}
+
+void MigrationSpec::dump(Formatter *f) const {
+ f->dump_stream("header_type") << header_type;
+ if (header_type == MIGRATION_HEADER_TYPE_SRC ||
+ source_spec.empty()) {
+ f->dump_int("pool_id", pool_id);
+ f->dump_string("pool_namespace", pool_namespace);
+ f->dump_string("image_name", image_name);
+ f->dump_string("image_id", image_id);
+ } else {
+ f->dump_string("source_spec", source_spec);
+ }
+ f->dump_stream("snap_seqs") << snap_seqs;
+ f->dump_unsigned("overlap", overlap);
+ f->dump_bool("mirroring", mirroring);
+ f->dump_stream("mirror_image_mode") << mirror_image_mode;
+}
+
+void MigrationSpec::generate_test_instances(std::list<MigrationSpec*> &o) {
+ o.push_back(new MigrationSpec());
+ o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC, 1, "ns",
+ "image_name", "image_id", "", {{1, 2}}, 123,
+ true, MIRROR_IMAGE_MODE_SNAPSHOT, true,
+ MIGRATION_STATE_PREPARED, "description"));
+ o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_DST, -1, "", "", "",
+ "{\"format\": \"raw\"}", {{1, 2}}, 123,
+ true, MIRROR_IMAGE_MODE_SNAPSHOT, true,
+ MIGRATION_STATE_PREPARED, "description"));
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const MigrationSpec& migration_spec) {
+ os << "["
+ << "header_type=" << migration_spec.header_type << ", ";
+ if (migration_spec.header_type == MIGRATION_HEADER_TYPE_SRC ||
+ migration_spec.source_spec.empty()) {
+ os << "pool_id=" << migration_spec.pool_id << ", "
+ << "pool_namespace=" << migration_spec.pool_namespace << ", "
+ << "image_name=" << migration_spec.image_name << ", "
+ << "image_id=" << migration_spec.image_id << ", ";
+ } else {
+ os << "source_spec=" << migration_spec.source_spec << ", ";
+ }
+ os << "snap_seqs=" << migration_spec.snap_seqs << ", "
+ << "overlap=" << migration_spec.overlap << ", "
+ << "flatten=" << migration_spec.flatten << ", "
+ << "mirroring=" << migration_spec.mirroring << ", "
+ << "mirror_image_mode=" << migration_spec.mirror_image_mode << ", "
+ << "state=" << migration_spec.state << ", "
+ << "state_description=" << migration_spec.state_description << "]";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const AssertSnapcSeqState& state) {
+ switch (state) {
+ case ASSERT_SNAPC_SEQ_GT_SNAPSET_SEQ:
+ os << "gt";
+ break;
+ case ASSERT_SNAPC_SEQ_LE_SNAPSET_SEQ:
+ os << "le";
+ break;
+ default:
+ os << "unknown (" << static_cast<uint32_t>(state) << ")";
+ break;
+ }
+ return os;
+}
+
+void sanitize_entity_inst(entity_inst_t* entity_inst) {
+ // make all addrs of type ANY because the type isn't what uniquely
+ // identifies them and clients and on-disk formats can be encoded
+ // with different backwards compatibility settings.
+ entity_inst->addr.set_type(entity_addr_t::TYPE_ANY);
+}
+
+} // namespace rbd
+} // namespace cls