From 6fa25c2bf230263da6f9a26739938d67c13b5bba Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 18 May 2017 12:38:44 -0400 Subject: [PATCH] librbd: recheck current lock owner before blacklist Signed-off-by: Jason Dillaman --- qa/workunits/rbd/rbd_mirror.sh | 4 + src/librbd/ManagedLock.cc | 5 +- src/librbd/managed_lock/AcquireRequest.cc | 7 +- src/librbd/managed_lock/AcquireRequest.h | 20 +- src/librbd/managed_lock/BreakRequest.cc | 42 +++- src/librbd/managed_lock/BreakRequest.h | 22 +- .../managed_lock/test_mock_AcquireRequest.cc | 3 +- .../managed_lock/test_mock_BreakRequest.cc | 204 +++++++++++++++++- src/test/librbd/test_mock_ManagedLock.cc | 2 +- 9 files changed, 275 insertions(+), 34 deletions(-) diff --git a/qa/workunits/rbd/rbd_mirror.sh b/qa/workunits/rbd/rbd_mirror.sh index f4935941205..f000b66271c 100755 --- a/qa/workunits/rbd/rbd_mirror.sh +++ b/qa/workunits/rbd/rbd_mirror.sh @@ -387,4 +387,8 @@ wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+error' 'split-brain request_resync_image ${CLUSTER1} ${POOL} ${image} image_id wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying' 'master_position' +testlog "TEST: no blacklists" +ceph --cluster ${CLUSTER1} osd blacklist ls 2>&1 | grep -q "listed 0 entries" +ceph --cluster ${CLUSTER2} osd blacklist ls 2>&1 | grep -q "listed 0 entries" + echo OK diff --git a/src/librbd/ManagedLock.cc b/src/librbd/ManagedLock.cc index ee321bf93ad..f584d6af5fb 100644 --- a/src/librbd/ManagedLock.cc +++ b/src/librbd/ManagedLock.cc @@ -256,8 +256,9 @@ void ManagedLock::break_lock(const managed_lock::Locker &locker, } else { on_finish = new C_Tracked(m_async_op_tracker, on_finish); auto req = managed_lock::BreakRequest::create( - m_ioctx, m_work_queue, m_oid, locker, m_blacklist_on_break_lock, - m_blacklist_expire_seconds, force_break_lock, on_finish); + m_ioctx, m_work_queue, m_oid, locker, m_mode == EXCLUSIVE, + m_blacklist_on_break_lock, m_blacklist_expire_seconds, force_break_lock, + on_finish); req->send(); return; } diff --git a/src/librbd/managed_lock/AcquireRequest.cc b/src/librbd/managed_lock/AcquireRequest.cc index 0249be2a14e..83f5dbac1a8 100644 --- a/src/librbd/managed_lock/AcquireRequest.cc +++ b/src/librbd/managed_lock/AcquireRequest.cc @@ -146,8 +146,8 @@ void AcquireRequest::send_break_lock() { Context *ctx = create_context_callback< AcquireRequest, &AcquireRequest::handle_break_lock>(this); auto req = BreakRequest::create( - m_ioctx, m_work_queue, m_oid, m_locker, m_blacklist_on_break_lock, - m_blacklist_expire_seconds, false, ctx); + m_ioctx, m_work_queue, m_oid, m_locker, m_exclusive, + m_blacklist_on_break_lock, m_blacklist_expire_seconds, false, ctx); req->send(); } @@ -165,7 +165,8 @@ void AcquireRequest::handle_break_lock(int r) { return; } - send_get_locker(); + m_locker = {}; + send_lock(); } template diff --git a/src/librbd/managed_lock/AcquireRequest.h b/src/librbd/managed_lock/AcquireRequest.h index 16a5be36c78..20af0693349 100644 --- a/src/librbd/managed_lock/AcquireRequest.h +++ b/src/librbd/managed_lock/AcquireRequest.h @@ -47,15 +47,17 @@ private: * * | * v - * GET_LOCKER <---------------------------------------\ - * | ^ | - * | . (EBUSY && no cached locker) | - * | . | - * | . (EBUSY && cached locker) | - * \--> LOCK_IMAGE * * * * * * * * > BREAK_LOCK ---/ - * | - * v - * + * GET_LOCKER + * | ^ + * | . (EBUSY && no cached locker) + * | . + * | . (EBUSY && cached locker) + * \--> LOCK_IMAGE * * * * * * * * > BREAK_LOCK . . . . . + * | ^ | . + * | | | (success) . + * | \-------------------------/ . + * v . + * < . . . . . . . . . . . . . . . . . . . * * @endverbatim */ diff --git a/src/librbd/managed_lock/BreakRequest.cc b/src/librbd/managed_lock/BreakRequest.cc index 6c4d4d208fe..9a7fe10f35a 100644 --- a/src/librbd/managed_lock/BreakRequest.cc +++ b/src/librbd/managed_lock/BreakRequest.cc @@ -10,6 +10,7 @@ #include "cls/lock/cls_lock_types.h" #include "librbd/ImageCtx.h" #include "librbd/Utils.h" +#include "librbd/managed_lock/GetLockerRequest.h" #define dout_subsys ceph_subsys_rbd #undef dout_prefix @@ -48,12 +49,12 @@ struct C_BlacklistClient : public Context { template BreakRequest::BreakRequest(librados::IoCtx& ioctx, ContextWQ *work_queue, const std::string& oid, const Locker &locker, - bool blacklist_locker, + bool exclusive, bool blacklist_locker, uint32_t blacklist_expire_seconds, bool force_break_lock, Context *on_finish) : m_ioctx(ioctx), m_cct(reinterpret_cast(m_ioctx.cct())), m_work_queue(work_queue), m_oid(oid), m_locker(locker), - m_blacklist_locker(blacklist_locker), + m_exclusive(exclusive), m_blacklist_locker(blacklist_locker), m_blacklist_expire_seconds(blacklist_expire_seconds), m_force_break_lock(force_break_lock), m_on_finish(on_finish) { } @@ -112,6 +113,43 @@ void BreakRequest::handle_get_watchers(int r) { return; } + send_get_locker(); +} + +template +void BreakRequest::send_get_locker() { + ldout(m_cct, 10) << dendl; + + using klass = BreakRequest; + Context *ctx = create_context_callback( + this); + auto req = GetLockerRequest::create(m_ioctx, m_oid, m_exclusive, + &m_refreshed_locker, ctx); + req->send(); +} + +template +void BreakRequest::handle_get_locker(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r == -ENOENT) { + ldout(m_cct, 5) << "no lock owner" << dendl; + finish(0); + return; + } else if (r < 0 && r != -EBUSY) { + lderr(m_cct) << "failed to retrieve lockers: " << cpp_strerror(r) << dendl; + finish(r); + return; + } else if (r < 0) { + m_refreshed_locker = {}; + } + + if (m_refreshed_locker != m_locker || m_refreshed_locker == Locker{}) { + ldout(m_cct, 5) << "no longer lock owner" << dendl; + finish(-EAGAIN); + return; + } + send_blacklist(); } diff --git a/src/librbd/managed_lock/BreakRequest.h b/src/librbd/managed_lock/BreakRequest.h index 045f629de29..6f4f4acab04 100644 --- a/src/librbd/managed_lock/BreakRequest.h +++ b/src/librbd/managed_lock/BreakRequest.h @@ -30,12 +30,12 @@ class BreakRequest { public: static BreakRequest* create(librados::IoCtx& ioctx, ContextWQ *work_queue, const std::string& oid, const Locker &locker, - bool blacklist_locker, + bool exclusive, bool blacklist_locker, uint32_t blacklist_expire_seconds, bool force_break_lock, Context *on_finish) { - return new BreakRequest(ioctx, work_queue, oid, locker, blacklist_locker, - blacklist_expire_seconds, force_break_lock, - on_finish); + return new BreakRequest(ioctx, work_queue, oid, locker, exclusive, + blacklist_locker, blacklist_expire_seconds, + force_break_lock, on_finish); } void send(); @@ -50,6 +50,9 @@ private: * GET_WATCHERS * | * v + * GET_LOCKER + * | + * v * BLACKLIST (skip if disabled) * | * v @@ -66,6 +69,7 @@ private: ContextWQ *m_work_queue; std::string m_oid; Locker m_locker; + bool m_exclusive; bool m_blacklist_locker; uint32_t m_blacklist_expire_seconds; bool m_force_break_lock; @@ -76,14 +80,20 @@ private: std::list m_watchers; int m_watchers_ret_val; + Locker m_refreshed_locker; + BreakRequest(librados::IoCtx& ioctx, ContextWQ *work_queue, const std::string& oid, const Locker &locker, - bool blacklist_locker, uint32_t blacklist_expire_seconds, - bool force_break_lock, Context *on_finish); + bool exclusive, bool blacklist_locker, + uint32_t blacklist_expire_seconds, bool force_break_lock, + Context *on_finish); void send_get_watchers(); void handle_get_watchers(int r); + void send_get_locker(); + void handle_get_locker(int r); + void send_blacklist(); void handle_blacklist(int r); diff --git a/src/test/librbd/managed_lock/test_mock_AcquireRequest.cc b/src/test/librbd/managed_lock/test_mock_AcquireRequest.cc index 4860b0385cb..174e97be49b 100644 --- a/src/test/librbd/managed_lock/test_mock_AcquireRequest.cc +++ b/src/test/librbd/managed_lock/test_mock_AcquireRequest.cc @@ -30,7 +30,7 @@ struct BreakRequest { static BreakRequest *s_instance; static BreakRequest* create(librados::IoCtx& ioctx, ContextWQ *work_queue, const std::string& oid, const Locker &locker, - bool blacklist_locker, + bool exclusive, bool blacklist_locker, uint32_t blacklist_expire_seconds, bool force_break_lock, Context *on_finish) { CephContext *cct = reinterpret_cast(ioctx.cct()); @@ -195,7 +195,6 @@ TEST_F(TestMockManagedLockAcquireRequest, LockBusy) { 0); expect_lock(mock_image_ctx, -EBUSY); expect_break_lock(mock_image_ctx, mock_break_request, 0); - expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, 0); expect_lock(mock_image_ctx, -ENOENT); C_SaferCond ctx; diff --git a/src/test/librbd/managed_lock/test_mock_BreakRequest.cc b/src/test/librbd/managed_lock/test_mock_BreakRequest.cc index c1dff856a0d..faeb090d505 100644 --- a/src/test/librbd/managed_lock/test_mock_BreakRequest.cc +++ b/src/test/librbd/managed_lock/test_mock_BreakRequest.cc @@ -8,6 +8,7 @@ #include "test/librados_test_stub/MockTestMemRadosClient.h" #include "cls/lock/cls_lock_ops.h" #include "librbd/managed_lock/BreakRequest.h" +#include "librbd/managed_lock/GetLockerRequest.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include @@ -23,6 +24,33 @@ struct MockTestImageCtx : public librbd::MockImageCtx { }; } // anonymous namespace + +namespace managed_lock { + +template <> +struct GetLockerRequest { + Locker *locker; + Context *on_finish = nullptr; + static GetLockerRequest *s_instance; + static GetLockerRequest* create(librados::IoCtx& ioctx, + const std::string& oid, bool exclusive, + Locker *locker, Context *on_finish) { + assert(s_instance != nullptr); + s_instance->locker = locker; + s_instance->on_finish = on_finish; + return s_instance; + } + + + GetLockerRequest() { + s_instance = this; + } + MOCK_METHOD0(send, void()); +}; + +GetLockerRequest *GetLockerRequest::s_instance = nullptr; + +} // namespace managed_lock } // namespace librbd // template definitions @@ -34,6 +62,7 @@ namespace managed_lock { using ::testing::_; using ::testing::DoAll; using ::testing::InSequence; +using ::testing::Invoke; using ::testing::Return; using ::testing::SetArgPointee; using ::testing::StrEq; @@ -42,6 +71,7 @@ using ::testing::WithArg; class TestMockManagedLockBreakRequest : public TestMockFixture { public: typedef BreakRequest MockBreakRequest; + typedef GetLockerRequest MockGetLockerRequest; void expect_list_watchers(MockTestImageCtx &mock_image_ctx, int r, const std::string &address, uint64_t watch_handle) { @@ -61,6 +91,18 @@ public: } } + void expect_get_locker(MockImageCtx &mock_image_ctx, + MockGetLockerRequest &mock_get_locker_request, + const Locker &locker, int r) { + EXPECT_CALL(mock_get_locker_request, send()) + .WillOnce(Invoke([&mock_image_ctx, &mock_get_locker_request, locker, r]() { + *mock_get_locker_request.locker = locker; + mock_image_ctx.image_ctx->op_work_queue->queue( + mock_get_locker_request.on_finish, r); + })); + } + + void expect_blacklist_add(MockTestImageCtx &mock_image_ctx, int r) { EXPECT_CALL(*get_mock_io_ctx(mock_image_ctx.md_ctx).get_mock_rados_client(), blacklist_add(_, _)) @@ -90,6 +132,12 @@ TEST_F(TestMockManagedLockBreakRequest, DeadLockOwner) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + 0); + expect_blacklist_add(mock_image_ctx, 0); expect_break_lock(mock_image_ctx, 0); @@ -97,7 +145,7 @@ TEST_F(TestMockManagedLockBreakRequest, DeadLockOwner) { Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } @@ -113,6 +161,12 @@ TEST_F(TestMockManagedLockBreakRequest, ForceBreak) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "1.2.3.4", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + 0); + expect_blacklist_add(mock_image_ctx, 0); expect_break_lock(mock_image_ctx, 0); @@ -120,7 +174,7 @@ TEST_F(TestMockManagedLockBreakRequest, ForceBreak) { Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, true, &ctx); + locker, true, true, 0, true, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } @@ -141,7 +195,7 @@ TEST_F(TestMockManagedLockBreakRequest, GetWatchersError) { Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -162,11 +216,113 @@ TEST_F(TestMockManagedLockBreakRequest, GetWatchersAlive) { Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); + req->send(); + ASSERT_EQ(-EAGAIN, ctx.wait()); +} + +TEST_F(TestMockManagedLockBreakRequest, GetLockerUpdated) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(2), "auto 123", "1.2.3.4:0/0", 123}, + 0); + + C_SaferCond ctx; + Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; + MockBreakRequest *req = MockBreakRequest::create( + mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, + locker, true, false, 0, false, &ctx); + req->send(); + ASSERT_EQ(-EAGAIN, ctx.wait()); +} + +TEST_F(TestMockManagedLockBreakRequest, GetLockerBusy) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + -EBUSY); + + C_SaferCond ctx; + Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; + MockBreakRequest *req = MockBreakRequest::create( + mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, + locker, true, false, 0, false, &ctx); req->send(); ASSERT_EQ(-EAGAIN, ctx.wait()); } +TEST_F(TestMockManagedLockBreakRequest, GetLockerMissing) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + -ENOENT); + + C_SaferCond ctx; + Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; + MockBreakRequest *req = MockBreakRequest::create( + mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, + locker, true, false, 0, false, &ctx); + req->send(); + ASSERT_EQ(0, ctx.wait()); +} + +TEST_F(TestMockManagedLockBreakRequest, GetLockerError) { + REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + expect_op_work_queue(mock_image_ctx); + + InSequence seq; + expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, -EINVAL); + + C_SaferCond ctx; + Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; + MockBreakRequest *req = MockBreakRequest::create( + mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, + locker, true, false, 0, false, &ctx); + req->send(); + ASSERT_EQ(-EINVAL, ctx.wait()); +} + TEST_F(TestMockManagedLockBreakRequest, BlacklistDisabled) { REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); @@ -178,13 +334,19 @@ TEST_F(TestMockManagedLockBreakRequest, BlacklistDisabled) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + 0); + expect_break_lock(mock_image_ctx, 0); C_SaferCond ctx; Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, false, 0, false, &ctx); + locker, true, false, 0, false, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } @@ -200,13 +362,19 @@ TEST_F(TestMockManagedLockBreakRequest, BlacklistSelf) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "dead client", 456); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(456), "auto 123", "1.2.3.4:0/0", + 123}, 0); + expect_get_instance_id(mock_image_ctx, 456); C_SaferCond ctx; Locker locker{entity_name_t::CLIENT(456), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -222,13 +390,19 @@ TEST_F(TestMockManagedLockBreakRequest, BlacklistError) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + 0); + expect_blacklist_add(mock_image_ctx, -EINVAL); C_SaferCond ctx; Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -244,6 +418,12 @@ TEST_F(TestMockManagedLockBreakRequest, BreakLockMissing) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + 0); + expect_blacklist_add(mock_image_ctx, 0); expect_break_lock(mock_image_ctx, -ENOENT); @@ -251,7 +431,7 @@ TEST_F(TestMockManagedLockBreakRequest, BreakLockMissing) { Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } @@ -267,6 +447,12 @@ TEST_F(TestMockManagedLockBreakRequest, BreakLockError) { InSequence seq; expect_list_watchers(mock_image_ctx, 0, "dead client", 123); + + MockGetLockerRequest mock_get_locker_request; + expect_get_locker(mock_image_ctx, mock_get_locker_request, + {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, + 0); + expect_blacklist_add(mock_image_ctx, 0); expect_break_lock(mock_image_ctx, -EINVAL); @@ -274,7 +460,7 @@ TEST_F(TestMockManagedLockBreakRequest, BreakLockError) { Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; MockBreakRequest *req = MockBreakRequest::create( mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid, - locker, true, 0, false, &ctx); + locker, true, true, 0, false, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } diff --git a/src/test/librbd/test_mock_ManagedLock.cc b/src/test/librbd/test_mock_ManagedLock.cc index 7e79aa24125..a808523fc20 100644 --- a/src/test/librbd/test_mock_ManagedLock.cc +++ b/src/test/librbd/test_mock_ManagedLock.cc @@ -106,7 +106,7 @@ template <> struct BreakRequest { static BreakRequest* create(librados::IoCtx& ioctx, ContextWQ *work_queue, const std::string& oid, const Locker &locker, - bool blacklist_locker, + bool exclusive, bool blacklist_locker, uint32_t blacklist_expire_seconds, bool force_break_lock, Context *on_finish) { assert(0 == "unexpected call"); -- 2.39.5