TestMockJournalReplay() : m_invoke_lock("m_invoke_lock") {
}
+ void expect_accept_ops(MockExclusiveLock &mock_exclusive_lock, bool accept) {
+ EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillRepeatedly(
+ Return(accept));
+ }
+
void expect_aio_discard(MockIoImageRequest &mock_io_image_request,
io::AioCompletion **aio_comp, uint64_t off,
uint64_t len, bool skip_partial_discard) {
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
bool enabled = !ictx->test_features(features);
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, true);
+
MockJournalReplay mock_journal_replay(mock_image_ctx);
MockIoImageRequest mock_io_image_request;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
}
+TEST_F(TestMockJournalReplay, LockLostBeforeProcess) {
+ REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, false);
+
+ MockJournalReplay mock_journal_replay(mock_image_ctx);
+ MockIoImageRequest mock_io_image_request;
+ expect_op_work_queue(mock_image_ctx);
+
+ InSequence seq;
+ C_SaferCond on_ready;
+ C_SaferCond on_safe;
+ when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
+ &on_ready, &on_safe);
+ ASSERT_EQ(0, on_ready.wait());
+ ASSERT_EQ(-ECANCELED, on_safe.wait());
+
+ ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
+}
+
+TEST_F(TestMockJournalReplay, LockLostBeforeExecuteOp) {
+ REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockReplayImageCtx mock_image_ctx(*ictx);
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+ expect_accept_ops(mock_exclusive_lock, false);
+
+ MockJournalReplay mock_journal_replay(mock_image_ctx);
+ expect_op_work_queue(mock_image_ctx);
+
+ InSequence seq;
+ EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
+ EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
+ expect_refresh_image(mock_image_ctx, false, 0);
+
+ C_SaferCond on_start_ready;
+ C_SaferCond on_start_safe;
+ when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
+ &on_start_ready, &on_start_safe);
+ ASSERT_EQ(0, on_start_ready.wait());
+
+ C_SaferCond on_finish_ready;
+ C_SaferCond on_finish_safe;
+ when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+ &on_finish_ready, &on_finish_safe);
+
+ ASSERT_EQ(-ECANCELED, on_start_safe.wait());
+ ASSERT_EQ(0, on_finish_ready.wait());
+ ASSERT_EQ(-ECANCELED, on_finish_safe.wait());
+}
+
} // namespace journal
} // namespace librbd