]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: optionally ignore missing peers when creating promoted mirror snapshot
authorJason Dillaman <dillaman@redhat.com>
Fri, 31 Jan 2020 02:21:30 +0000 (21:21 -0500)
committerJason Dillaman <dillaman@redhat.com>
Fri, 31 Jan 2020 03:52:31 +0000 (22:52 -0500)
The initial enable steps as well as demote/promote should ignore the lack of
peers. Otherwise, you would never be able to enable snapshot mirroring
without first creating TX peers.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/api/Mirror.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/librbd/mirror/snapshot/Types.h
src/test/librbd/mirror/snapshot/test_mock_CreatePrimaryRequest.cc
src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc

index ae4874cc45a00117c408dd4958928c8822f4f862..81694d843473063e2aae785c7d86693e762d3cbc 100644 (file)
@@ -1818,7 +1818,7 @@ int Mirror<I>::image_snapshot_create(I *ictx, uint64_t *snap_id) {
 
   C_SaferCond on_finish;
   auto req = mirror::snapshot::CreatePrimaryRequest<I>::create(
-    ictx, false, false, snap_id, &on_finish);
+    ictx, 0U, snap_id, &on_finish);
   req->send();
   return on_finish.wait();
 }
index d11df27bc7c938e2cd323b96bd81acc970209297..4ec7967f98b39c302219df07d382d8d93a85a5b4 100644 (file)
@@ -26,10 +26,10 @@ using librbd::util::create_context_callback;
 using librbd::util::create_rados_callback;
 
 template <typename I>
