}
int image_snapshot_set_copy_progress(cls_method_context_t hctx,
- uint64_t snap_id, bool copied,
+ uint64_t snap_id, bool complete,
uint64_t last_copied_object_number) {
cls_rbd_snap snap;
std::string snap_key;
return r;
}
- auto non_primary = boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
+ auto mirror_ns = boost::get<cls::rbd::MirrorSnapshotNamespace>(
&snap.snapshot_namespace);
- if (non_primary == nullptr) {
+ if (mirror_ns == nullptr) {
CLS_LOG(5, "mirror_image_snapshot_set_copy_progress " \
"not mirroring snapshot snap_id=%" PRIu64, snap_id);
return -EINVAL;
}
- non_primary->copied = copied;
- non_primary->last_copied_object_number = last_copied_object_number;
+ mirror_ns->complete = complete;
+ if (mirror_ns->state == cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY ||
+ mirror_ns->state == cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED) {
+ mirror_ns->last_copied_object_number = last_copied_object_number;
+ }
r = image::snapshot::write(hctx, snap_key, std::move(snap));
if (r < 0) {
/**
* Input:
* @param snap_id: snapshot id
- * @param copied: true if shapshot fully copied
+ * @param complete: true if shapshot fully copied/complete
* @param last_copied_object_number: last copied object number
*
* Output:
bufferlist *in,
bufferlist *out) {
uint64_t snap_id;
- bool copied;
+ bool complete;
uint64_t last_copied_object_number;
try {
auto iter = in->cbegin();
decode(snap_id, iter);
- decode(copied, iter);
+ decode(complete, iter);
decode(last_copied_object_number, iter);
} catch (const buffer::error &err) {
return -EINVAL;
}
CLS_LOG(20, "mirror_image_snapshot_set_copy_progress snap_id=%" PRIu64 \
- " copied=%d last_copied_object_number=%" PRIu64, snap_id, copied,
+ " complete=%d last_copied_object_number=%" PRIu64, snap_id, complete,
last_copied_object_number);
- int r = mirror::image_snapshot_set_copy_progress(hctx, snap_id, copied,
+ int r = mirror::image_snapshot_set_copy_progress(hctx, snap_id, complete,
last_copied_object_number);
if (r < 0) {
return r;
}
void mirror_image_snapshot_set_copy_progress(librados::ObjectWriteOperation *op,
- snapid_t snap_id, bool copied,
+ snapid_t snap_id, bool complete,
uint64_t copy_progress) {
bufferlist bl;
encode(snap_id, bl);
- encode(copied, bl);
+ encode(complete, bl);
encode(copy_progress, bl);
op->exec("rbd", "mirror_image_snapshot_set_copy_progress", bl);
int mirror_image_snapshot_set_copy_progress(librados::IoCtx *ioctx,
const std::string &oid,
- snapid_t snap_id, bool copied,
+ snapid_t snap_id, bool complete,
uint64_t copy_progress) {
librados::ObjectWriteOperation op;
- mirror_image_snapshot_set_copy_progress(&op, snap_id, copied, copy_progress);
+ mirror_image_snapshot_set_copy_progress(&op, snap_id, complete,
+ copy_progress);
return ioctx->operate(oid, &op);
}
snapid_t snap_id,
const std::string &mirror_peer_uuid);
void mirror_image_snapshot_set_copy_progress(librados::ObjectWriteOperation *op,
- snapid_t snap_id, bool copied,
+ snapid_t snap_id, bool complete,
uint64_t copy_progress);
int mirror_image_snapshot_set_copy_progress(librados::IoCtx *ioctx,
const std::string &oid,
- snapid_t snap_id, bool copied,
+ snapid_t snap_id, bool complete,
uint64_t copy_progress);
// Groups functions
f->dump_stream("snap_seqs") << snap_seqs;
}
-void MirrorNonPrimarySnapshotNamespace::encode(bufferlist& bl) const {
- using ceph::encode;
- encode(primary_mirror_uuid, bl);
- encode(primary_snap_id, bl);
- encode(copied, bl);
- encode(last_copied_object_number, bl);
- encode(snap_seqs, bl);
-}
-
-void MirrorNonPrimarySnapshotNamespace::decode(bufferlist::const_iterator& it) {
- using ceph::decode;
- decode(primary_mirror_uuid, it);
- decode(primary_snap_id, it);
- decode(copied, it);
- decode(last_copied_object_number, it);
- decode(snap_seqs, it);
-}
-
-void MirrorNonPrimarySnapshotNamespace::dump(Formatter *f) const {
- f->dump_string("primary_mirror_uuid", primary_mirror_uuid);
- f->dump_unsigned("primary_snap_id", primary_snap_id);
- f->dump_bool("copied", copied);
- 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) {
MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_NON_PRIMARY,
{"1", "2"}, "uuid", 123},
"snap1", 123, {123456, 0}, 12));
- o.push_back(new SnapshotInfo(1ULL,
- MirrorNonPrimarySnapshotNamespace{"uuid", 111},
- "snap1", 123, {123456, 0}, 12));
}
void SnapshotNamespace::encode(bufferlist& bl) const {
case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR:
*this = MirrorSnapshotNamespace();
break;
- case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY:
- *this = MirrorNonPrimarySnapshotNamespace();
- break;
default:
*this = UnknownSnapshotNamespace();
break;
o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED,
{"peer uuid"},
"uuid", 123)));
- o.push_back(new SnapshotNamespace(MirrorNonPrimarySnapshotNamespace("", 0)));
}
std::ostream& operator<<(std::ostream& os, const SnapshotNamespaceType& type) {
case SNAPSHOT_NAMESPACE_TYPE_MIRROR:
os << "mirror";
break;
- case SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY:
- os << "mirror_non_primary";
- break;
default:
os << "unknown";
break;
return os;
}
-std::ostream& operator<<(std::ostream& os,
- const MirrorNonPrimarySnapshotNamespace& ns) {
- os << "[" << SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY << " "
- << "primary_mirror_uuid=" << ns.primary_mirror_uuid << ", "
- << "primary_snap_id=" << ns.primary_snap_id << ", "
- << "copied=" << ns.copied << ", "
- << "last_copied_object_number=" << ns.last_copied_object_number << ", "
- << "snap_seqs=" << ns.snap_seqs
- << "]";
- return os;
-}
-
std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) {
os << "[unknown]";
return os;
break;
}
return os;
-
}
void ImageSnapshotSpec::encode(bufferlist& bl) const {
WRITE_CLASS_ENCODER(GroupSpec);
enum SnapshotNamespaceType {
- SNAPSHOT_NAMESPACE_TYPE_USER = 0,
- SNAPSHOT_NAMESPACE_TYPE_GROUP = 1,
- SNAPSHOT_NAMESPACE_TYPE_TRASH = 2,
- SNAPSHOT_NAMESPACE_TYPE_MIRROR = 3,
- SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY = 4,
+ SNAPSHOT_NAMESPACE_TYPE_USER = 0,
+ SNAPSHOT_NAMESPACE_TYPE_GROUP = 1,
+ SNAPSHOT_NAMESPACE_TYPE_TRASH = 2,
+ SNAPSHOT_NAMESPACE_TYPE_MIRROR = 3,
};
struct UserSnapshotNamespace {
}
};
-struct MirrorNonPrimarySnapshotNamespace {
- static const SnapshotNamespaceType SNAPSHOT_NAMESPACE_TYPE =
- SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY;
-
- std::string primary_mirror_uuid;
- snapid_t primary_snap_id = CEPH_NOSNAP;
- bool copied = false;
- uint64_t last_copied_object_number = 0;
- SnapSeqs snap_seqs;
-
- MirrorNonPrimarySnapshotNamespace() {
- }
- MirrorNonPrimarySnapshotNamespace(const std::string &primary_mirror_uuid,
- snapid_t primary_snap_id)
- : primary_mirror_uuid(primary_mirror_uuid),
- primary_snap_id(primary_snap_id) {
- }
-
- void encode(bufferlist& bl) const;
- void decode(bufferlist::const_iterator& it);
-
- void dump(Formatter *f) const;
-
- inline bool operator==(const MirrorNonPrimarySnapshotNamespace& mnsn) const {
- return primary_mirror_uuid == mnsn.primary_mirror_uuid &&
- primary_snap_id == mnsn.primary_snap_id && copied == mnsn.copied &&
- last_copied_object_number == mnsn.last_copied_object_number;
- }
-
- inline bool operator<(const MirrorNonPrimarySnapshotNamespace& mnsn) const {
- if (primary_mirror_uuid != mnsn.primary_mirror_uuid) {
- return primary_mirror_uuid < mnsn.primary_mirror_uuid;
- }
- if (primary_snap_id != mnsn.primary_snap_id) {
- return primary_snap_id < mnsn.primary_snap_id;
- }
- if (copied != mnsn.copied) {
- return copied < mnsn.copied;
- }
- return last_copied_object_number < mnsn.last_copied_object_number;
- }
-};
-
struct UnknownSnapshotNamespace {
static const SnapshotNamespaceType SNAPSHOT_NAMESPACE_TYPE =
static_cast<SnapshotNamespaceType>(-1);
std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns);
std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns);
std::ostream& operator<<(std::ostream& os, const MirrorSnapshotNamespace& ns);
-std::ostream& operator<<(std::ostream& os,
- const MirrorNonPrimarySnapshotNamespace& ns);
std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns);
typedef boost::variant<UserSnapshotNamespace,
GroupSnapshotNamespace,
TrashSnapshotNamespace,
MirrorSnapshotNamespace,
- MirrorNonPrimarySnapshotNamespace,
UnknownSnapshotNamespace> SnapshotNamespaceVariant;
struct SnapshotNamespace : public SnapshotNamespaceVariant {
snap_namespace.last_copied_object_number;
return 0;
}
-
- inline int operator()(
- const cls::rbd::MirrorNonPrimarySnapshotNamespace& snap_namespace) {
- mirror_snap->state = RBD_SNAP_MIRROR_STATE_NON_PRIMARY;
- mirror_snap->primary_mirror_uuid = snap_namespace.primary_mirror_uuid;
- mirror_snap->primary_snap_id = snap_namespace.primary_snap_id;
- mirror_snap->complete = snap_namespace.copied;
- mirror_snap->last_copied_object_number =
- snap_namespace.last_copied_object_number;
- return 0;
- }
};
} // anonymous namespace
snap_info.snap_namespace);
switch (snap_namespace_type) {
case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR:
- case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY:
return true;
default:
return false;
auto &snap_info = it.second;
auto type = cls::rbd::get_snap_namespace_type(
snap_info.snap_namespace);
- if (type == cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR ||
- type == cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY) {
+ if (type == cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR) {
send_remove_snap("", snap_info.snap_namespace, snap_info.name);
removing_snapshots = true;
}
}
break;
}
-
- auto non_primary =
- boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
- &it->second.snap_namespace);
- if (non_primary != nullptr) {
- if (non_primary->primary_mirror_uuid.empty()) {
- *m_promotion_state = PROMOTION_STATE_ORPHAN;
- } else {
- *m_promotion_state = PROMOTION_STATE_NON_PRIMARY;
- *m_primary_mirror_uuid = non_primary->primary_mirror_uuid;
- }
- break;
- }
}
ldout(m_cct, 10) << "promotion_state=" << *m_promotion_state << ", "
CephContext *cct = m_image_ctx->cct;
ldout(cct, 20) << dendl;
- cls::rbd::MirrorNonPrimarySnapshotNamespace ns{m_primary_mirror_uuid,
- m_primary_snap_id};
+ cls::rbd::MirrorSnapshotNamespace ns{
+ cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY, {},
+ m_primary_mirror_uuid, m_primary_snap_id};
auto ctx = create_context_callback<
CreateNonPrimaryRequest<I>,
&CreateNonPrimaryRequest<I>::handle_create_snapshot>(this);
uint64_t snap_id;
{
std::shared_lock image_locker{m_image_ctx->image_lock};
- cls::rbd::MirrorNonPrimarySnapshotNamespace ns{m_primary_mirror_uuid,
- m_primary_snap_id};
+ cls::rbd::MirrorSnapshotNamespace ns{
+ cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY, {},
+ m_primary_mirror_uuid, m_primary_snap_id};
snap_id = m_image_ctx->get_snap_id(ns, m_snap_name);
}
size_t count = 0;
uint64_t prev_snap_id = 0;
for (auto &snap_it : m_image_ctx->snap_info) {
- if (boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
- &snap_it.second.snap_namespace)) {
- // reset counters -- we count primary snapshots after the last promotion
- count = 0;
- prev_snap_id = 0;
- continue;
- }
auto info = boost::get<cls::rbd::MirrorSnapshotNamespace>(
&snap_it.second.snap_namespace);
if (info == nullptr) {
for (auto &[snap_id, snap_info] : m_image_ctx->snap_info) {
auto type = cls::rbd::get_snap_namespace_type(snap_info.snap_namespace);
- if (type == cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR ||
- type == cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY) {
+ if (type == cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR) {
continue;
}
m_image_state.snapshots[snap_id] = {snap_id, snap_info.snap_namespace,
uint64_t *rollback_snap_id) {
for (; it != end; it++) {
- auto primary = boost::get<cls::rbd::MirrorSnapshotNamespace>(
+ auto mirror_ns = boost::get<cls::rbd::MirrorSnapshotNamespace>(
&it->second.snap_namespace);
- if (primary != nullptr) {
+ if (mirror_ns->state != cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY) {
break;
}
-
- auto non_primary = boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
- &it->second.snap_namespace);
- if (non_primary->copied) {
+ if (mirror_ns->complete) {
break;
}
}
for (auto it = image_ctx->snap_info.rbegin();
it != image_ctx->snap_info.rend(); it++) {
- auto non_primary = boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
- &it->second.snap_namespace);
- if (non_primary != nullptr) {
- ldout(cct, 20) << "previous mirror snapshot snap_id=" << it->first << " "
- << *non_primary << dendl;
- if (!force) {
- lderr(cct) << "trying to create primary snapshot without force "
- << "when previous snapshot is non-primary"
- << dendl;
- return false;
- }
- if (demoted) {
- lderr(cct) << "trying to create primary demoted snapshot "
- << "when previous snapshot is non-primary"
- << dendl;
- return false;
- }
- if (!non_primary->primary_mirror_uuid.empty() && !non_primary->copied) {
- ldout(cct, 20) << "needs rollback" << dendl;
- if (!rollback_snap_id) {
- lderr(cct) << "trying to create primary snapshot "
- << "when previous non-primary snapshot is not copied yet"
- << dendl;
- return false;
- }
- if (!get_rollback_snap_id(++it, image_ctx->snap_info.rend(),
- rollback_snap_id)) {
- lderr(cct) << "cannot rollback" << dendl;
- return false;
- }
- ldout(cct, 20) << "rollback_snap_id=" << *rollback_snap_id << dendl;
- }
- return true;
- }
-
auto mirror_ns = boost::get<cls::rbd::MirrorSnapshotNamespace>(
&it->second.snap_namespace);
if (mirror_ns == nullptr) {
}
return true;
}
-
- auto non_primary = boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
- &it->second.snap_namespace);
- if (non_primary == nullptr) {
- continue;
- }
- ldout(cct, 20) << "previous snapshot snap_id=" << it->first << " "
- << *non_primary << dendl;
- if (!non_primary->copied) {
- lderr(cct) << "trying to create non-primary snapshot "
- << "when previous non-primary snapshot is not copied yet"
- << dendl;
- return false;
- }
- return true;
}
ldout(cct, 20) << "no previous mirror snapshots found" << dendl;
I &image_ctx = this->m_image_ctx;
auto type = cls::rbd::get_snap_namespace_type(m_snap_namespace);
- if (type != cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR &&
- type != cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR_NON_PRIMARY) {
+ if (type != cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR) {
release_snap_id();
return;
}
cls::rbd::MirrorSnapshotNamespace primary = {
cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"peer1", "peer2"}, "",
CEPH_NOSNAP};
- cls::rbd::MirrorNonPrimarySnapshotNamespace non_primary = {"uuid", 123};
+ cls::rbd::MirrorSnapshotNamespace non_primary = {
+ cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY, {}, "uuid", 123};
librados::ObjectWriteOperation op;
::librbd::cls_client::snapshot_add(&op, 1, "primary", primary);
::librbd::cls_client::snapshot_add(&op, 2, "non_primary", non_primary);
ASSERT_EQ(1U, sn->mirror_peer_uuids.count("peer2"));
ASSERT_EQ(0, snapshot_get(&ioctx, oid, 2, &snap));
- auto nsn = boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
+ auto nsn = boost::get<cls::rbd::MirrorSnapshotNamespace>(
&snap.snapshot_namespace);
ASSERT_NE(nullptr, nsn);
ASSERT_EQ(non_primary, *nsn);
- ASSERT_FALSE(nsn->copied);
+ ASSERT_FALSE(nsn->complete);
ASSERT_EQ(nsn->last_copied_object_number, 0);
ASSERT_EQ(0, mirror_image_snapshot_set_copy_progress(&ioctx, oid, 2, true,
10));
ASSERT_EQ(0, snapshot_get(&ioctx, oid, 2, &snap));
- nsn = boost::get<cls::rbd::MirrorNonPrimarySnapshotNamespace>(
+ nsn = boost::get<cls::rbd::MirrorSnapshotNamespace>(
&snap.snapshot_namespace);
ASSERT_NE(nullptr, nsn);
- ASSERT_TRUE(nsn->copied);
+ ASSERT_TRUE(nsn->complete);
ASSERT_EQ(nsn->last_copied_object_number, 10);
ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 1));
&rollback_snap_id));
ASSERT_EQ(rollback_snap_id, CEPH_NOSNAP);
- cls::rbd::MirrorNonPrimarySnapshotNamespace nns{"mirror_uuid", 123};
- nns.copied = true;
+ cls::rbd::MirrorSnapshotNamespace nns{
+ cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY, {}, "mirror_uuid", 123};
+ nns.complete = true;
auto copied_snap_id = snap_create(mock_image_ctx, nns, "NPS1");
// without force, previous snapshot is non-primary
&rollback_snap_id));
ASSERT_EQ(rollback_snap_id, CEPH_NOSNAP);
- nns.copied = false;
+ nns.complete = false;
snap_create(mock_image_ctx, nns, "NPS2");
// previous non-primary snapshot is not copied yet
&rollback_snap_id));
ASSERT_EQ(rollback_snap_id, copied_snap_id);
- nns.primary_mirror_uuid.clear();
+ nns.state = cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED;
snap_create(mock_image_ctx, nns, "NPS3");
// previous non-primary snapshot is orphan
// no previous mirror snapshots found
ASSERT_TRUE(util::can_create_non_primary_snapshot(&mock_image_ctx));
- cls::rbd::MirrorNonPrimarySnapshotNamespace nns{"mirror_uuid", 123};
+ cls::rbd::MirrorSnapshotNamespace nns{
+ cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY, {}, "mirror_uuid", 123};
snap_create(mock_image_ctx, nns, "NPS1");
// previous non-primary snapshot is not copied yet
ASSERT_FALSE(util::can_create_non_primary_snapshot(&mock_image_ctx));
- nns.copied = true;
+ nns.complete = true;
snap_create(mock_image_ctx, nns, "NPS2");
// previous non-primary snapshot is copied