]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: API for mirror snapshot create to pass flags
authorMykola Golub <mgolub@suse.com>
Fri, 5 Jun 2020 09:02:57 +0000 (10:02 +0100)
committerMykola Golub <mgolub@suse.com>
Tue, 9 Jun 2020 07:33:52 +0000 (08:33 +0100)
Signed-off-by: Mykola Golub <mgolub@suse.com>
16 files changed:
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/Utils.cc
src/librbd/Utils.h
src/librbd/api/Mirror.cc
src/librbd/api/Mirror.h
src/librbd/api/Snapshot.cc
src/librbd/librbd.cc
src/librbd/mirror/EnableRequest.cc
src/librbd/mirror/snapshot/CreatePrimaryRequest.cc
src/librbd/mirror/snapshot/CreatePrimaryRequest.h
src/librbd/mirror/snapshot/DemoteRequest.cc
src/librbd/mirror/snapshot/PromoteRequest.cc
src/test/librbd/mirror/snapshot/test_mock_CreatePrimaryRequest.cc
src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc
src/test/rbd_mirror/test_ImageReplayer.cc

index 06c9b252f628b41acd0591bf75585757d2ed4715..50e2e990262cbb62de313f7205e9711b33927140 100644 (file)
@@ -1204,6 +1204,9 @@ CEPH_RBD_API int rbd_mirror_image_demote(rbd_image_t image);
 CEPH_RBD_API int rbd_mirror_image_resync(rbd_image_t image);
 CEPH_RBD_API int rbd_mirror_image_create_snapshot(rbd_image_t image,
                                                   uint64_t *snap_id);
+CEPH_RBD_API int rbd_mirror_image_create_snapshot2(rbd_image_t image,
+                                                   uint32_t flags,
+                                                   uint64_t *snap_id);
 CEPH_RBD_API int rbd_mirror_image_get_info(rbd_image_t image,
                                            rbd_mirror_image_info_t *mirror_image_info,
                                            size_t info_size);
index 6066bd33827af2a7644df28b201569d445853e0d..987a76eb9da8f0f3d67859c35b88a4a20834b683 100644 (file)
@@ -752,6 +752,7 @@ public:
   int mirror_image_demote();
   int mirror_image_resync();
   int mirror_image_create_snapshot(uint64_t *snap_id);
+  int mirror_image_create_snapshot2(uint32_t flags, uint64_t *snap_id);
   int mirror_image_get_info(mirror_image_info_t *mirror_image_info,
                             size_t info_size);
   int mirror_image_get_mode(mirror_image_mode_t *mode);
index c9d7b0413ab776516123e2975604ac4cec125ba1..4d3bde47acec6ce91f50cafaa4f82b14659cd803 100644 (file)
@@ -11,6 +11,8 @@
 #include "common/dout.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Features.h"
+
+#include <bitset>
 #include <random>
 
 #define dout_subsys ceph_subsys_rbd
@@ -141,5 +143,26 @@ int create_ioctx(librados::IoCtx& src_io_ctx, const std::string& pool_desc,
   return 0;
 }
 
+int snap_create_flags_api_to_internal(CephContext *cct, uint32_t api_flags,
+                                      uint64_t *internal_flags) {
+  *internal_flags = 0;
+
+  if (api_flags & RBD_SNAP_CREATE_SKIP_QUIESCE) {
+    *internal_flags |= SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE;
+    api_flags &= ~RBD_SNAP_CREATE_SKIP_QUIESCE;
+  } else if (api_flags & RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR) {
+    *internal_flags |= SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR;
+    api_flags &= ~RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR;
+  }
+
+  if (api_flags != 0) {
+    lderr(cct) << "invalid snap create flags: "
+                     << std::bitset<32>(api_flags) << dendl;
+    return -EINVAL;
+  }
+
+  return 0;
+}
+
 } // namespace util
 } // namespace librbd
index c63504ac1a7d4c1be2a9820b26ee4784258d45d3..9e95e692f70511a24510719a50a01f6ba58dc783 100644 (file)
@@ -260,6 +260,9 @@ int create_ioctx(librados::IoCtx& src_io_ctx, const std::string& pool_desc,
                  const std::optional<std::string>& pool_namespace,
                  librados::IoCtx* dst_io_ctx);
 
