From 24396dcba77a97342d19916fdd285bae0c38fd19 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Sun, 11 Sep 2016 09:08:41 -0400 Subject: [PATCH] librbd: ignore partial refresh error when acquiring exclusive lock Fixes: http://tracker.ceph.com/issues/17227 Signed-off-by: Jason Dillaman --- src/librbd/exclusive_lock/AcquireRequest.cc | 6 +++- .../test_mock_AcquireRequest.cc | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/librbd/exclusive_lock/AcquireRequest.cc b/src/librbd/exclusive_lock/AcquireRequest.cc index 3f8923ccba86b..5b5ba67210420 100644 --- a/src/librbd/exclusive_lock/AcquireRequest.cc +++ b/src/librbd/exclusive_lock/AcquireRequest.cc @@ -184,7 +184,11 @@ Context *AcquireRequest::handle_refresh(int *ret_val) { CephContext *cct = m_image_ctx.cct; ldout(cct, 10) << __func__ << ": r=" << *ret_val << dendl; - if (*ret_val < 0) { + if (*ret_val == -ERESTART) { + // next issued IO or op will (re)-refresh the image and shut down lock + ldout(cct, 5) << ": exclusive lock dynamically disabled" << dendl; + *ret_val = 0; + } else if (*ret_val < 0) { lderr(cct) << "failed to refresh image: " << cpp_strerror(*ret_val) << dendl; m_error_result = *ret_val; diff --git a/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc b/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc index 6840b2afad8db..65d0559d77335 100644 --- a/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc +++ b/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc @@ -431,6 +431,39 @@ TEST_F(TestMockExclusiveLockAcquireRequest, RefreshError) { ASSERT_EQ(-EINVAL, ctx.wait()); } +TEST_F(TestMockExclusiveLockAcquireRequest, RefreshLockDisabled) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + MockRefreshRequest mock_refresh_request; + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_prepare_lock(mock_image_ctx); + expect_flush_notifies(mock_image_ctx); + expect_lock(mock_image_ctx, 0); + expect_is_refresh_required(mock_image_ctx, true); + expect_refresh(mock_image_ctx, mock_refresh_request, -ERESTART); + + MockObjectMap mock_object_map; + expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, false); + expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, + mock_image_ctx.snap_lock, false); + expect_handle_prepare_lock_complete(mock_image_ctx); + + C_SaferCond acquire_ctx; + C_SaferCond ctx; + MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx, + TEST_COOKIE, + &acquire_ctx, &ctx); + req->send(); + ASSERT_EQ(0, acquire_ctx.wait()); + ASSERT_EQ(0, ctx.wait()); +} + TEST_F(TestMockExclusiveLockAcquireRequest, JournalError) { REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);