}
CephContext *cct = m_image_ctx.cct;
- ldout(cct, 10) << dendl;
+ entity_name_t entity_name = entity_name_t::CLIENT(
+ m_image_ctx.md_ctx.get_instance_id());
+ ldout(cct, 10) << "local entity=" << entity_name << ", "
+ << "locker entity=" << m_locker.entity << dendl;
+
+ if (m_locker.entity == entity_name) {
+ lderr(cct) << "attempting to self-blacklist" << dendl;
+ finish(-EINVAL);
+ return;
+ }
// TODO: need async version of RadosClient::blacklist_add
using klass = BreakRequest<I>;
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);
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));
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(TestMockExclusiveLockBreakRequest, DeadLockOwner) {
ASSERT_EQ(0, ctx.wait());
}
+TEST_F(TestMockExclusiveLockBreakRequest, 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, locker,
+ true, false, &ctx);
+ req->send();
+ ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
TEST_F(TestMockExclusiveLockBreakRequest, BlacklistError) {
REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);