rbd-mirror: do not attempt to unlink from more recent snapshots

The snapshot-based mirroring replayer should only attempt to unlink
from any snapshots that are older than the end remote snapshot id to
prevent the remote side from incorrectly deleted the snapshot.

Fixes: https://tracker.ceph.com/issues/48527
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2020-12-09 23:17:24 -05:00
parent 18a4550301
commit 78f8abce2d
2 changed files with 22 additions and 2 deletions

View File

@ -783,7 +783,24 @@ TEST_F(TestMockImageReplayerSnapshotReplayer, SyncSnapshot) {
1, true, 0, {{1, CEPH_NOSNAP}}},
0, {}, 0, 0, {}}},
}, 0);
expect_is_refresh_required(mock_remote_image_ctx, false);
expect_is_refresh_required(mock_remote_image_ctx, true);
expect_refresh(
mock_remote_image_ctx, {
{2U, librbd::SnapInfo{"snap2", cls::rbd::UserSnapshotNamespace{},
0, {}, 0, 0, {}}},
{3U, librbd::SnapInfo{"snap3", cls::rbd::MirrorSnapshotNamespace{
cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {""},
"", CEPH_NOSNAP, true, 0, {}},
0, {}, 0, 0, {}}},
{4U, librbd::SnapInfo{"snap4", cls::rbd::MirrorSnapshotNamespace{
cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"remote mirror peer uuid"},
"", CEPH_NOSNAP, true, 0, {}},
0, {}, 0, 0, {}}},
{5U, librbd::SnapInfo{"snap5", cls::rbd::MirrorSnapshotNamespace{
cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"remote mirror peer uuid"},
"", CEPH_NOSNAP, true, 0, {}},
0, {}, 0, 0, {}}}
}, 0);
expect_snapshot_copy(mock_snapshot_copy_request, 1, 4, 11,
{{1, 11}, {2, 12}, {4, CEPH_NOSNAP}}, 0);
expect_get_image_state(mock_get_image_state_request, 4, 0);

View File

@ -552,7 +552,10 @@ void Replayer<I>::scan_remote_mirror_snapshots(
ceph_assert(m_local_mirror_snap_ns.primary_mirror_uuid ==
m_state_builder->remote_mirror_uuid);
unlink_snap_ids.insert(remote_snap_id);
if (m_remote_snap_id_end == CEPH_NOSNAP) {
// haven't found the end snap so treat this as a candidate for unlink
unlink_snap_ids.insert(remote_snap_id);
}
if (m_local_mirror_snap_ns.complete &&
m_local_mirror_snap_ns.primary_snap_id >= remote_snap_id) {
// skip past completed remote snapshot