From: Jason Dillaman Date: Wed, 19 Oct 2016 14:55:05 +0000 (-0400) Subject: librbd: restore journal access when force disabling mirroring X-Git-Tag: v11.1.0~462^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=86a0c1e5e3bca7869a7a41b3f031fbed7a866903;p=ceph.git librbd: restore journal access when force disabling mirroring 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 --- diff --git a/src/librbd/mirror/DisableRequest.cc b/src/librbd/mirror/DisableRequest.cc index 49d58fea46ae..d9eb0ad3626b 100644 --- a/src/librbd/mirror/DisableRequest.cc +++ b/src/librbd/mirror/DisableRequest.cc @@ -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::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::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::handle_notify_mirroring_watcher(int *result) { *result = 0; } + send_promote_image(); + return nullptr; +} + +template +void DisableRequest::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; + Context *ctx = util::create_context_callback< + klass, &klass::handle_promote_image>(this); + auto req = journal::PromoteRequest::create(m_image_ctx, true, ctx); + req->send(); +} + +template +Context *DisableRequest::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; } diff --git a/src/librbd/mirror/DisableRequest.h b/src/librbd/mirror/DisableRequest.h index 0b1ed126092b..f794ab1d922d 100644 --- a/src/librbd/mirror/DisableRequest.h +++ b/src/librbd/mirror/DisableRequest.h @@ -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::*handle)( int*, const std::string &client_id), const std::string &client_id); + }; } // namespace mirror