From: Jason Dillaman Date: Mon, 15 May 2017 16:12:12 +0000 (-0400) Subject: librbd: reacquire lock should update lock owner client id X-Git-Tag: v12.1.0~10^2~109^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=21ce5e16703776cbae20ac981dff4ec7cc2bc9c8;p=ceph.git librbd: reacquire lock should update lock owner client id Fixes: http://tracker.ceph.com/issues/19929 Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/ExclusiveLock.cc b/src/librbd/ExclusiveLock.cc index 19ca6e42e1306..a6f8b08cf36cb 100644 --- a/src/librbd/ExclusiveLock.cc +++ b/src/librbd/ExclusiveLock.cc @@ -293,6 +293,16 @@ void ExclusiveLock::post_release_lock_handler(bool shutting_down, int r, on_finish->complete(r); } +template +void ExclusiveLock::post_reacquire_lock_handler(int r, Context *on_finish) { + ldout(m_image_ctx.cct, 10) << dendl; + if (r >= 0) { + m_image_ctx.image_watcher->notify_acquired_lock(); + } + + on_finish->complete(r); +} + template struct ExclusiveLock::C_InitComplete : public Context { ExclusiveLock *exclusive_lock; diff --git a/src/librbd/ExclusiveLock.h b/src/librbd/ExclusiveLock.h index 092f7094a6c6f..7b2e63c2bcbdc 100644 --- a/src/librbd/ExclusiveLock.h +++ b/src/librbd/ExclusiveLock.h @@ -36,6 +36,7 @@ protected: Context *on_finish) override; void post_release_lock_handler(bool shutting_down, int r, Context *on_finish) override; + void post_reacquire_lock_handler(int r, Context *on_finish) override; private: diff --git a/src/librbd/ManagedLock.cc b/src/librbd/ManagedLock.cc index 71f5dab4df650..ee321bf93adea 100644 --- a/src/librbd/ManagedLock.cc +++ b/src/librbd/ManagedLock.cc @@ -329,6 +329,11 @@ void ManagedLock::post_release_lock_handler(bool shutting_down, int r, on_finish->complete(r); } +template +void ManagedLock::post_reacquire_lock_handler(int r, Context *on_finish) { + on_finish->complete(r); +} + template bool ManagedLock::is_transition_state() const { switch (m_state) { @@ -565,11 +570,15 @@ void ManagedLock::send_reacquire_lock() { ldout(m_cct, 10) << dendl; m_state = STATE_REACQUIRING; + auto ctx = create_context_callback< + ManagedLock, &ManagedLock::handle_reacquire_lock>(this); + ctx = new FunctionContext([this, ctx](int r) { + post_reacquire_lock_handler(r, ctx); + }); + using managed_lock::ReacquireRequest; ReacquireRequest* req = ReacquireRequest::create(m_ioctx, m_oid, - m_cookie, m_new_cookie, m_mode == EXCLUSIVE, - create_context_callback< - ManagedLock, &ManagedLock::handle_reacquire_lock>(this)); + m_cookie, m_new_cookie, m_mode == EXCLUSIVE, ctx); m_work_queue->queue(new C_SendLockRequest>(req)); } diff --git a/src/librbd/ManagedLock.h b/src/librbd/ManagedLock.h index d18cfbef15602..c619f4823dd22 100644 --- a/src/librbd/ManagedLock.h +++ b/src/librbd/ManagedLock.h @@ -134,6 +134,7 @@ protected: Context *on_finish); virtual void post_release_lock_handler(bool shutting_down, int r, Context *on_finish); + virtual void post_reacquire_lock_handler(int r, Context *on_finish); void execute_next_action(); diff --git a/src/test/librbd/test_mock_ExclusiveLock.cc b/src/test/librbd/test_mock_ExclusiveLock.cc index f593f834803e5..eeb62f63ea5d2 100644 --- a/src/test/librbd/test_mock_ExclusiveLock.cc +++ b/src/test/librbd/test_mock_ExclusiveLock.cc @@ -52,6 +52,7 @@ struct ManagedLock { virtual void post_acquire_lock_handler(int, Context *) = 0; virtual void pre_release_lock_handler(bool, Context *) = 0; virtual void post_release_lock_handler(bool, int, Context *) = 0; + virtual void post_reacquire_lock_handler(int, Context *) = 0; MOCK_CONST_METHOD0(is_lock_owner, bool()); @@ -322,6 +323,12 @@ public: return ctx.wait(); } + int when_post_reacquire_lock_handler(MockManagedLock &managed_lock, int r) { + C_SaferCond ctx; + managed_lock.post_reacquire_lock_handler(r, &ctx); + return ctx.wait(); + } + int when_shut_down(MockExclusiveLockImageCtx &mock_image_ctx, MockExclusiveLock &exclusive_lock) { C_SaferCond ctx; @@ -599,6 +606,52 @@ TEST_F(TestMockExclusiveLock, PreReleaseLockError) { -EINVAL)); } +TEST_F(TestMockExclusiveLock, ReacquireLock) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockExclusiveLockImageCtx mock_image_ctx(*ictx); + MockExclusiveLock exclusive_lock(mock_image_ctx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_set_state_initializing(exclusive_lock); + expect_block_writes(mock_image_ctx); + expect_set_state_unlocked(exclusive_lock); + ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock)); + + // (try) acquire lock + MockPreAcquireRequest try_lock_pre_acquire; + expect_pre_acquire_request(try_lock_pre_acquire, 0); + ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock)); + + MockPostAcquireRequest try_lock_post_acquire; + expect_post_acquire_request(try_lock_post_acquire, 0); + expect_is_state_acquiring(exclusive_lock, true); + expect_notify_acquired_lock(mock_image_ctx); + expect_unblock_writes(mock_image_ctx); + ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, 0)); + + // reacquire lock + expect_notify_acquired_lock(mock_image_ctx); + ASSERT_EQ(0, when_post_reacquire_lock_handler(exclusive_lock, 0)); + + // shut down (and release) + expect_shut_down(exclusive_lock); + expect_is_state_waiting_for_lock(exclusive_lock, false); + ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock)); + + MockPreReleaseRequest shutdown_pre_release; + expect_pre_release_request(shutdown_pre_release, 0); + ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock, true)); + + expect_unblock_writes(mock_image_ctx); + expect_notify_released_lock(mock_image_ctx); + ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock, true, 0)); +} + TEST_F(TestMockExclusiveLock, BlockRequests) { REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);