}
bool is_user_snapshot(const cls::rbd::GroupSnapshot &group_snap) {
- auto ns = std::get_if<cls::rbd::UserGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceUser>(
&group_snap.snapshot_namespace);
return ns != nullptr;
}
}
for (auto it = snaps.rbegin(); it != snaps.rend(); it++) {
- auto ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&it->snapshot_namespace);
if (ns != nullptr) {
// XXXMG: check primary_mirror_uuid matches?
return r;
}
- group_snap->snapshot_namespace = cls::rbd::MirrorGroupSnapshotNamespace{
+ group_snap->snapshot_namespace = cls::rbd::GroupSnapshotNamespaceMirror{
state, mirror_peer_uuids, {}, {}};
for (auto image_ctx: *image_ctxs) {
uuid_gen.generate_random();
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceMirror{},
prepare_primary_mirror_snap_name(cct, uuid_gen.to_string(),
group_snap_id),
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
}
for (auto &snap : snaps) {
- auto ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&snap.snapshot_namespace);
if (ns == nullptr) {
continue;
std::string group_snap_id = librbd::util::generate_image_id(group_ioctx);
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceMirror{},
prepare_primary_mirror_snap_name(cct, mirror_group.global_group_id,
group_snap_id),
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
std::string group_snap_id = librbd::util::generate_image_id(group_ioctx);
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceMirror{},
prepare_primary_mirror_snap_name(cct, mirror_group.global_group_id,
group_snap_id),
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
<< " is primary, cannot resync to itself" << dendl;
return -EINVAL;
}
+ bufferlist bl;
+ bl.append("true");
- r = cls_client::mirror_group_resync_set(&group_ioctx,
- librbd::util::group_header_name(group_id),
- mirror_group.global_group_id,
- group_name, group_id);
+ r = cls_client::metadata_set(&group_ioctx,
+ librbd::util::group_header_name(group_id),
+ {{RBD_GROUP_RESYNC, bl}});
if (r < 0) {
- lderr(cct) << "setting group resync with global_group_id="
- << mirror_group.global_group_id << " failed: "
- << cpp_strerror(r) << dendl;
+ lderr(cct) << "failed setting metadata: " << cpp_strerror(r) << dendl;
return r;
}
std::string group_snap_id = librbd::util::generate_image_id(group_ioctx);
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceMirror{},
prepare_primary_mirror_snap_name(cct, mirror_group.global_group_id,
group_snap_id),
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
std::string group_snap_id = librbd::util::generate_image_id(group_ioctx);
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceMirror{},
prepare_primary_mirror_snap_name(cct, mirror_info.global_group_id,
group_snap_id),
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
std::string group_snap_id = librbd::util::generate_image_id(group_ioctx);
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceMirror{},
prepare_primary_mirror_snap_name(cct, mirror_info.global_group_id,
group_snap_id),
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
librados::snap_t get_group_snap_id(
I *ictx, const cls::rbd::SnapshotNamespace& in_snap_namespace) {
ceph_assert(ceph_mutex_is_locked(ictx->image_lock));
- auto it = ictx->snap_ids.lower_bound({cls::rbd::GroupImageSnapshotNamespace{},
+ auto it = ictx->snap_ids.lower_bound({cls::rbd::ImageSnapshotNamespaceGroup{},
""});
for (; it != ictx->snap_ids.end(); ++it) {
if (it->first.first == in_snap_namespace) {
return it->second;
- } else if (std::get_if<cls::rbd::GroupImageSnapshotNamespace>(
+ } else if (std::get_if<cls::rbd::ImageSnapshotNamespaceGroup>(
&it->first.first) == nullptr) {
break;
}
std::vector<librbd::ImageCtx*> ictxs;
- cls::rbd::GroupImageSnapshotNamespace snap_namespace{group_ioctx.get_id(),
+ cls::rbd::ImageSnapshotNamespaceGroup snap_namespace{group_ioctx.get_id(),
group_id, group_snap.id};
ldout(cct, 20) << "Removing snapshot with group snap_id: " << group_snap.id
if (m_snap_seqs.find(src_snap_id) == m_snap_seqs.end()) {
// the source snapshot is not in our mapping table, ...
if (std::holds_alternative<cls::rbd::UserSnapshotNamespace>(snap_namespace) ||
- std::holds_alternative<cls::rbd::GroupImageSnapshotNamespace>(snap_namespace)) {
+ std::holds_alternative<cls::rbd::ImageSnapshotNamespaceGroup>(snap_namespace)) {
// ... create it since it's a user snapshot
break;
} else if (src_snap_id == m_src_snap_id_end) {
{cls::rbd::UserSnapshotNamespace(), m_snap_name});
if (snap_it == m_dst_image_ctx->snap_ids.end()) {
snap_it = m_dst_image_ctx->snap_ids.find(
- {cls::rbd::GroupImageSnapshotNamespace(), m_snap_name});
+ {cls::rbd::ImageSnapshotNamespaceGroup(), m_snap_name});
}
ceph_assert(snap_it != m_dst_image_ctx->snap_ids.end());
librados::snap_t dst_snap_id = snap_it->second;
m_dst_image_ctx->image_lock.lock_shared();
auto snap_it = m_dst_image_ctx->snap_ids.find(
- {cls::rbd::UserSnapshotNamespace(), m_snap_name});
+ {cls::rbd::UserSnapshotNamespace(), m_snap_name});
+ if (snap_it == m_dst_image_ctx->snap_ids.end()) {
+ snap_it = m_dst_image_ctx->snap_ids.find(
+ {cls::rbd::ImageSnapshotNamespaceGroup(), m_snap_name});
+ }
if (snap_it == m_dst_image_ctx->snap_ids.end()) {
lderr(m_cct) << "failed to locate snap: " << m_snap_name << dendl;
m_dst_image_ctx->image_lock.unlock_shared();
auto unlink_unsynced_snap = snaps.end();
bool unlink_unsynced = false;
for (auto it = snaps.begin(); it != snaps.end(); it++) {
- auto ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&it->snapshot_namespace);
if (ns != nullptr) {
// FIXME: after relocate, on new primary the previous primary demoted
return;
} else if (r == -ENOENT) {
r = 0;
- m_mirror_image.group_spec = {m_group_id, m_group_pool_id};
+ if (!m_group_snap_id.empty()) {
+ m_mirror_image.type = cls::rbd::MIRROR_IMAGE_TYPE_GROUP;
+ }
} else {
lderr(m_cct) << "failed to retrieve mirror image: " << cpp_strerror(r)
<< dendl;
template <typename I>
void ImageStateUpdateRequest<I>::notify_mirroring_watcher() {
// skip image notification if mirroring for the image group is disabled
- if (m_mirror_image.group_spec.is_valid()) {
+ if (m_mirror_image.type == cls::rbd::MIRROR_IMAGE_TYPE_GROUP) {
finish(0);
return;
}
template <typename I>
CreateNonPrimaryRequest<I>::CreateNonPrimaryRequest(
- I* image_ctx, bool demoted, const std::string &primary_mirror_uuid,
+ I* image_ctx, bool demoted, const std::string group_id,
+ const std::string group_snap_id, const std::string &primary_mirror_uuid,
uint64_t primary_snap_id, const SnapSeqs& snap_seqs,
const ImageState &image_state, uint64_t *snap_id, Context *on_finish)
: m_image_ctx(image_ctx), m_demoted(demoted),
+ m_group_id(group_id), m_group_snap_id(group_snap_id),
m_primary_mirror_uuid(primary_mirror_uuid),
m_primary_snap_id(primary_snap_id), m_snap_seqs(snap_seqs),
m_image_state(image_state), m_snap_id(snap_id), m_on_finish(on_finish) {
if (m_demoted) {
ns.mirror_peer_uuids = m_mirror_peer_uuids;
}
+ if (!m_group_snap_id.empty()) {
+ ns.group_spec = {m_group_id, m_image_ctx->md_ctx.get_id()};
+ ns.group_snap_id = m_group_snap_id;
+ }
ns.snap_seqs = m_snap_seqs;
ns.complete = is_orphan();
ldout(cct, 15) << "ns=" << ns << dendl;
public:
static CreateNonPrimaryRequest *create(ImageCtxT *image_ctx,
bool demoted,
+ const std::string group_id,
+ const std::string group_snap_id,
const std::string &primary_mirror_uuid,
uint64_t primary_snap_id,
const SnapSeqs& snap_seqs,
const ImageState &image_state,
uint64_t *snap_id,
Context *on_finish) {
- return new CreateNonPrimaryRequest(image_ctx, demoted, primary_mirror_uuid,
+ return new CreateNonPrimaryRequest(image_ctx, demoted, group_id,
+ group_snap_id, primary_mirror_uuid,
primary_snap_id, snap_seqs,
image_state, snap_id, on_finish);
}
CreateNonPrimaryRequest(ImageCtxT *image_ctx,
bool demoted,
+ const std::string group_id,
+ const std::string group_snap_id,
const std::string &primary_mirror_uuid,
uint64_t primary_snap_id,
const SnapSeqs& snap_seqs,
ImageCtxT *m_image_ctx;
const bool m_demoted;
+ const std::string m_group_id;
+ const std::string m_group_snap_id;
const std::string m_primary_mirror_uuid;
const uint64_t m_primary_snap_id;
const SnapSeqs m_snap_seqs;
&PromoteRequest<I>::handle_create_orphan_snapshot>(this);
auto req = CreateNonPrimaryRequest<I>::create(
- m_image_ctx, false, "", CEPH_NOSNAP, {}, {}, nullptr, ctx);
+ m_image_ctx, false, "", "", "", CEPH_NOSNAP, {}, {}, nullptr, ctx);
req->send();
}
expect_write_image_state(mock_image_ctx, mock_write_image_state_request, 0);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
expect_write_image_state(mock_image_ctx, mock_write_image_state_request, 0);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, true,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, true, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
expect_refresh_image(mock_image_ctx, true, -EINVAL);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, -EINVAL);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
expect_can_create_non_primary_snapshot(mock_utils, false);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
expect_get_mirror_peers(mock_image_ctx, {}, -EPERM);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, true,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, true, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
expect_create_snapshot(mock_image_ctx, -EINVAL);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
-EINVAL);
C_SaferCond ctx;
- auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false,
+ auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, false, "", "",
"mirror_uuid", 123, {{1, 2}}, {},
nullptr, &ctx);
req->send();
static CreateNonPrimaryRequest* s_instance;
static CreateNonPrimaryRequest *create(MockTestImageCtx *image_ctx,
bool demoted,
+ const std::string group_id,
+ const std::string group_snap_id,
const std::string &primary_mirror_uuid,
uint64_t primary_snap_id,
SnapSeqs snap_seqs,
bool is_demoted_snap_exists(
const std::vector<cls::rbd::GroupSnapshot> &snaps) {
for (auto it = snaps.rbegin(); it != snaps.rend(); it++) {
- auto ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&it->snapshot_namespace);
if (ns != nullptr) {
if (ns->is_demoted()) {
const std::vector<cls::rbd::GroupSnapshot> &snaps,
cls::rbd::MirrorSnapshotState *state) {
for (auto it = snaps.rbegin(); it != snaps.rend(); it++) {
- auto ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&it->snapshot_namespace);
if (ns != nullptr) {
// XXXMG: check primary_mirror_uuid matches?
void BootstrapRequest<I>::send() {
*m_resync_requested = false;
- std::string group_id;
-
if (m_local_group_id && !m_local_group_id->empty()) {
std::string group_header_oid = librbd::util::group_header_name(
*m_local_group_id);
- int r = librbd::cls_client::mirror_group_resync_get(&m_local_io_ctx,
- group_header_oid,
- m_global_group_id,
- m_local_group_ctx->name,
- &group_id);
- if (r < 0) {
- derr << "getting mirror group resync for global_group_id="
- << m_global_group_id << " failed: " << cpp_strerror(r) << dendl;
- } else if (r == 0 && group_id == *m_local_group_id) {
+ std::string value;
+ int r = librbd::cls_client::metadata_get(&m_local_io_ctx, group_header_oid,
+ RBD_GROUP_RESYNC, &value);
+ if (r < 0 && r != -ENOENT) {
+ derr << "failed reading metadata: " << cpp_strerror(r) << dendl;
+ } else if (r == 0) {
*m_resync_requested = true;
}
}
std::string group_snap_id = librbd::util::generate_image_id(m_local_io_ctx);
cls::rbd::GroupSnapshot group_snap{
group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{
+ cls::rbd::GroupSnapshotNamespaceMirror{
cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY,
{}, remote_pool_meta.mirror_peer_uuid, {}},
prepare_non_primary_mirror_snap_name(m_global_group_id, group_snap_id),
bool Replayer<I>::is_resync_requested() {
dout(10) << "m_local_group_id=" << m_local_group_id << dendl;
- std::string group_id;
std::string group_header_oid = librbd::util::group_header_name(
m_local_group_id);
- int r = librbd::cls_client::mirror_group_resync_get(&m_local_io_ctx,
- group_header_oid,
- m_global_group_id,
- m_local_group_ctx->name,
- &group_id);
- if (r < 0 && r != -EINVAL) {
- derr << "getting mirror group resync for global_group_id="
- << m_global_group_id << " failed: " << cpp_strerror(r) << dendl;
- } else if (r == 0 && group_id == m_local_group_id) {
+ std::string value;
+ int r = librbd::cls_client::metadata_get(&m_local_io_ctx, group_header_oid,
+ RBD_GROUP_RESYNC, &value);
+ if (r < 0 && r != -ENOENT) {
+ derr << "failed reading metadata: " << cpp_strerror(r) << dendl;
+ } else if (r == 0) {
return true;
}
for (auto it = m_local_group_snaps.rbegin();
it != m_local_group_snaps.rend(); it++) {
- auto ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&it->snapshot_namespace);
if (ns == nullptr) {
continue;
return;
}
- auto last_local_snap_ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto last_local_snap_ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&last_local_snap->snapshot_namespace);
if (last_local_snap_ns &&
last_local_snap_ns->state == cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED &&
local_snap != m_local_group_snaps.rend(); ++local_snap) {
auto snap_type = cls::rbd::get_group_snap_namespace_type(
local_snap->snapshot_namespace);
- auto local_snap_ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto local_snap_ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&local_snap->snapshot_namespace);
auto next_remote_snap = m_remote_group_snaps.end();
if (snap_type == cls::rbd::GROUP_SNAPSHOT_NAMESPACE_TYPE_USER ||
if (snap_type != cls::rbd::GROUP_SNAPSHOT_NAMESPACE_TYPE_MIRROR) {
continue;
}
- auto prev_remote_snap_ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto prev_remote_snap_ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&prev_remote_snap->snapshot_namespace);
if (prev_remote_snap_ns && prev_remote_snap_ns->is_demoted()) {
break;
auto snap_type = cls::rbd::get_group_snap_namespace_type(
snap.snapshot_namespace);
if (snap_type == cls::rbd::GROUP_SNAPSHOT_NAMESPACE_TYPE_MIRROR) {
- auto snap_ns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto snap_ns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&snap.snapshot_namespace);
if (snap_ns->is_non_primary()) {
dout(10) << "remote group snapshot: " << snap.id << "is non primary"
{remote_group_snap_id, {}}).first;
cls::rbd::GroupSnapshot local_snap =
{remote_group_snap_id,
- cls::rbd::MirrorGroupSnapshotNamespace{
+ cls::rbd::GroupSnapshotNamespaceMirror{
snap_state, {}, m_remote_mirror_uuid, remote_group_snap_id},
{}, cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
local_snap.name = prepare_non_primary_mirror_snap_name(m_global_group_id,
return s.id == remote_group_snap_id;
});
if (itr->snaps.size() != 0) {
- // update image snap
- C_SaferCond *ctx = new C_SaferCond;
- update_image_snapshot(remote_group_snap_id, *spec, ctx);
- ctx->wait();
-
// update the group snap with snap spec
itl->snaps.push_back(*spec);
}
});
ceph_assert(itr != m_remote_group_snaps.end());
- auto rns = std::get_if<cls::rbd::MirrorGroupSnapshotNamespace>(
+ auto rns = std::get_if<cls::rbd::GroupSnapshotNamespaceMirror>(
&itr->snapshot_namespace);
if (rns != nullptr) {
rns->mirror_peer_uuids.clear();
}
}
-template <typename I>
-void Replayer<I>::update_image_snapshot(
- const std::string &remote_group_snap_id,
- cls::rbd::ImageSnapshotSpec spec,
- Context *on_finish) {
- dout(10) << "local group snap info: "
- << "image snap id: " << spec.snap_id
- << ", image id: " << spec.image_id
- << ", group snap id: " << remote_group_snap_id
- << dendl;
- std::string image_header_oid = librbd::util::header_name(spec.image_id);
- cls::rbd::SnapshotInfo snap_info;
- int r = librbd::cls_client::snapshot_get(&m_local_io_ctx, image_header_oid,
- spec.snap_id, &snap_info);
- if (r < 0) {
- derr << "failed getting snap info for snap id: " << spec.snap_id
- << ", : " << cpp_strerror(r) << dendl;
- return;
- }
- auto mirror_ns = std::get_if<cls::rbd::MirrorSnapshotNamespace>(
- &snap_info.snapshot_namespace);
- ceph_assert(mirror_ns != nullptr);
- mirror_ns->group_spec = {m_local_group_id, spec.pool};
- mirror_ns->group_snap_id = remote_group_snap_id;
-
- // write to disk
- librados::ObjectWriteOperation op;
- librbd::cls_client::snapshot_add(&op, snap_info.id, snap_info.name,
- *mirror_ns);
- auto comp = create_rados_callback(
- new LambdaContext([this, snap_info, on_finish](int r) {
- handle_update_image_snapshot(r, snap_info.id, on_finish);
- }));
- r = m_local_io_ctx.aio_operate(image_header_oid, comp, &op);
- ceph_assert(r == 0);
- comp->release();
-}
-
-template <typename I>
-void Replayer<I>::handle_update_image_snapshot(
- int r, uint64_t local_snap_id, Context *on_finish) {
- dout(10) << "snap id: " << local_snap_id << ", r=" << r << dendl;
- on_finish->complete(r);
-}
-
template <typename I>
void Replayer<I>::create_regular_snapshot(
const std::string &remote_group_snap_name,
librados::ObjectWriteOperation op;
cls::rbd::GroupSnapshot group_snap{
remote_group_snap_id, // keeping it same as remote group snap id
- cls::rbd::UserGroupSnapshotNamespace{},
+ cls::rbd::GroupSnapshotNamespaceUser{},
remote_group_snap_name,
cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE};
void unlink_group_snapshots(const std::string &remote_group_snap_id);
- void update_image_snapshot(
- const std::string &remote_group_snap_id,
- cls::rbd::ImageSnapshotSpec spec,
- Context *on_finish);
- void handle_update_image_snapshot(
- int r, uint64_t local_snap_id, Context *on_finish);
-
void create_regular_snapshot(
const std::string &remote_group_snap_name,
const std::string &remote_group_snap_id,
}
if (m_mirror_image.state == cls::rbd::MIRROR_IMAGE_STATE_CREATING &&
- !m_mirror_image.group_spec.is_valid()) {
+ m_mirror_image.type == cls::rbd::MIRROR_IMAGE_TYPE_STANDALONE) {
dout(5) << "local image is still in creating state, issuing a removal"
<< dendl;
move_to_trash();
// need to send 'disabling' since the cls methods will fail if we aren't
// in that state
- cls::rbd::GroupSpec group_spec;
+ cls::rbd::MirrorImageType type = cls::rbd::MIRROR_IMAGE_TYPE_STANDALONE;
if (m_local_group_ctx != nullptr) {
- group_spec = {m_local_group_ctx->group_id,
- m_local_group_ctx->io_ctx.get_id()};
+ type = cls::rbd::MIRROR_IMAGE_TYPE_GROUP;
}
cls::rbd::MirrorImage mirror_image{
- cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, m_global_image_id, group_spec,
+ cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, m_global_image_id, type,
cls::rbd::MIRROR_IMAGE_STATE_DISABLING};
librados::ObjectWriteOperation op;
librbd::cls_client::mirror_image_set(&op, m_state_builder->local_image_id,
dout(10) << "local_image_id=" << m_state_builder->local_image_id << dendl;
update_progress("ADD_MIRROR_IMAGE");
- cls::rbd::GroupSpec group_spec;
+ cls::rbd::MirrorImageType type = cls::rbd::MIRROR_IMAGE_TYPE_STANDALONE;
if (m_local_group_ctx != nullptr) {
- group_spec = {m_local_group_ctx->group_id,
- m_local_group_ctx->io_ctx.get_id()};
+ type = cls::rbd::MIRROR_IMAGE_TYPE_GROUP;
}
// use 'creating' to track a partially constructed image. it will
// be switched to 'enabled' once the image is fully created
cls::rbd::MirrorImage mirror_image{
- cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, m_global_image_id, group_spec,
+ cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, m_global_image_id, type,
cls::rbd::MIRROR_IMAGE_STATE_CREATING};
librados::ObjectWriteOperation op;
librbd::cls_client::mirror_image_set(&op, m_state_builder->local_image_id,
Replayer<I>, &Replayer<I>::handle_create_non_primary_snapshot>(this);
auto req = librbd::mirror::snapshot::CreateNonPrimaryRequest<I>::create(
local_image_ctx, m_remote_mirror_snap_ns.is_demoted(),
+ m_local_group_id, m_remote_mirror_snap_ns.group_snap_id,
m_state_builder->remote_mirror_uuid, m_remote_snap_id_end,
m_local_mirror_snap_ns.snap_seqs, m_image_state, &m_local_snap_id_end, ctx);
req->send();
dout(15) << "local_snap_id_end=" << m_local_snap_id_end << dendl;
- update_image_snapshot();
-}
-
-template <typename I>
-void Replayer<I>::update_image_snapshot() {
- if (!m_remote_mirror_snap_ns.group_spec.is_valid() &&
- m_remote_mirror_snap_ns.group_snap_id.empty()) {
- std::unique_lock locker{m_lock};
- update_mirror_image_state();
- return;
- }
- dout(10) << dendl;
-
- auto local_image_ctx = m_state_builder->local_image_ctx;
- bool snap_valid = false;
- cls::rbd::SnapshotNamespace snap_namespace;
- std::string snap_name;
- uint64_t snap_id = m_local_snap_id_end;
-
- {
- std::shared_lock image_locker{local_image_ctx->image_lock};
- auto snap_info = local_image_ctx->get_snap_info(snap_id);
- if (snap_info != nullptr) {
- snap_valid = true;
- snap_namespace = snap_info->snap_namespace;
- snap_name = snap_info->name;
- }
- }
-
- if (!snap_valid) {
- derr << "failed to get snap info" << dendl;
- handle_replay_complete(-EINVAL, "invalid local mirror snapshot state");
- return;
- }
- auto mirror_ns = std::get_if<cls::rbd::MirrorSnapshotNamespace>(
- &snap_namespace);
- ceph_assert(mirror_ns != nullptr);
- //mirror_ns->group_spec = {m_local_group_id, spec.pool};
-
- m_local_mirror_snap_ns = *mirror_ns;
- m_local_mirror_snap_ns.group_snap_id = m_remote_mirror_snap_ns.group_snap_id;
-
- // write to disk
- librados::ObjectWriteOperation op;
- librbd::cls_client::snapshot_add(&op, snap_id, snap_name,
- m_local_mirror_snap_ns);
- auto ctx = new C_TrackedOp(
- m_in_flight_op_tracker, new LambdaContext([this, snap_id](int r) {
- handle_update_image_snapshot(r, snap_id);
- }));
- auto aio_comp = create_rados_callback(ctx);
- int r = local_image_ctx->md_ctx.aio_operate(
- local_image_ctx->header_oid, aio_comp, &op);
- ceph_assert(r == 0);
- aio_comp->release();
-}
-
-template <typename I>
-void Replayer<I>::handle_update_image_snapshot(
- int r, uint64_t local_snap_id) {
- dout(10) << "snap id: " << local_snap_id << ", r=" << r << dendl;
-
update_mirror_image_state();
}
void update_non_primary_snapshot(bool complete);
void handle_update_non_primary_snapshot(bool complete, int r);
- void update_image_snapshot();
- void handle_update_image_snapshot(int r, uint64_t local_snap_id);
-
void notify_image_update();
void handle_notify_image_update(int r);