if (r < 0 || !snap_protected) {
m_r_saved = -EINVAL;
- send_remove_child();
+ send_close();
return;
}
} else {
lderr(m_cct) << "couldn't list metadata: " << cpp_strerror(r) << dendl;
m_r_saved = r;
- send_remove_child();
+ send_close();
}
return;
}
if (r < 0) {
lderr(m_cct) << "couldn't set metadata: " << cpp_strerror(r) << dendl;
m_r_saved = r;
- send_remove_child();
+ send_close();
} else {
get_mirror_mode();
}
<< dendl;
m_r_saved = r;
- send_remove_child();
+ send_close();
} else {
if (m_mirror_mode == cls::rbd::MIRROR_MODE_POOL ||
!m_non_primary_global_image_id.empty()) {
lderr(m_cct) << "failed to enable mirroring: " << cpp_strerror(r)
<< dendl;
m_r_saved = r;
- send_remove_child();
- } else {
- send_close();
}
+ send_close();
}
template <typename I>
}
}
-template <typename I>
-void CloneRequest<I>::send_remove_child() {
- ldout(m_cct, 20) << this << " " << __func__ << dendl;
-
- librados::ObjectWriteOperation op;
- cls_client::remove_child(&op, m_pspec, m_id);
-
- using klass = CloneRequest<I>;
- librados::AioCompletion *comp =
- create_rados_callback<klass, &klass::handle_remove_child>(this);
- int r = m_ioctx.aio_operate(RBD_CHILDREN, comp, &op);
- assert(r == 0);
- comp->release();
-}
-
-template <typename I>
-void CloneRequest<I>::handle_remove_child(int r) {
- ldout(m_cct, 20) << this << " " << __func__ << " r=" << r << dendl;
-
- if (r < 0) {
- lderr(m_cct) << "Error removing failed clone from list of children: "
- << cpp_strerror(r) << dendl;
- }
-
- send_close();
-}
-
template <typename I>
void CloneRequest<I>::send_remove() {
ldout(m_cct, 20) << this << " " << __func__ << dendl;
EXPECT_CALL(mock_image_ctx, destroy());
}
- void expect_remove_child(librados::IoCtx& io_ctx, int r) {
- EXPECT_CALL(get_mock_io_ctx(io_ctx),
- exec(RBD_CHILDREN, _, StrEq("rbd"), StrEq("remove_child"), _, _, _))
- .WillOnce(Return(r));
- }
-
void expect_remove(MockRemoveRequest& mock_remove_request, int r) {
EXPECT_CALL(mock_remove_request, send())
.WillOnce(Invoke([this, &mock_remove_request, r]() {
MockRefreshRequest mock_refresh_request;
expect_refresh(mock_refresh_request, -EINVAL);
- expect_remove_child(m_ioctx, 0);
expect_close(mock_image_ctx, 0);
MockRemoveRequest mock_remove_request;
expect_metadata_list(mock_image_ctx, {{"key", {}}}, -EINVAL);
- expect_remove_child(m_ioctx, 0);
expect_close(mock_image_ctx, 0);
MockRemoveRequest mock_remove_request;
expect_metadata_list(mock_image_ctx, {{"key", {}}}, 0);
expect_metadata_set(m_ioctx, mock_image_ctx, {{"key", {}}}, -EINVAL);
- expect_remove_child(m_ioctx, 0);
expect_close(mock_image_ctx, 0);
MockRemoveRequest mock_remove_request;
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
expect_mirror_mode_get(mock_image_ctx, cls::rbd::MIRROR_MODE_POOL, -EINVAL);
- expect_remove_child(m_ioctx, 0);
expect_close(mock_image_ctx, 0);
MockRemoveRequest mock_remove_request;
MockMirrorEnableRequest mock_mirror_enable_request;
expect_mirror_enable(mock_mirror_enable_request, -EINVAL);
- expect_remove_child(m_ioctx, 0);
expect_close(mock_image_ctx, 0);
MockRemoveRequest mock_remove_request;
ASSERT_EQ(-EINVAL, ctx.wait());
}
-TEST_F(TestMockImageCloneRequest, RemoveChildError) {
- REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
-
- MockTestImageCtx mock_image_ctx(*image_ctx);
- expect_op_work_queue(mock_image_ctx);
-
- InSequence seq;
- expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
- expect_is_snap_protected(mock_image_ctx, true, 0);
-
- MockCreateRequest mock_create_request;
- expect_create(mock_create_request, 0);
-
- expect_open(mock_image_ctx, 0);
- expect_set_parent(mock_image_ctx, 0);
- expect_add_child(m_ioctx, 0);
-
- MockRefreshRequest mock_refresh_request;
- expect_refresh(mock_refresh_request, -EINVAL);
-
- expect_remove_child(m_ioctx, -EPERM);
- expect_close(mock_image_ctx, 0);
-
- MockRemoveRequest mock_remove_request;
- expect_remove(mock_remove_request, 0);
-
- C_SaferCond ctx;
- ImageOptions clone_opts;
- auto req = new MockCloneRequest(&mock_image_ctx, m_ioctx, "clone name",
- "clone id", clone_opts, "", "",
- image_ctx->op_work_queue, &ctx);
- req->send();
- ASSERT_EQ(-EINVAL, ctx.wait());
-}
-
TEST_F(TestMockImageCloneRequest, RemoveError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);