librbd: make AttachParentRequest support reattach

Signed-off-by: Mykola Golub <mgolub@suse.com>
This commit is contained in:
Mykola Golub 2019-01-21 08:29:14 +00:00
parent 6795f0267d
commit 79d9fea47b
8 changed files with 35 additions and 24 deletions

View File

@ -177,7 +177,7 @@ void SetHeadRequest<I>::send_attach_parent() {
finish_op_ctx->complete(0);
});
auto req = image::AttachParentRequest<I>::create(
*m_image_ctx, m_parent_spec, m_parent_overlap, ctx);
*m_image_ctx, m_parent_spec, m_parent_overlap, false, ctx);
req->send();
}

View File

@ -1,4 +1,4 @@
// -*- mode:C++; tab-width:8; c-basic-offattach:2; indent-tabs-mode:t -*-
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include "librbd/image/AttachParentRequest.h"
@ -17,7 +17,6 @@
namespace librbd {
namespace image {
using util::create_context_callback;
using util::create_rados_callback;
template <typename I>
@ -33,7 +32,7 @@ void AttachParentRequest<I>::attach_parent() {
librados::ObjectWriteOperation op;
if (!m_legacy_parent) {
librbd::cls_client::parent_attach(&op, m_parent_image_spec,
m_parent_overlap);
m_parent_overlap, m_reattach);
} else {
librbd::cls_client::set_parent(&op, m_parent_image_spec, m_parent_overlap);
}
@ -51,7 +50,7 @@ void AttachParentRequest<I>::handle_attach_parent(int r) {
auto cct = m_image_ctx.cct;
ldout(cct, 5) << dendl;
if (!m_legacy_parent && r == -EOPNOTSUPP) {
if (!m_legacy_parent && r == -EOPNOTSUPP && !m_reattach) {
if (m_parent_image_spec.pool_namespace ==
m_image_ctx.md_ctx.get_namespace()) {
m_parent_image_spec.pool_namespace = "";

View File

@ -1,4 +1,4 @@
// -*- mode:C++; tab-width:8; c-basic-offattach:2; indent-tabs-mode:t -*-
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_LIBRBD_IMAGE_ATTACH_PARENT_REQUEST_H
@ -23,15 +23,19 @@ public:
static AttachParentRequest* create(ImageCtxT& image_ctx,
const cls::rbd::ParentImageSpec& pspec,
uint64_t parent_overlap,
bool reattach,
Context* on_finish) {
return new AttachParentRequest(image_ctx, pspec, parent_overlap, on_finish);
return new AttachParentRequest(image_ctx, pspec, parent_overlap, reattach,
on_finish);
}
AttachParentRequest(ImageCtxT& image_ctx,
const cls::rbd::ParentImageSpec& pspec,
uint64_t parent_overlap, Context* on_finish)
uint64_t parent_overlap, bool reattach,
Context* on_finish)
: m_image_ctx(image_ctx), m_parent_image_spec(pspec),
m_parent_overlap(parent_overlap), m_on_finish(on_finish) {
m_parent_overlap(parent_overlap), m_reattach(reattach),
m_on_finish(on_finish) {
}
void send();
@ -55,6 +59,7 @@ private:
ImageCtxT& m_image_ctx;
cls::rbd::ParentImageSpec m_parent_image_spec;
uint64_t m_parent_overlap;
bool m_reattach;
Context* m_on_finish;
bool m_legacy_parent = false;

View File

@ -342,7 +342,7 @@ void CloneRequest<I>::attach_parent() {
auto ctx = create_context_callback<
CloneRequest<I>, &CloneRequest<I>::handle_attach_parent>(this);
auto req = AttachParentRequest<I>::create(
*m_imctx, m_pspec, m_size, ctx);
*m_imctx, m_pspec, m_size, false, ctx);
req->send();
}

View File

@ -855,7 +855,8 @@ TEST_F(TestClsRbd, parents_v2)
ASSERT_EQ(-ENOENT, parent_get(&ioctx, oid, &parent_image_spec));
ASSERT_EQ(-ENOENT, parent_overlap_get(&ioctx, oid, CEPH_NOSNAP,
&parent_overlap));
ASSERT_EQ(-ENOENT, parent_attach(&ioctx, oid, parent_image_spec, 0ULL));
ASSERT_EQ(-ENOENT, parent_attach(&ioctx, oid, parent_image_spec, 0ULL,
false));
ASSERT_EQ(-ENOENT, parent_detach(&ioctx, oid));
// no layering support should fail
@ -865,7 +866,7 @@ TEST_F(TestClsRbd, parents_v2)
ASSERT_FALSE(parent_image_spec.exists());
ASSERT_EQ(0, parent_overlap_get(&ioctx, oid, CEPH_NOSNAP, &parent_overlap));
ASSERT_EQ(std::nullopt, parent_overlap);
ASSERT_EQ(-ENOEXEC, parent_attach(&ioctx, oid, parent_image_spec, 0ULL));
ASSERT_EQ(-ENOEXEC, parent_attach(&ioctx, oid, parent_image_spec, 0ULL, false));
ASSERT_EQ(-ENOEXEC, parent_detach(&ioctx, oid));
// layering support available -- no pool namespaces
@ -877,14 +878,17 @@ TEST_F(TestClsRbd, parents_v2)
ASSERT_FALSE(parent_image_spec.exists());
ASSERT_EQ(0, parent_overlap_get(&ioctx, oid, CEPH_NOSNAP, &parent_overlap));
ASSERT_EQ(std::nullopt, parent_overlap);
ASSERT_EQ(-EINVAL, parent_attach(&ioctx, oid, parent_image_spec, 0ULL));
ASSERT_EQ(-EINVAL, parent_attach(&ioctx, oid, parent_image_spec, 0ULL, false));
ASSERT_EQ(-ENOENT, parent_detach(&ioctx, oid));
parent_image_spec = {1, "", "parent", 2};
parent_overlap = (33 << 20) + 1;
ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap));
ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
false));
ASSERT_EQ(-EEXIST, parent_attach(&ioctx, oid, parent_image_spec,
*parent_overlap));
*parent_overlap, false));
ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
true));
--(*parent_overlap);
cls::rbd::ParentImageSpec on_disk_parent_image_spec;
@ -925,9 +929,12 @@ TEST_F(TestClsRbd, parents_v2)
// clone across pool namespaces
parent_image_spec.pool_namespace = "ns";
parent_overlap = 31 << 20;
ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap));
ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
false));
ASSERT_EQ(-EEXIST, parent_attach(&ioctx, oid, parent_image_spec,
*parent_overlap));
*parent_overlap, false));
ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
true));
ASSERT_EQ(0, parent_get(&ioctx, oid, &on_disk_parent_image_spec));
ASSERT_EQ(parent_image_spec, on_disk_parent_image_spec);

