From 4fa53eac4d08c8787ddf9b51c2481c0d67deb521 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 12 Jan 2016 10:35:05 -0500 Subject: [PATCH] librbd: do not accept RPC requests while transitioning lock state Signed-off-by: Jason Dillaman --- src/librbd/ExclusiveLock.cc | 10 ++++++++++ src/librbd/ExclusiveLock.h | 1 + src/librbd/ImageWatcher.cc | 31 +++++++++++++++---------------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/librbd/ExclusiveLock.cc b/src/librbd/ExclusiveLock.cc index 83d182f500703..92e7ef7136ea0 100644 --- a/src/librbd/ExclusiveLock.cc +++ b/src/librbd/ExclusiveLock.cc @@ -63,6 +63,16 @@ bool ExclusiveLock::is_lock_owner() const { return lock_owner; } +template +bool ExclusiveLock::accept_requests() const { + Mutex::Locker locker(m_lock); + + bool accept_requests = (!is_shutdown() && m_state == STATE_LOCKED); + ldout(m_image_ctx.cct, 20) << this << " " << __func__ << "=" + << accept_requests << dendl; + return accept_requests; +} + template void ExclusiveLock::init(Context *on_init) { assert(m_image_ctx.owner_lock.is_locked()); diff --git a/src/librbd/ExclusiveLock.h b/src/librbd/ExclusiveLock.h index 4434b615a1246..af107c25f7dc8 100644 --- a/src/librbd/ExclusiveLock.h +++ b/src/librbd/ExclusiveLock.h @@ -30,6 +30,7 @@ public: ~ExclusiveLock(); bool is_lock_owner() const; + bool accept_requests() const; void init(Context *on_init); void shut_down(Context *on_shutdown); diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 0f0b22434de8d..ea3dbe0d7b6d0 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -568,7 +568,7 @@ bool ImageWatcher::handle_payload(const RequestLockPayload &payload, RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { // need to send something back so the client can detect a missing leader ::encode(ResponseMessage(0), ack_ctx->out); @@ -621,7 +621,7 @@ bool ImageWatcher::handle_payload(const FlattenPayload &payload, RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { bool new_request; Context *ctx; ProgressContext *prog_ctx; @@ -642,7 +642,7 @@ bool ImageWatcher::handle_payload(const ResizePayload &payload, C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { bool new_request; Context *ctx; ProgressContext *prog_ctx; @@ -664,7 +664,7 @@ bool ImageWatcher::handle_payload(const SnapCreatePayload &payload, C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ldout(m_image_ctx.cct, 10) << this << " remote snap_create request: " << payload.snap_name << dendl; @@ -679,7 +679,7 @@ bool ImageWatcher::handle_payload(const SnapRenamePayload &payload, C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ldout(m_image_ctx.cct, 10) << this << " remote snap_rename request: " << payload.snap_id << " to " << payload.snap_name << dendl; @@ -695,7 +695,7 @@ bool ImageWatcher::handle_payload(const SnapRemovePayload &payload, C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ldout(m_image_ctx.cct, 10) << this << " remote snap_remove request: " << payload.snap_name << dendl; @@ -710,7 +710,7 @@ bool ImageWatcher::handle_payload(const SnapProtectPayload& payload, C_NotifyAck *ack_ctx) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ldout(m_image_ctx.cct, 10) << this << " remote snap_protect request: " << payload.snap_name << dendl; @@ -725,7 +725,7 @@ bool ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, C_NotifyAck *ack_ctx) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ldout(m_image_ctx.cct, 10) << this << " remote snap_unprotect request: " << payload.snap_name << dendl; @@ -740,7 +740,7 @@ bool ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { bool new_request; Context *ctx; ProgressContext *prog_ctx; @@ -762,7 +762,7 @@ bool ImageWatcher::handle_payload(const RenamePayload& payload, C_NotifyAck *ack_ctx) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ldout(m_image_ctx.cct, 10) << this << " remote rename request: " << payload.image_name << dendl; @@ -777,7 +777,7 @@ bool ImageWatcher::handle_payload(const UnknownPayload &payload, C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { + m_image_ctx.exclusive_lock->accept_requests()) { ::encode(ResponseMessage(-EOPNOTSUPP), ack_ctx->out); } return true; @@ -847,19 +847,18 @@ void ImageWatcher::acknowledge_notify(uint64_t notify_id, uint64_t handle, void ImageWatcher::reregister_watch() { ldout(m_image_ctx.cct, 10) << this << " re-registering image watch" << dendl; - bool was_lock_owner = false; + bool releasing_lock = false; C_SaferCond release_lock_ctx; { RWLock::WLocker l(m_image_ctx.owner_lock); - if (m_image_ctx.exclusive_lock != nullptr && - m_image_ctx.exclusive_lock->is_lock_owner()) { - was_lock_owner = true; + if (m_image_ctx.exclusive_lock != nullptr) { + releasing_lock = true; m_image_ctx.exclusive_lock->release_lock(&release_lock_ctx); } } int r; - if (was_lock_owner) { + if (releasing_lock) { r = release_lock_ctx.wait(); assert(r == 0); } -- 2.39.5