-CreatePrimaryRequest<I>::CreatePrimaryRequest(I *image_ctx, bool demoted,
-                                              bool force, uint64_t *snap_id,
+CreatePrimaryRequest<I>::CreatePrimaryRequest(I *image_ctx, uint32_t flags,
+                                              uint64_t *snap_id,
                                               Context *on_finish)
-  : m_image_ctx(image_ctx), m_demoted(demoted), m_force(force),
+  : m_image_ctx(image_ctx), 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("");
@@ -111,8 +111,10 @@ void CreatePrimaryRequest<I>::handle_get_mirror_image(int r) {
     return;
   }
 
-  if (!util::can_create_primary_snapshot(m_image_ctx, m_demoted, m_force,
-                                         nullptr)) {
+  if (!util::can_create_primary_snapshot(
+        m_image_ctx,
+        ((m_flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0),
+        ((m_flags & CREATE_PRIMARY_FLAG_FORCE) != 0), nullptr)) {
     finish(-EINVAL);
     return;
   }
@@ -166,7 +168,8 @@ void CreatePrimaryRequest<I>::handle_get_mirror_peers(int r) {
     m_mirror_peer_uuids.insert(peer.uuid);
   }
 
-  if (m_mirror_peer_uuids.empty()) {
+  if (m_mirror_peer_uuids.empty() &&
+      ((m_flags & CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS) == 0)) {
     lderr(cct) << "no mirror tx peers configured for the pool" << dendl;
     finish(-EINVAL);
     return;
@@ -180,7 +183,8 @@ void CreatePrimaryRequest<I>::create_snapshot() {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 20) << dendl;
 
-  cls::rbd::MirrorPrimarySnapshotNamespace ns{m_demoted, m_mirror_peer_uuids};
+  cls::rbd::MirrorPrimarySnapshotNamespace ns{
+    ((m_flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0), m_mirror_peer_uuids};
   auto ctx = create_context_callback<
     CreatePrimaryRequest<I>,
     &CreatePrimaryRequest<I>::handle_create_snapshot>(this);
@@ -201,7 +205,8 @@ void CreatePrimaryRequest<I>::handle_create_snapshot(int r) {
 
   if (m_snap_id != nullptr) {
     std::shared_lock image_locker{m_image_ctx->image_lock};
-    cls::rbd::MirrorPrimarySnapshotNamespace ns{m_demoted, m_mirror_peer_uuids};
+    cls::rbd::MirrorPrimarySnapshotNamespace ns{
+      ((m_flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0), m_mirror_peer_uuids};
     *m_snap_id = m_image_ctx->get_snap_id(ns, m_snap_name);
   }
 
index fe7d5f90b26d13a30eb7045f97878f896d278276..022cc95efc3f906c2360215c60ee61d191661bd5 100644 (file)
@@ -7,6 +7,7 @@
 #include "include/buffer.h"
 #include "include/rados/librados.hpp"
 #include "cls/rbd/cls_rbd_types.h"
+#include "librbd/mirror/snapshot/Types.h"
 
 #include <string>
 #include <set>
@@ -23,15 +24,14 @@ namespace snapshot {
 template <typename ImageCtxT = librbd::ImageCtx>
 class CreatePrimaryRequest {
 public:
-  static CreatePrimaryRequest *create(ImageCtxT *image_ctx, bool demoted,
-                                      bool force, uint64_t *snap_id,
+  static CreatePrimaryRequest *create(ImageCtxT *image_ctx, uint32_t flags,
+                                      uint64_t *snap_id,
                                       Context *on_finish) {
-    return new CreatePrimaryRequest(image_ctx, demoted, force, snap_id,
-                                    on_finish);
+    return new CreatePrimaryRequest(image_ctx, flags, snap_id, on_finish);
   }
 
-  CreatePrimaryRequest(ImageCtxT *image_ctx, bool demoted, bool force,
-                       uint64_t *snap_id, Context *on_finish);
+  CreatePrimaryRequest(ImageCtxT *image_ctx, uint32_t flags, uint64_t *snap_id,
+                       Context *on_finish);
 
   void send();
 
@@ -63,8 +63,7 @@ private:
    */
 
   ImageCtxT *m_image_ctx;
-  const bool m_demoted;
-  const bool m_force;
+  const uint32_t m_flags;
   uint64_t *m_snap_id;
   Context *m_on_finish;
 
index 18481b20a49bbb73f4d8e5795fe2022a3d75026f..62fd7f45d747ab56ea950b12a409380e80e38485 100644 (file)
@@ -64,8 +64,10 @@ void DemoteRequest<I>::create_snapshot() {
   auto ctx = create_context_callback<
     DemoteRequest<I>, &DemoteRequest<I>::handle_create_snapshot>(this);
 
-  auto req = CreatePrimaryRequest<I>::create(m_image_ctx, true, false, nullptr,
-                                             ctx);
+  auto req = CreatePrimaryRequest<I>::create(
+    m_image_ctx,
+    (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
+     snapshot::CREATE_PRIMARY_FLAG_DEMOTED), nullptr, ctx);
   req->send();
 }
 
index 683b5f4e50e06a8a1ceca7d6bf50124933876d0c..3fb28cf16ea90da70ef8045e351ab21c7163faad 100644 (file)
@@ -322,8 +322,10 @@ void PromoteRequest<I>::create_promote_snapshot() {
     PromoteRequest<I>,
     &PromoteRequest<I>::handle_create_promote_snapshot>(this);
 
-  auto req = CreatePrimaryRequest<I>::create(m_image_ctx, false, true, nullptr,
-                                             ctx);
+  auto req = CreatePrimaryRequest<I>::create(
+    m_image_ctx,
+    (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
+     snapshot::CREATE_PRIMARY_FLAG_FORCE), nullptr, ctx);
   req->send();
 }
 
index 42f4aeae0ccb687f615f5208df26c76e179e6a91..1c35aea3307abccac222f67785d2335eaa12a116 100644 (file)
@@ -15,6 +15,12 @@ namespace librbd {
 namespace mirror {
 namespace snapshot {
 
+enum CreatePrimaryFlags {
+  CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS = (1 << 0),
+  CREATE_PRIMARY_FLAG_DEMOTED            = (1 << 1),
+  CREATE_PRIMARY_FLAG_FORCE              = (1 << 2)
+};
+
 struct ImageStateHeader {
   uint32_t object_count = 0;
 
index 9d88a97a7561be61c1f40cac1d87fe7dced9514b..6fda820caebd2738edb5719cc4c1c1998145b4a3 100644 (file)
@@ -237,8 +237,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, Success) {
   expect_create_snapshot(mock_image_ctx, 0);
 
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(0, ctx.wait());
 }
@@ -257,8 +256,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, RefreshError) {
   expect_refresh_image(mock_image_ctx, true, -EINVAL);
 
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -280,8 +278,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, GetMirrorImageError) {
                      cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, -EINVAL);
 
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -305,8 +302,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CanNotError) {
   expect_can_create_primary_snapshot(mock_utils, false, false, false);
 
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -333,8 +329,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, GetMirrorPeersError) {
                             "mirror", "fsid"}}, -EINVAL);
 
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -362,8 +357,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CreateSnapshotError) {
   expect_create_snapshot(mock_image_ctx, -EINVAL);
 
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
@@ -400,8 +394,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkPeer) {
   expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid",
                      0);
   C_SaferCond ctx;
-  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false,
-                                          nullptr, &ctx);
+  auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx);
   req->send();
   ASSERT_EQ(0, ctx.wait());
 }
index 4948652d1cdb2e4335311b255dc17c9a08978ace..f0a49971317ccf69b737faa09792f98dd3a2d53b 100644 (file)
@@ -116,12 +116,12 @@ struct CreatePrimaryRequest<MockTestImageCtx> {
   bool force = false;
   Context* on_finish = nullptr;
   static CreatePrimaryRequest* s_instance;
-  static CreatePrimaryRequest *create(MockTestImageCtx *image_ctx, bool demoted,
-                                      bool force, uint64_t *snap_id,
+  static CreatePrimaryRequest *create(MockTestImageCtx *image_ctx,
+                                      uint32_t flags, uint64_t *snap_id,
                                       Context *on_finish) {
     ceph_assert(s_instance != nullptr);
-    s_instance->demoted = demoted;
-    s_instance->force = force;
+    s_instance->demoted = ((flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0);
+    s_instance->force = ((flags & CREATE_PRIMARY_FLAG_FORCE) != 0);
     s_instance->on_finish = on_finish;
     return s_instance;
   }