From cb6712b0d9d5bccadb23a0e011eef05cf4d92280 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 31 May 2018 14:04:19 -0400 Subject: [PATCH] librbd: ensure managed lock can shut down if stuck waiting for register Signed-off-by: Jason Dillaman --- src/librbd/ManagedLock.cc | 10 ++++++++ src/test/librbd/test_mock_ManagedLock.cc | 31 ++++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/librbd/ManagedLock.cc b/src/librbd/ManagedLock.cc index 53bfd26226655..81dd880c8e550 100644 --- a/src/librbd/ManagedLock.cc +++ b/src/librbd/ManagedLock.cc @@ -129,6 +129,16 @@ void ManagedLock::shut_down(Context *on_shut_down) { Mutex::Locker locker(m_lock); assert(!is_state_shutdown()); + + if (m_state == STATE_WAITING_FOR_REGISTER) { + // abort stalled acquire lock state + ldout(m_cct, 10) << "woke up waiting acquire" << dendl; + Action active_action = get_active_action(); + assert(active_action == ACTION_TRY_LOCK || + active_action == ACTION_ACQUIRE_LOCK); + complete_active_action(STATE_UNLOCKED, -ESHUTDOWN); + } + execute_action(ACTION_SHUT_DOWN, on_shut_down); } diff --git a/src/test/librbd/test_mock_ManagedLock.cc b/src/test/librbd/test_mock_ManagedLock.cc index d6b8f5955637a..9b4381878010c 100644 --- a/src/test/librbd/test_mock_ManagedLock.cc +++ b/src/test/librbd/test_mock_ManagedLock.cc @@ -214,7 +214,7 @@ public: } on_finish->complete(r);})); } - + int when_acquire_lock(MockManagedLock &managed_lock) { C_SaferCond ctx; { @@ -529,19 +529,19 @@ TEST_F(TestMockManagedLock, ReacquireLockError) { TEST_F(TestMockManagedLock, ReacquireWithSameCookie) { librbd::ImageCtx *ictx; ASSERT_EQ(0, open_image(m_image_name, &ictx)); - + MockManagedLockImageCtx mock_image_ctx(*ictx); MockMockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue, ictx->header_oid, mock_image_ctx.image_watcher, librbd::managed_lock::EXCLUSIVE, true, 0); InSequence seq; - + MockAcquireRequest request_lock_acquire; expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire, 0); ASSERT_EQ(0, when_acquire_lock(managed_lock)); ASSERT_TRUE(is_lock_owner(managed_lock)); - - // watcher with same cookie after rewatch + + // watcher with same cookie after rewatch uint64_t client_id = 0; C_SaferCond reacquire_ctx; expect_post_reacquired_lock_handler(*mock_image_ctx.image_watcher, managed_lock, client_id); @@ -555,4 +555,25 @@ TEST_F(TestMockManagedLock, ReacquireWithSameCookie) { ASSERT_EQ(0, when_shut_down(managed_lock)); } +TEST_F(TestMockManagedLock, ShutDownWhileWaiting) { + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockManagedLockImageCtx mock_image_ctx(*ictx); + MockMockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue, + ictx->header_oid, mock_image_ctx.image_watcher, + librbd::managed_lock::EXCLUSIVE, true, 0); + + InSequence seq; + + expect_get_watch_handle(*mock_image_ctx.image_watcher, 0); + + C_SaferCond acquire_ctx; + managed_lock.acquire_lock(&acquire_ctx); + + ASSERT_EQ(0, when_shut_down(managed_lock)); + ASSERT_EQ(-ESHUTDOWN, acquire_ctx.wait()); + ASSERT_FALSE(is_lock_owner(managed_lock)); +} + } // namespace librbd -- 2.39.5