]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: restore journal access when force disabling mirroring
authorJason Dillaman <dillaman@redhat.com>
Wed, 19 Oct 2016 14:55:05 +0000 (10:55 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 31 Oct 2016 14:57:14 +0000 (10:57 -0400)
If mirroring is force disabled on a demoted image, the journal was
being left in an inconsistent ownership state.

Fixes: http://tracker.ceph.com/issues/17588
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/mirror/DisableRequest.cc
src/librbd/mirror/DisableRequest.h

index 49d58fea46ae83cf4f4e86fe17f81bdda5a3011b..d9eb0ad3626b17a437535989ce9bb4d3b3447f15 100644 (file)
@@ -13,6 +13,7 @@
 #include "librbd/MirroringWatcher.h"
 #include "librbd/Operations.h"
 #include "librbd/Utils.h"
+#include "librbd/journal/PromoteRequest.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -111,7 +112,6 @@ Context *DisableRequest<I>::handle_get_tag_owner(int *result) {
     return m_on_finish;
   }
 
-  m_mirror_image.state = cls::rbd::MIRROR_IMAGE_STATE_DISABLING;
   send_set_mirror_image();
   return nullptr;
 }
@@ -121,6 +121,8 @@ void DisableRequest<I>::send_set_mirror_image() {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << dendl;
 
+  m_mirror_image.state = cls::rbd::MIRROR_IMAGE_STATE_DISABLING;
+
   librados::ObjectWriteOperation op;
   cls_client::mirror_image_set(&op, m_image_ctx->id, m_mirror_image);
 
@@ -174,6 +176,40 @@ Context *DisableRequest<I>::handle_notify_mirroring_watcher(int *result) {
     *result = 0;
   }
 
+  send_promote_image();
+  return nullptr;
+}
+
+template <typename I>
+void DisableRequest<I>::send_promote_image() {
+  if (m_is_primary) {
+    send_get_clients();
+    return;
+  }
+
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << dendl;
+
+  // Not primary -- shouldn't have the journal open
+  assert(m_image_ctx->journal == nullptr);
+
+  using klass = DisableRequest<I>;
+  Context *ctx = util::create_context_callback<
+    klass, &klass::handle_promote_image>(this);
+  auto req = journal::PromoteRequest<I>::create(m_image_ctx, true, ctx);
+  req->send();
+}
+
+template <typename I>
+Context *DisableRequest<I>::handle_promote_image(int *result) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl;
+
+  if (*result < 0) {
+    lderr(cct) << "failed to promote image: " << cpp_strerror(*result) << dendl;
+    return m_on_finish;
+  }
+
   send_get_clients();
   return nullptr;
 }
index 0b1ed126092b591ef7f65b9a665526d5bab8ec0e..f794ab1d922dac4bdf80dc3a19d2978bb33d0b1b 100644 (file)
@@ -48,6 +48,9 @@ private:
    * NOTIFY_MIRRORING_WATCHER                                     *
    *    |                                                         *
    *    v                                                         *
+   * PROMOTE_IMAGE (skip if primary)                              *
+   *    |                                                         *
+   *    v                                                         *
    * GET_CLIENTS <----------------------------------------\ * * * *
    *    |     | (unregister clients)                      |       *  (on error)
    *    |     |/----------------------------\             |       *
@@ -103,6 +106,9 @@ private:
   void send_notify_mirroring_watcher();
   Context *handle_notify_mirroring_watcher(int *result);
 
+  void send_promote_image();
+  Context *handle_promote_image(int *result);
+
   void send_get_clients();
   Context *handle_get_clients(int *result);
 
@@ -123,6 +129,7 @@ private:
     Context*(DisableRequest<ImageCtxT>::*handle)(
       int*, const std::string &client_id),
     const std::string &client_id);
+
 };
 
 } // namespace mirror