]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: mirror enable state machine might need to open image
authorJason Dillaman <dillaman@redhat.com>
Mon, 20 Apr 2020 22:16:40 +0000 (18:16 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 23 Apr 2020 17:19:48 +0000 (13:19 -0400)
If attempting to create a snapshot-based mirroring primary snapshot,
the image needs to first be opened. If we weren't supplied an image,
open the image, create the snapshot, and close the image again.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/mirror/EnableRequest.cc
src/librbd/mirror/EnableRequest.h

index c2cbbbd322c7facfc1f5b453437bac3fe26de450..cb61631f4860056546082b4847128a719e02bba1 100644 (file)
@@ -106,7 +106,7 @@ void EnableRequest<I>::handle_get_mirror_image(int r) {
 template <typename I>
 void EnableRequest<I>::get_tag_owner() {
   if (m_mirror_image.mode == cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT) {
-    create_primary_snapshot();
+    open_image();
     return;
   } else if (!m_non_primary_global_image_id.empty()) {
     image_state_update();
@@ -143,13 +143,43 @@ void EnableRequest<I>::handle_get_tag_owner(int r) {
 }
 
 template <typename I>
-void EnableRequest<I>::create_primary_snapshot() {
+void EnableRequest<I>::open_image() {
   if (!m_non_primary_global_image_id.empty()) {
     // special case for rbd-mirror creating a non-primary image
     enable_non_primary_feature();
     return;
+  } else if (m_image_ctx != nullptr) {
+    create_primary_snapshot();
+    return;
+  }
+
+  ldout(m_cct, 10) << dendl;
+
+  m_close_image = true;
+  m_image_ctx = I::create("", m_image_id, CEPH_NOSNAP, m_io_ctx, false);
+
+  auto ctx = create_context_callback<
+    EnableRequest<I>, &EnableRequest<I>::handle_open_image>(this);
+  m_image_ctx->state->open(OPEN_FLAG_SKIP_OPEN_PARENT, ctx);
+}
+
+template <typename I>
+void EnableRequest<I>::handle_open_image(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(m_cct) << "failed to open image: " << cpp_strerror(r) << dendl;
+    m_image_ctx->destroy();
+    m_image_ctx = nullptr;
+    finish(r);
+    return;
   }
 
+  create_primary_snapshot();
+}
+
+template <typename I>
+void EnableRequest<I>::create_primary_snapshot() {
   ldout(m_cct, 10) << dendl;
 
   ceph_assert(m_image_ctx != nullptr);
@@ -169,13 +199,53 @@ void EnableRequest<I>::handle_create_primary_snapshot(int r) {
   if (r < 0) {
     lderr(m_cct) << "failed to create initial primary snapshot: "
                  << cpp_strerror(r) << dendl;
-    finish(r);
+    m_ret_val = r;
+  }
+
+  close_image();
+}
+
+template <typename I>
+void EnableRequest<I>::close_image() {
+  if (!m_close_image) {
+    if (m_ret_val < 0) {
+      finish(m_ret_val);
+    } else {
+      image_state_update();
+    }
+    return;
+  }
+
+  ldout(m_cct, 10) << dendl;
+
+  auto ctx = create_context_callback<
+    EnableRequest<I>, &EnableRequest<I>::handle_close_image>(this);
+  m_image_ctx->state->close(ctx);
+}
+
+template <typename I>
+void EnableRequest<I>::handle_close_image(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  m_image_ctx->destroy();
+  m_image_ctx = nullptr;
+
+  if (r < 0) {
+    lderr(m_cct) << "failed to close image: " << cpp_strerror(r) << dendl;
+    if (m_ret_val == 0) {
+      m_ret_val = r;
+    }
+  }
+
+  if (m_ret_val < 0) {
+    finish(m_ret_val);
     return;
   }
 
   image_state_update();
 }
 
+
 template <typename I>
 void EnableRequest<I>::enable_non_primary_feature() {
   if (m_mirror_image.mode != cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT) {
index c9945d7b56c7dcd90dc1cae787df8e29d72446be..12ab0f035af7b50c7339e53f936d00359a2db1df 100644 (file)
@@ -53,8 +53,14 @@ private:
    * GET_TAG_OWNER  * * * * * * * *
    *    |                         *
    *    v (skip if not needed)    *
+   * OPEN_IMAGE                   *
+   *    |                         *
+   *    v (skip if not needed)    *
    * CREATE_PRIMARY_SNAPSHOT  * * *
    *    |                         *
+   *    v (skip of not opened)    *
+   * CLOSE_IMAGE                  *
+   *    |                         *
    *    v (skip if not needed)    *
    * ENABLE_NON_PRIMARY_FEATURE   *
    *    |                         *
@@ -84,6 +90,9 @@ private:
   bufferlist m_out_bl;
   cls::rbd::MirrorImage m_mirror_image;
 
+  int m_ret_val = 0;
+  bool m_close_image = false;
+
   bool m_is_primary = false;
   uint64_t m_snap_id = CEPH_NOSNAP;
 
@@ -93,9 +102,15 @@ private:
   void get_tag_owner();
   void handle_get_tag_owner(int r);
 
+  void open_image();
+  void handle_open_image(int r);
+
   void create_primary_snapshot();
   void handle_create_primary_snapshot(int r);
 
+  void close_image();
+  void handle_close_image(int r);
+
   void enable_non_primary_feature();
   void handle_enable_non_primary_feature(int r);