template <typename I>
void CloneRequest<I>::open_parent() {
ldout(m_cct, 20) << dendl;
+ assert(m_parent_snap_name.empty() ^ (m_parent_snap_id == CEPH_NOSNAP));
- m_parent_image_ctx = I::create("", m_parent_image_id, "", m_parent_io_ctx, true);
+ if (m_parent_snap_id != CEPH_NOSNAP) {
+ m_parent_image_ctx = I::create("", m_parent_image_id, m_parent_snap_id,
+ m_parent_io_ctx, true);
+ } else {
+ m_parent_image_ctx = I::create("", m_parent_image_id,
+ m_parent_snap_name.c_str(), m_parent_io_ctx,
+ true);
+ }
Context *ctx = create_context_callback<
CloneRequest<I>, &CloneRequest<I>::handle_open_parent>(this);
return;
}
- set_parent_snap();
-}
-
-template <typename I>
-void CloneRequest<I>::set_parent_snap() {
- assert((m_parent_snap_name.empty()) ^ (m_parent_snap_id == CEPH_NOSNAP));
-
- if (m_parent_snap_id == CEPH_NOSNAP) {
- // look up user snapshot by name
- m_parent_image_ctx->snap_lock.get_read();
- auto it = m_parent_image_ctx->snap_ids.find(
- {cls::rbd::UserSnapshotNamespace{}, m_parent_snap_name});
- if (it == m_parent_image_ctx->snap_ids.end()) {
- m_parent_image_ctx->snap_lock.put_read();
-
- lderr(m_cct) << "failed to located parent snapshot: " <<
- m_parent_snap_name << dendl;
- m_r_saved = -ENOENT;
- close_parent();
- return;
- }
-
- m_parent_snap_id = it->second;
- m_parent_image_ctx->snap_lock.put_read();
- }
-
- ldout(m_cct, 20) << "parent_snap_id=" << m_parent_snap_id << dendl;
-
- Context *ctx = create_context_callback<
- CloneRequest<I>, &CloneRequest<I>::handle_set_parent_snap>(this);
- m_parent_image_ctx->state->snap_set(m_parent_snap_id, ctx);
-}
-
-template <typename I>
-void CloneRequest<I>::handle_set_parent_snap(int r) {
- ldout(m_cct, 20) << "r=" << r << dendl;
-
- if (r < 0) {
- lderr(m_cct) << "failed to set parent snapshot: " << cpp_strerror(r)
- << dendl;
-
- m_r_saved = r;
- close_parent();
- return;
- }
-
+ m_parent_snap_id = m_parent_image_ctx->snap_id;
m_pspec = {m_parent_io_ctx.get_id(), m_parent_image_id, m_parent_snap_id};
validate_parent();
}
assert(s_instance != nullptr);
return s_instance;
}
+ static MockTestImageCtx* create(const std::string &image_name,
+ const std::string &image_id,
+ librados::snap_t snap_id, IoCtx& p,
+ bool read_only) {
+ assert(s_instance != nullptr);
+ return s_instance;
+ }
MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
s_instance = this;
}
}
- void expect_snap_set(librbd::MockTestImageCtx &mock_image_ctx,
- uint64_t snap_id, int r) {
- EXPECT_CALL(*mock_image_ctx.state, snap_set(snap_id, _))
- .WillOnce(WithArg<1>(Invoke([this, r](Context *on_finish) {
- image_ctx->op_work_queue->queue(on_finish, r);
- })));
- }
-
void expect_set_parent(MockImageCtx &mock_image_ctx, int r) {
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_get_min_compat_client(1, 0);
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
ASSERT_EQ(-EINVAL, ctx.wait());
}
-TEST_F(TestMockImageCloneRequest, SetParentSnapError) {
- REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
-
- MockTestImageCtx mock_image_ctx(*image_ctx);
- expect_op_work_queue(mock_image_ctx);
-
- InSequence seq;
- expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, -EINVAL);
- expect_close(mock_image_ctx, 0);
-
- C_SaferCond ctx;
- ImageOptions clone_opts;
- auto req = new MockCloneRequest(m_ioctx, "parent id", "", 123, m_ioctx,
- "clone name", "clone id", clone_opts, "", "",
- image_ctx->op_work_queue, &ctx);
- req->send();
- ASSERT_EQ(-EINVAL, ctx.wait());
-}
-
TEST_F(TestMockImageCloneRequest, CreateError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);
InSequence seq;
expect_open(mock_image_ctx, 0);
- expect_snap_set(mock_image_ctx, 123, 0);
expect_get_image_size(mock_image_ctx, mock_image_ctx.snaps.front(), 123);
expect_is_snap_protected(mock_image_ctx, true, 0);