mirror of
https://github.com/ceph/ceph
synced 2024-12-21 10:54:42 +00:00
Merge pull request #13110 from dillaman/wip-18666
librbd: prevent self-blacklisting during break lock Reviewed-by: Mykola Golub <mgolub@mirantis.com>
This commit is contained in:
commit
c720e348d4
@ -119,7 +119,15 @@ void BreakRequest<I>::send_blacklist() {
|
||||
return;
|
||||
}
|
||||
|
||||
ldout(m_cct, 10) << dendl;
|
||||
entity_name_t entity_name = entity_name_t::CLIENT(m_ioctx.get_instance_id());
|
||||
ldout(m_cct, 10) << "local entity=" << entity_name << ", "
|
||||
<< "locker entity=" << m_locker.entity << dendl;
|
||||
|
||||
if (m_locker.entity == entity_name) {
|
||||
lderr(m_cct) << "attempting to self-blacklist" << dendl;
|
||||
finish(-EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: need async version of RadosClient::blacklist_add
|
||||
using klass = BreakRequest<I>;
|
||||
|
@ -60,6 +60,11 @@ public:
|
||||
snapc);
|
||||
}
|
||||
|
||||
MOCK_CONST_METHOD0(get_instance_id, uint64_t());
|
||||
uint64_t do_get_instance_id() const {
|
||||
return TestMemIoCtxImpl::get_instance_id();
|
||||
}
|
||||
|
||||
MOCK_METHOD2(list_snaps, int(const std::string& o, snap_set_t *out_snaps));
|
||||
int do_list_snaps(const std::string& o, snap_set_t *out_snaps) {
|
||||
return TestMemIoCtxImpl::list_snaps(o, out_snaps);
|
||||
@ -148,6 +153,7 @@ public:
|
||||
ON_CALL(*this, aio_watch(_, _, _, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_aio_watch));
|
||||
ON_CALL(*this, aio_unwatch(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_aio_unwatch));
|
||||
ON_CALL(*this, exec(_, _, _, _, _, _, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_exec));
|
||||
ON_CALL(*this, get_instance_id()).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_get_instance_id));
|
||||
ON_CALL(*this, list_snaps(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_list_snaps));
|
||||
ON_CALL(*this, list_watchers(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_list_watchers));
|
||||
ON_CALL(*this, notify(_, _, _, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_notify));
|
||||
|
@ -71,6 +71,11 @@ public:
|
||||
exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("break_lock"), _, _, _))
|
||||
.WillOnce(Return(r));
|
||||
}
|
||||
|
||||
void expect_get_instance_id(MockTestImageCtx &mock_image_ctx, uint64_t id) {
|
||||
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), get_instance_id())
|
||||
.WillOnce(Return(id));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestMockManagedLockBreakRequest, DeadLockOwner) {
|
||||
@ -183,6 +188,28 @@ TEST_F(TestMockManagedLockBreakRequest, BlacklistDisabled) {
|
||||
ASSERT_EQ(0, ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockManagedLockBreakRequest, BlacklistSelf) {
|
||||
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", 456);
|
||||
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);
|
||||
req->send();
|
||||
ASSERT_EQ(-EINVAL, ctx.wait());
|
||||
}
|
||||
|
||||
TEST_F(TestMockManagedLockBreakRequest, BlacklistError) {
|
||||
REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user