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 <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2016-10-19 10:55:05 -04:00
parent 3bc9f51c58
commit 86a0c1e5e3
2 changed files with 44 additions and 1 deletions

View 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;
}

View 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