cls/rbd: fixed last read key for interrupted mirror_image_map_list 22105/head
authorJason Dillaman <dillaman@redhat.com>
Wed, 16 May 2018 20:14:36 +0000 (16:14 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sat, 19 May 2018 12:18:03 +0000 (08:18 -0400)
Previously, the image map would only return a maximum of 64 mappings.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 3cbe0cedcd3057066cee88e98ccf8a19dbdf52d2)

src/cls/rbd/cls_rbd.cc
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/test/cls_rbd/test_cls_rbd.cc

index e163f11432c3b311ee1e6aa37105b53362dd073c..9d8f64bc3162fdfc7210960b248187697ff8ff5c 100644 (file)
@@ -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;
     }
   }
 
index 2a702471626eeb580416762f9d28d155f575c721..e8b83b92f033fdd6d87df90684eb90b910281ade 100644 (file)
@@ -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<std::string, cls::rbd::MirrorImageMap> *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) {
index c842189bd471583db0815bba8f2fd38e9cb96600..e483e5a4327a9cf8b46ea066fe6a151005901c5a 100644 (file)
@@ -438,6 +438,9 @@ namespace librbd {
                                      uint64_t max_read);
     int mirror_image_map_list_finish(bufferlist::iterator *iter,
                                      std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping);
+    int mirror_image_map_list(librados::IoCtx *ioctx,
+                              const std::string &start_after, uint64_t max_read,
+                              std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping);
     void mirror_image_map_update(librados::ObjectWriteOperation *op,
                                  const std::string &global_image_id,
                                  const cls::rbd::MirrorImageMap &image_map);
index 8558c97f88c8b77977f4a019f984c8cdbfb502ac..735c3d26d8c7170c1452b7095cdffc5f4b92e5b3 100644 (file)
@@ -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<std::string, cls::rbd::MirrorImageMap> 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<std::string, cls::rbd::MirrorImageMap> 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));