View File

@ -32,7 +32,7 @@ struct AttachParentRequest<MockTestImageCtx> {
static AttachParentRequest* s_instance;
static AttachParentRequest* create(MockTestImageCtx&,
const cls::rbd::ParentImageSpec& pspec,
uint64_t parent_overlap,
uint64_t parent_overlap, bool reattach,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;

View File

@ -72,7 +72,7 @@ TEST_F(TestMockImageAttachParentRequest, ParentAttachSuccess) {
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
234, &ctx);
234, false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
}
@ -91,7 +91,7 @@ TEST_F(TestMockImageAttachParentRequest, SetParentSuccess) {
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
234, &ctx);
234, false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
}
@ -109,7 +109,7 @@ TEST_F(TestMockImageAttachParentRequest, ParentAttachError) {
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
234, &ctx);
234, false, &ctx);
req->send();
ASSERT_EQ(-EPERM, ctx.wait());
}
@ -128,7 +128,7 @@ TEST_F(TestMockImageAttachParentRequest, SetParentError) {
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
234, &ctx);
234, false, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
}
@ -146,7 +146,7 @@ TEST_F(TestMockImageAttachParentRequest, NamespaceUnsupported) {
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
234, &ctx);
234, false, &ctx);
req->send();
ASSERT_EQ(-EXDEV, ctx.wait());
}

View File

@ -55,7 +55,7 @@ struct AttachParentRequest<MockTestImageCtx> {
static AttachParentRequest* s_instance;
static AttachParentRequest* create(MockTestImageCtx&,
const cls::rbd::ParentImageSpec& pspec,
uint64_t parent_overlap,
uint64_t parent_overlap, bool reattach,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;