+int snap_create_flags_api_to_internal(CephContext *cct, uint32_t api_flags,
+                                      uint64_t *internal_flags);
+
 } // namespace util
 } // namespace librbd
 
index 2855ae329889595fbd3d5ee7dfb1b44086e5b4d4..b95bae8cc061806356613c3ec25281594380cba2 100644 (file)
@@ -1970,11 +1970,19 @@ int Mirror<I>::image_info_list(
 }
 
 template <typename I>
-int Mirror<I>::image_snapshot_create(I *ictx, uint64_t *snap_id) {
+int Mirror<I>::image_snapshot_create(I *ictx, uint32_t flags,
+                                     uint64_t *snap_id) {
   CephContext *cct = ictx->cct;
   ldout(cct, 20) << "ictx=" << ictx << dendl;
 
-  int r = ictx->state->refresh_if_required();
+  uint64_t snap_create_flags = 0;
+  int r = util::snap_create_flags_api_to_internal(cct, flags,
+                                                  &snap_create_flags);
+  if (r < 0) {
+    return r;
+  }
+
+  r = ictx->state->refresh_if_required();
   if (r < 0) {
     return r;
   }
@@ -1997,7 +2005,8 @@ int Mirror<I>::image_snapshot_create(I *ictx, uint64_t *snap_id) {
 
   C_SaferCond on_finish;
   auto req = mirror::snapshot::CreatePrimaryRequest<I>::create(
-    ictx, mirror_image.global_image_id, CEPH_NOSNAP, 0U, snap_id, &on_finish);
+    ictx, mirror_image.global_image_id, CEPH_NOSNAP, snap_create_flags, 0U,
+    snap_id, &on_finish);
   req->send();
   return on_finish.wait();
 }
index b0dae99bc4a1e3e6e3ce94ac7d06b58ceb1c2498..194ab818d763671754cacf1551f805b5935bb6c7 100644 (file)
@@ -113,7 +113,8 @@ struct Mirror {
                                       Context *on_finish);
   static int image_get_instance_id(ImageCtxT *ictx, std::string *instance_id);
 
-  static int image_snapshot_create(ImageCtxT *ictx, uint64_t *snap_id);
+  static int image_snapshot_create(ImageCtxT *ictx, uint32_t flags,
+                                   uint64_t *snap_id);
 };
 
 } // namespace api
index 03f30ecba379901cb67cba201e11ba217a3550aa..88f22694cf28d4e85c6beeb14e2e894fef8ea479 100644 (file)
@@ -13,7 +13,6 @@
 #include "include/Context.h"
 #include "common/Cond.h"
 
-#include <bitset>
 #include <boost/variant.hpp>
 
 #define dout_subsys ceph_subsys_rbd
