From 3cbe0cedcd3057066cee88e98ccf8a19dbdf52d2 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 16 May 2018 16:14:36 -0400 Subject: [PATCH] cls/rbd: fixed last read key for interrupted mirror_image_map_list Previously, the image map would only return a maximum of 64 mappings. Signed-off-by: Jason Dillaman --- src/cls/rbd/cls_rbd.cc | 5 +-- src/cls/rbd/cls_rbd_client.cc | 17 +++++++++ src/cls/rbd/cls_rbd_client.h | 3 ++ src/test/cls_rbd/test_cls_rbd.cc | 61 ++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/cls/rbd/cls_rbd.cc b/src/cls/rbd/cls_rbd.cc index e163f11432c3b..9d8f64bc3162f 100644 --- a/src/cls/rbd/cls_rbd.cc +++ b/src/cls/rbd/cls_rbd.cc @@ -4253,7 +4253,8 @@ int mirror_image_map_list(cls_method_context_t hctx, try { decode(mirror_image_map, iter); } catch (const buffer::error &err) { - CLS_ERR("could not decode image map payload: %s", cpp_strerror(r).c_str()); + CLS_ERR("could not decode image map payload: %s", + cpp_strerror(r).c_str()); return -EINVAL; } @@ -4261,7 +4262,7 @@ int mirror_image_map_list(cls_method_context_t hctx, } if (!vals.empty()) { - last_read = mirror_image_map_key(vals.rbegin()->first); + last_read = vals.rbegin()->first; } } diff --git a/src/cls/rbd/cls_rbd_client.cc b/src/cls/rbd/cls_rbd_client.cc index 2a702471626ee..e8b83b92f033f 100644 --- a/src/cls/rbd/cls_rbd_client.cc +++ b/src/cls/rbd/cls_rbd_client.cc @@ -2107,6 +2107,23 @@ namespace librbd { return 0; } + int mirror_image_map_list( + librados::IoCtx *ioctx, const std::string &start_after, + uint64_t max_read, + std::map *image_mapping) { + librados::ObjectReadOperation op; + mirror_image_map_list_start(&op, start_after, max_read); + + bufferlist out_bl; + int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl); + if (r < 0) { + return r; + } + + bufferlist::iterator iter = out_bl.begin(); + return mirror_image_map_list_finish(&iter, image_mapping); + } + void mirror_image_map_update(librados::ObjectWriteOperation *op, const std::string &global_image_id, const cls::rbd::MirrorImageMap &image_map) { diff --git a/src/cls/rbd/cls_rbd_client.h b/src/cls/rbd/cls_rbd_client.h index c842189bd4715..e483e5a4327a9 100644 --- a/src/cls/rbd/cls_rbd_client.h +++ b/src/cls/rbd/cls_rbd_client.h @@ -438,6 +438,9 @@ namespace librbd { uint64_t max_read); int mirror_image_map_list_finish(bufferlist::iterator *iter, std::map *image_mapping); + int mirror_image_map_list(librados::IoCtx *ioctx, + const std::string &start_after, uint64_t max_read, + std::map *image_mapping); void mirror_image_map_update(librados::ObjectWriteOperation *op, const std::string &global_image_id, const cls::rbd::MirrorImageMap &image_map); diff --git a/src/test/cls_rbd/test_cls_rbd.cc b/src/test/cls_rbd/test_cls_rbd.cc index 201053b8133cb..da59138f633cf 100644 --- a/src/test/cls_rbd/test_cls_rbd.cc +++ b/src/test/cls_rbd/test_cls_rbd.cc @@ -1877,6 +1877,67 @@ TEST_F(TestClsRbd, mirror_image_status) { ASSERT_EQ(0U, statuses.size()); } +TEST_F(TestClsRbd, mirror_image_map) +{ + librados::IoCtx ioctx; + ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx)); + ioctx.remove(RBD_MIRRORING); + + std::map image_mapping; + ASSERT_EQ(-ENOENT, mirror_image_map_list(&ioctx, "", 0, &image_mapping)); + + utime_t expected_time = ceph_clock_now(); + + bufferlist expected_data; + expected_data.append("test"); + + std::map expected_image_mapping; + while (expected_image_mapping.size() < 1024) { + librados::ObjectWriteOperation op; + for (uint32_t i = 0; i < 32; ++i) { + std::string global_image_id{stringify(expected_image_mapping.size())}; + cls::rbd::MirrorImageMap mirror_image_map{ + stringify(i), expected_time, expected_data}; + expected_image_mapping.emplace(global_image_id, mirror_image_map); + + mirror_image_map_update(&op, global_image_id, mirror_image_map); + } + ASSERT_EQ(0, ioctx.operate(RBD_MIRRORING, &op)); + } + + ASSERT_EQ(0, mirror_image_map_list(&ioctx, "", 1000, &image_mapping)); + ASSERT_EQ(1000U, image_mapping.size()); + + ASSERT_EQ(0, mirror_image_map_list(&ioctx, image_mapping.rbegin()->first, + 1000, &image_mapping)); + ASSERT_EQ(24U, image_mapping.size()); + + const auto& image_map = *image_mapping.begin(); + ASSERT_EQ("978", image_map.first); + + cls::rbd::MirrorImageMap expected_mirror_image_map{ + stringify(18), expected_time, expected_data}; + ASSERT_EQ(expected_mirror_image_map, image_map.second); + + expected_time = ceph_clock_now(); + expected_mirror_image_map.mapped_time = expected_time; + + expected_data.append("update"); + expected_mirror_image_map.data = expected_data; + + librados::ObjectWriteOperation op; + mirror_image_map_remove(&op, "1"); + mirror_image_map_update(&op, "10", expected_mirror_image_map); + ASSERT_EQ(0, ioctx.operate(RBD_MIRRORING, &op)); + + ASSERT_EQ(0, mirror_image_map_list(&ioctx, "0", 1, &image_mapping)); + ASSERT_EQ(1U, image_mapping.size()); + + const auto& updated_image_map = *image_mapping.begin(); + ASSERT_EQ("10", updated_image_map.first); + ASSERT_EQ(expected_mirror_image_map, updated_image_map.second); +} + TEST_F(TestClsRbd, mirror_instances) { librados::IoCtx ioctx; ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx)); -- 2.39.5