MockImageCopyRequest mock_image_copy_request;
expect_image_copy(mock_image_copy_request, 0, 1, 0, {},
{{1, CEPH_NOSNAP}}, 0);
- MockUnlinkPeerRequest mock_unlink_peer_request;
- expect_unlink_peer(mock_unlink_peer_request, 1, "remote mirror peer uuid",
- 0);
expect_mirror_image_snapshot_set_copy_progress(
mock_local_image_ctx, 11, true, 0, 0);
expect_notify_update(mock_local_image_ctx);
{{1, 11}, {4, CEPH_NOSNAP}}, 14, 0);
expect_image_copy(mock_image_copy_request, 1, 4, 11, {},
{{1, 11}, {4, CEPH_NOSNAP}}, 0);
- expect_unlink_peer(mock_unlink_peer_request, 4, "remote mirror peer uuid",
- 0);
+ MockUnlinkPeerRequest mock_unlink_peer_request;
expect_mirror_image_snapshot_set_copy_progress(
mock_local_image_ctx, 14, true, 0, 0);
expect_notify_update(mock_local_image_ctx);
+ expect_unlink_peer(mock_unlink_peer_request, 1, "remote mirror peer uuid",
+ 0);
// idle
expect_is_refresh_required(mock_local_image_ctx, true);
expect_image_copy(mock_image_copy_request, 0, 1, 0,
librbd::deep_copy::ObjectNumber{123U},
{{1, CEPH_NOSNAP}}, 0);
- MockUnlinkPeerRequest mock_unlink_peer_request;
- expect_unlink_peer(mock_unlink_peer_request, 1, "remote mirror peer uuid",
- 0);
expect_mirror_image_snapshot_set_copy_progress(
mock_local_image_ctx, 11, true, 123, 0);
expect_notify_update(mock_local_image_ctx);
MockImageCopyRequest mock_image_copy_request;
expect_image_copy(mock_image_copy_request, 0, 1, 0, {},
{{1, CEPH_NOSNAP}}, 0);
- MockUnlinkPeerRequest mock_unlink_peer_request;
- expect_unlink_peer(mock_unlink_peer_request, 1, "remote mirror peer uuid",
- 0);
expect_mirror_image_snapshot_set_copy_progress(
mock_local_image_ctx, 11, true, 0, 0);
expect_notify_update(mock_local_image_ctx);
mock_remote_image_ctx));
}
-TEST_F(TestMockImageReplayerSnapshotReplayer, UnlinkPeerError) {
+TEST_F(TestMockImageReplayerSnapshotReplayer, UpdateNonPrimarySnapshotError) {
librbd::MockTestImageCtx mock_local_image_ctx{*m_local_image_ctx};
librbd::MockTestImageCtx mock_remote_image_ctx{*m_remote_image_ctx};
MockImageCopyRequest mock_image_copy_request;
expect_image_copy(mock_image_copy_request, 0, 1, 0, {},
{{1, CEPH_NOSNAP}}, 0);
- MockUnlinkPeerRequest mock_unlink_peer_request;
- expect_unlink_peer(mock_unlink_peer_request, 1, "remote mirror peer uuid",
- 0);
expect_mirror_image_snapshot_set_copy_progress(
mock_local_image_ctx, 11, true, 0, -EINVAL);
mock_remote_image_ctx));
}
-TEST_F(TestMockImageReplayerSnapshotReplayer, UpdateNonPrimarySnapshotError) {
+TEST_F(TestMockImageReplayerSnapshotReplayer, UnlinkPeerError) {
librbd::MockTestImageCtx mock_local_image_ctx{*m_local_image_ctx};
librbd::MockTestImageCtx mock_remote_image_ctx{*m_remote_image_ctx};
{1U, librbd::SnapInfo{"snap1", cls::rbd::MirrorSnapshotNamespace{
cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"remote mirror peer uuid"}, "",
0U},
+ 0, {}, 0, 0, {}}},
+ {2U, librbd::SnapInfo{"snap2", cls::rbd::MirrorSnapshotNamespace{
+ cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"remote mirror peer uuid"},
+ "", 0U},
+ 0, {}, 0, 0, {}}}};
+ mock_local_image_ctx.snap_info = {
+ {11U, librbd::SnapInfo{"snap1", cls::rbd::MirrorSnapshotNamespace{
+ cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY, {}, "remote mirror uuid",
+ 1, true, 0, {}},
0, {}, 0, 0, {}}}};
- // sync snap1
+ // sync snap2
expect_is_refresh_required(mock_local_image_ctx, false);
expect_is_refresh_required(mock_remote_image_ctx, false);
MockSnapshotCopyRequest mock_snapshot_copy_request;
- expect_snapshot_copy(mock_snapshot_copy_request, 0, 1, 0, {{1, CEPH_NOSNAP}},
+ expect_snapshot_copy(mock_snapshot_copy_request, 1, 2, 11, {{2, CEPH_NOSNAP}},
0);
MockGetImageStateRequest mock_get_image_state_request;
- expect_get_image_state(mock_get_image_state_request, 1, 0);
+ expect_get_image_state(mock_get_image_state_request, 2, 0);
MockCreateNonPrimaryRequest mock_create_non_primary_request;
expect_create_non_primary_request(mock_create_non_primary_request,
- false, "remote mirror uuid", 1,
- {{1, CEPH_NOSNAP}}, 11, 0);
+ false, "remote mirror uuid", 2,
+ {{2, CEPH_NOSNAP}}, 12, 0);
MockImageCopyRequest mock_image_copy_request;
- expect_image_copy(mock_image_copy_request, 0, 1, 0, {},
- {{1, CEPH_NOSNAP}}, 0);
+ expect_image_copy(mock_image_copy_request, 1, 2, 11, {},
+ {{2, CEPH_NOSNAP}}, 0);
+ expect_mirror_image_snapshot_set_copy_progress(
+ mock_local_image_ctx, 12, true, 0, 0);
+ expect_notify_update(mock_local_image_ctx);
MockUnlinkPeerRequest mock_unlink_peer_request;
expect_unlink_peer(mock_unlink_peer_request, 1, "remote mirror peer uuid",
- 0);
- expect_mirror_image_snapshot_set_copy_progress(
- mock_local_image_ctx, 11, true, 0, -EINVAL);
+ -EINVAL);
// wake-up replayer
update_watch_ctx->handle_notify();
return;
}
- unlink_peer();
+ update_non_primary_snapshot(true);
}
template <typename I>
// TODO
}
-template <typename I>
-void Replayer<I>::unlink_peer() {
- dout(10) << dendl;
-
- auto ctx = create_context_callback<
- Replayer<I>, &Replayer<I>::handle_unlink_peer>(this);
- auto req = librbd::mirror::snapshot::UnlinkPeerRequest<I>::create(
- m_state_builder->remote_image_ctx, m_remote_snap_id_end,
- m_remote_mirror_peer_uuid, ctx);
- req->send();
-}
-
-template <typename I>
-void Replayer<I>::handle_unlink_peer(int r) {
- dout(10) << "r=" << r << dendl;
-
- if (r < 0 && r != -ENOENT) {
- derr << "failed to unlink local peer from remote image: " << cpp_strerror(r)
- << dendl;
- handle_replay_complete(r, "failed to unlink local peer from remote image");
- return;
- }
-
- update_non_primary_snapshot(true);
-}
-
template <typename I>
void Replayer<I>::update_non_primary_snapshot(bool complete) {
dout(10) << dendl;
return;
}
- {
- std::unique_lock locker{m_lock};
- notify_status_updated();
- }
-
notify_image_update();
}
return;
}
+ unlink_peer();
+}
+
+template <typename I>
+void Replayer<I>::unlink_peer() {
+ if (m_remote_snap_id_start == 0) {
+ {
+ std::unique_lock locker{m_lock};
+ notify_status_updated();
+ }
+
+ refresh_local_image();
+ return;
+ }
+
+ // local snapshot fully synced -- we no longer depend on the sync
+ // start snapshot in the remote image
+ dout(10) << "remote_snap_id=" << m_remote_snap_id_start << dendl;
+
+ auto ctx = create_context_callback<
+ Replayer<I>, &Replayer<I>::handle_unlink_peer>(this);
+ auto req = librbd::mirror::snapshot::UnlinkPeerRequest<I>::create(
+ m_state_builder->remote_image_ctx, m_remote_snap_id_start,
+ m_remote_mirror_peer_uuid, ctx);
+ req->send();
+}
+
+template <typename I>
+void Replayer<I>::handle_unlink_peer(int r) {
+ dout(10) << "r=" << r << dendl;
+
+ if (r < 0 && r != -ENOENT) {
+ derr << "failed to unlink local peer from remote image: " << cpp_strerror(r)
+ << dendl;
+ handle_replay_complete(r, "failed to unlink local peer from remote image");
+ return;
+ }
+
+ {
+ std::unique_lock locker{m_lock};
+ notify_status_updated();
+ }
+
refresh_local_image();
}
m_threads->work_queue->queue(ctx, r);
}
-
template <typename I>
void Replayer<I>::handle_register_update_watcher(int r) {
dout(10) << "r=" << r << dendl;