@@ -318,19 +317,10 @@ int Snapshot<I>::create(I *ictx, const char *snap_name, uint32_t flags,
                        << " flags: " << flags << dendl;
 
   uint64_t internal_flags = 0;
-
-  if (flags & RBD_SNAP_CREATE_SKIP_QUIESCE) {
-    internal_flags |= SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE;
-    flags &= ~RBD_SNAP_CREATE_SKIP_QUIESCE;
-  } else if (flags & RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR) {
-    internal_flags |= SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR;
-    flags &= ~RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR;
-  }
-
-  if (flags != 0) {
-    lderr(ictx->cct) << "invalid snap create flags: " << std::bitset<32>(flags)
-                     << dendl;
-    return -EINVAL;
+  int r = util::snap_create_flags_api_to_internal(ictx->cct, flags,
+                                                  &internal_flags);
+  if (r < 0) {
+    return r;
   }
 
   return ictx->operations->snap_create(cls::rbd::UserSnapshotNamespace(),
index d61a9335b90e21c0a6a3396fddf894a4648bb274..8468a26dca92c1777a459031409aa27f87cc11d2 100644 (file)
@@ -2846,7 +2846,13 @@ namespace librbd {
   int Image::mirror_image_create_snapshot(uint64_t *snap_id)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
-    return librbd::api::Mirror<>::image_snapshot_create(ictx, snap_id);
+    return librbd::api::Mirror<>::image_snapshot_create(ictx, 0, snap_id);
+  }
+
+  int Image::mirror_image_create_snapshot2(uint32_t flags, uint64_t *snap_id)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::api::Mirror<>::image_snapshot_create(ictx, flags, snap_id);
   }
 
   int Image::mirror_image_get_info(mirror_image_info_t *mirror_image_info,
@@ -6329,7 +6335,15 @@ extern "C" int rbd_mirror_image_create_snapshot(rbd_image_t image,
                                                 uint64_t *snap_id)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
-  return librbd::api::Mirror<>::image_snapshot_create(ictx, snap_id);
+  return librbd::api::Mirror<>::image_snapshot_create(ictx, 0, snap_id);
+}
+
+extern "C" int rbd_mirror_image_create_snapshot2(rbd_image_t image,
+                                                 uint32_t flags,
+                                                 uint64_t *snap_id)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::api::Mirror<>::image_snapshot_create(ictx, flags, snap_id);
 }
 
 extern "C" int rbd_mirror_image_get_info(rbd_image_t image,
index cd276fdfe852a05e7e355abea9a68594b63736f5..13b69c02328d454722926f221c844087771c45a1 100644 (file)
@@ -192,6 +192,7 @@ void EnableRequest<I>::create_primary_snapshot() {
   auto req = snapshot::CreatePrimaryRequest<I>::create(
     m_image_ctx, m_mirror_image.global_image_id,
     (m_image_clean ? 0 : CEPH_NOSNAP),
+    SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR,
     snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS, &m_snap_id, ctx);
   req->send();
 }
index 0694ecc109034629a633ede2342d1ab0158d6ba7..36961d35e848ef256a0d9bdf13eeb03644136001 100644 (file)
@@ -28,11 +28,12 @@ using librbd::util::create_rados_callback;
 template <typename I>
 CreatePrimaryRequest<I>::CreatePrimaryRequest(
     I *image_ctx, const std::string& global_image_id,
-    uint64_t clean_since_snap_id, uint32_t flags, uint64_t *snap_id,
-    Context *on_finish)
+    uint64_t clean_since_snap_id, uint64_t snap_create_flags, uint32_t flags,
+    uint64_t *snap_id, Context *on_finish)
   : m_image_ctx(image_ctx), m_global_image_id(global_image_id),
-    m_clean_since_snap_id(clean_since_snap_id), m_flags(flags),
-    m_snap_id(snap_id), m_on_finish(on_finish) {
+    m_clean_since_snap_id(clean_since_snap_id),
+    m_snap_create_flags(snap_create_flags), m_flags(flags), m_snap_id(snap_id),
+    m_on_finish(on_finish) {
   m_default_ns_ctx.dup(m_image_ctx->md_ctx);
   m_default_ns_ctx.set_namespace("");
 }
@@ -121,7 +122,8 @@ void CreatePrimaryRequest<I>::create_snapshot() {
   auto ctx = create_context_callback<
     CreatePrimaryRequest<I>,
     &CreatePrimaryRequest<I>::handle_create_snapshot>(this);
-  m_image_ctx->operations->snap_create(ns, m_snap_name, 0, m_prog_ctx, ctx);
+  m_image_ctx->operations->snap_create(ns, m_snap_name, m_snap_create_flags,
+                                       m_prog_ctx, ctx);
 }
 
 template <typename I>
index b7869e5ef000e8cba61fd9ba9c6180ff2cb8b365..b8e84cf2b74b2422b4ba5ed690d2ef6fb4787ec5 100644 (file)
@@ -28,17 +28,18 @@ public:
   static CreatePrimaryRequest *create(ImageCtxT *image_ctx,
                                       const std::string& global_image_id,
                                       uint64_t clean_since_snap_id,
+                                      uint64_t snap_create_flags,
                                       uint32_t flags, uint64_t *snap_id,
                                       Context *on_finish) {
     return new CreatePrimaryRequest(image_ctx, global_image_id,
-                                    clean_since_snap_id, flags, snap_id,
-                                    on_finish);
+                                    clean_since_snap_id, snap_create_flags, flags,
+                                    snap_id, on_finish);
   }
 
   CreatePrimaryRequest(ImageCtxT *image_ctx,
                        const std::string& global_image_id,
-                       uint64_t clean_since_snap_id, uint32_t flags,
-                       uint64_t *snap_id, Context *on_finish);
+                       uint64_t clean_since_snap_id, uint64_t snap_create_flags,
+                       uint32_t flags, uint64_t *snap_id, Context *on_finish);
 
   void send();
 
