}
void expect_open_object_map(MockImageCtx &mock_image_ctx,
- MockObjectMap &mock_object_map) {
+ MockObjectMap &mock_object_map, int r) {
EXPECT_CALL(mock_object_map, open(_))
- .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
+ .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
}
void expect_close_object_map(MockImageCtx &mock_image_ctx,
MockObjectMap mock_object_map;
expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
expect_create_object_map(mock_image_ctx, &mock_object_map);
- expect_open_object_map(mock_image_ctx, mock_object_map);
+ expect_open_object_map(mock_image_ctx, mock_object_map, 0);
MockJournal mock_journal;
MockJournalPolicy mock_journal_policy;
MockObjectMap mock_object_map;
expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
expect_create_object_map(mock_image_ctx, &mock_object_map);
- expect_open_object_map(mock_image_ctx, mock_object_map);
+ expect_open_object_map(mock_image_ctx, mock_object_map, 0);
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, false);
MockObjectMap *mock_object_map = new MockObjectMap();
expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
expect_create_object_map(mock_image_ctx, mock_object_map);
- expect_open_object_map(mock_image_ctx, *mock_object_map);
+ expect_open_object_map(mock_image_ctx, *mock_object_map, 0);
MockJournal *mock_journal = new MockJournal();
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
MockObjectMap *mock_object_map = new MockObjectMap();
expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
expect_create_object_map(mock_image_ctx, mock_object_map);
- expect_open_object_map(mock_image_ctx, *mock_object_map);
+ expect_open_object_map(mock_image_ctx, *mock_object_map, 0);
MockJournal *mock_journal = new MockJournal();
MockJournalPolicy mock_journal_policy;
ASSERT_EQ(-EINVAL, ctx.wait());
}
+TEST_F(TestMockExclusiveLockAcquireRequest, OpenObjectMapError) {
+ REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockImageCtx mock_image_ctx(*ictx);
+ expect_op_work_queue(mock_image_ctx);
+
+ InSequence seq;
+ expect_flush_notifies(mock_image_ctx);
+ expect_lock(mock_image_ctx, 0);
+
+ MockObjectMap *mock_object_map = new MockObjectMap();
+ expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
+ expect_create_object_map(mock_image_ctx, mock_object_map);
+ expect_open_object_map(mock_image_ctx, *mock_object_map, -EFBIG);
+
+ MockJournal mock_journal;
+ MockJournalPolicy mock_journal_policy;
+ expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
+ expect_create_journal(mock_image_ctx, &mock_journal);
+ expect_open_journal(mock_image_ctx, mock_journal, 0);
+ expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
+ expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
+
+ 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());
+ ASSERT_EQ(nullptr, mock_image_ctx.object_map);
+}
+
} // namespace exclusive_lock
} // namespace librbd
}
void expect_open_object_map(MockRefreshImageCtx &mock_image_ctx,
- MockObjectMap &mock_object_map, int r) {
+ MockObjectMap *mock_object_map, int r) {
EXPECT_CALL(mock_image_ctx, create_object_map(_))
- .WillOnce(Return(&mock_object_map));
- EXPECT_CALL(mock_object_map, open(_))
+ .WillOnce(Return(mock_object_map));
+ EXPECT_CALL(*mock_object_map, open(_))
.WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
}
expect_get_snapshots(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
- expect_open_object_map(mock_image_ctx, mock_object_map, 0);
+ expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
}
expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
expect_get_snap_id(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
expect_get_mutable_metadata(mock_image_ctx, 0);
expect_get_flags(mock_image_ctx, 0);
expect_refresh_parent_is_required(mock_refresh_parent_request, false);
- expect_open_object_map(mock_image_ctx, mock_object_map, 0);
+ expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
C_SaferCond ctx;
MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, &ctx);
ASSERT_EQ(0, ctx.wait());
}
+TEST_F(TestMockImageRefreshRequest, OpenObjectMapError) {
+ REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ ASSERT_EQ(0, update_features(ictx, RBD_FEATURE_JOURNALING, false));
+
+ MockRefreshImageCtx mock_image_ctx(*ictx);
+ MockRefreshParentRequest mock_refresh_parent_request;
+
+ MockExclusiveLock mock_exclusive_lock;
+ mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+
+ MockObjectMap *mock_object_map = new MockObjectMap();
+
+ expect_op_work_queue(mock_image_ctx);
+ expect_test_features(mock_image_ctx);
+ expect_is_exclusive_lock_owner(mock_exclusive_lock, true);
+
+ // object map should be immediately opened if exclusive lock owned
+ InSequence seq;
+ expect_get_mutable_metadata(mock_image_ctx, 0);
+ expect_get_flags(mock_image_ctx, 0);
+ expect_refresh_parent_is_required(mock_refresh_parent_request, false);
+ expect_open_object_map(mock_image_ctx, mock_object_map, -EFBIG);
+
+ C_SaferCond ctx;
+ MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, &ctx);
+ req->send();
+
+ ASSERT_EQ(0, ctx.wait());
+ ASSERT_EQ(nullptr, mock_image_ctx.object_map);
+}
+
} // namespace image
} // namespace librbd