@@ -69,6 +70,7 @@ private:
   ImageCtxT *m_image_ctx;
   std::string m_global_image_id;
   uint64_t m_clean_since_snap_id;
+  const uint64_t m_snap_create_flags;
   const uint32_t m_flags;
   uint64_t *m_snap_id;
   Context *m_on_finish;
index 17d157d41e17e4ada8709e6b5ef85cf4acb30a71..f9c14ea8a2b363bc8a12fdb5c9729b08227a58af 100644 (file)
@@ -73,6 +73,7 @@ void DemoteRequest<I>::create_snapshot() {
 
   auto req = CreatePrimaryRequest<I>::create(
     m_image_ctx, m_global_image_id, CEPH_NOSNAP,
+    SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE,
     (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
      snapshot::CREATE_PRIMARY_FLAG_DEMOTED), nullptr, ctx);
   req->send();
index f9cf4b5b973dd67d66dcf228bb1df16a978581f2..821860106428326ab68c42573cc7d5129e7ee6da 100644 (file)
@@ -296,6 +296,7 @@ void PromoteRequest<I>::create_promote_snapshot() {
 
   auto req = CreatePrimaryRequest<I>::create(
     m_image_ctx, m_global_image_id, CEPH_NOSNAP,
+    SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE,
     (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
      snapshot::CREATE_PRIMARY_FLAG_FORCE), nullptr, ctx);
   req->send();
index 8006c35956e22a67f7bedd04dcddfb9650e33ea4..3babd19d2328828dac8f73e5e68fc238cb28b4ec 100644 (file)
@@ -213,7 +213,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, Success) {
 
   C_SaferCond ctx;
   auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
-                                          0U, nullptr, &ctx);
+                                          0U, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(0, ctx.wait());
 }
@@ -234,7 +234,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CanNotError) {
 
   C_SaferCond ctx;
   auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
-                                          0U, nullptr, &ctx);
+                                          0U, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -258,7 +258,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, GetMirrorPeersError) {
 
   C_SaferCond ctx;
   auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
-                                          0U, nullptr, &ctx);
+                                          0U, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -283,7 +283,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CreateSnapshotError) {
 
   C_SaferCond ctx;
   auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
-                                          0U, nullptr, &ctx);
+                                          0U, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -318,7 +318,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkPeer) {
                      0);
   C_SaferCond ctx;
   auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
-                                          0U, nullptr, &ctx);
+                                          0U, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(0, ctx.wait());
 }
index 0965ab4644bede272ea9084605a0f58c672ebdd2..af9c349339b4665aa09dc40965ca89efe5799215 100644 (file)
@@ -123,6 +123,7 @@ struct CreatePrimaryRequest<MockTestImageCtx> {
   static CreatePrimaryRequest *create(MockTestImageCtx *image_ctx,
                                       const std::string& global_image_id,
                                       uint64_t clean_since_snap_id,
+                                      uint64_t snap_create_flags,
                                       uint32_t flags, uint64_t *snap_id,
                                       Context *on_finish) {
     ceph_assert(s_instance != nullptr);
index 592044c920b1dd060280684e9773d8c356b045c4..ce94e5a6d140ea790f3541676df2dd9677afd905 100644 (file)
@@ -536,7 +536,7 @@ public:
     } else {
       uint64_t snap_id = CEPH_NOSNAP;
       ASSERT_EQ(0, librbd::api::Mirror<>::image_snapshot_create(
-                     ictx, &snap_id));
+                  ictx, 0, &snap_id));
     }
 
     printf("flushed\n");