From 70ae1cbc46ae43c0aaa5c82621b97fd06eb05e01 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 27 Jul 2018 10:44:41 -0400 Subject: [PATCH] librbd: ChildImageSpec now optionally includes child pool namespace It will break version compatibility if used against older OSDs that don't support RBD pool namespace support. Signed-off-by: Jason Dillaman --- src/cls/rbd/cls_rbd_types.cc | 12 +++-- src/cls/rbd/cls_rbd_types.h | 10 +++- src/librbd/image/CloneRequest.cc | 4 +- src/librbd/image/DetachChildRequest.cc | 4 +- src/test/cls_rbd/test_cls_rbd.cc | 49 +++++++++++++++---- .../librbd/image/test_mock_CloneRequest.cc | 3 +- .../image/test_mock_DetachChildRequest.cc | 2 +- 7 files changed, 66 insertions(+), 18 deletions(-) diff --git a/src/cls/rbd/cls_rbd_types.cc b/src/cls/rbd/cls_rbd_types.cc index 24d63d72d8d89..fc733bb6f2231 100644 --- a/src/cls/rbd/cls_rbd_types.cc +++ b/src/cls/rbd/cls_rbd_types.cc @@ -244,27 +244,33 @@ void ParentImageSpec::generate_test_instances(std::list& o) { } void ChildImageSpec::encode(bufferlist &bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); encode(pool_id, bl); encode(image_id, bl); + encode(pool_namespace, bl); ENCODE_FINISH(bl); } void ChildImageSpec::decode(bufferlist::const_iterator &it) { - DECODE_START(1, it); + DECODE_START(2, it); decode(pool_id, it); decode(image_id, it); + if (struct_v >= 2) { + decode(pool_namespace, it); + } DECODE_FINISH(it); } void ChildImageSpec::dump(Formatter *f) const { f->dump_int("pool_id", pool_id); + f->dump_string("pool_namespace", pool_namespace); f->dump_string("image_id", image_id); } void ChildImageSpec::generate_test_instances(std::list &o) { o.push_back(new ChildImageSpec()); - o.push_back(new ChildImageSpec(123, "abc")); + o.push_back(new ChildImageSpec(123, "", "abc")); + o.push_back(new ChildImageSpec(123, "ns", "abc")); } void GroupImageSpec::encode(bufferlist &bl) const { diff --git a/src/cls/rbd/cls_rbd_types.h b/src/cls/rbd/cls_rbd_types.h index 03fe4750f0f3a..60042e6097969 100644 --- a/src/cls/rbd/cls_rbd_types.h +++ b/src/cls/rbd/cls_rbd_types.h @@ -221,11 +221,13 @@ WRITE_CLASS_ENCODER(ParentImageSpec); struct ChildImageSpec { int64_t pool_id = -1; + std::string pool_namespace; std::string image_id; ChildImageSpec() {} - ChildImageSpec(int64_t pool_id, const std::string& image_id) - : pool_id(pool_id), image_id(image_id) { + ChildImageSpec(int64_t pool_id, const std::string& pool_namespace, + const std::string& image_id) + : pool_id(pool_id), pool_namespace(pool_namespace), image_id(image_id) { } void encode(bufferlist &bl) const; @@ -236,12 +238,16 @@ struct ChildImageSpec { inline bool operator==(const ChildImageSpec& rhs) const { return (pool_id == rhs.pool_id && + pool_namespace == rhs.pool_namespace && image_id == rhs.image_id); } inline bool operator<(const ChildImageSpec& rhs) const { if (pool_id != rhs.pool_id) { return pool_id < rhs.pool_id; } + if (pool_namespace != rhs.pool_namespace) { + return pool_namespace < rhs.pool_namespace; + } return image_id < rhs.image_id; } }; diff --git a/src/librbd/image/CloneRequest.cc b/src/librbd/image/CloneRequest.cc index 1889481ba9889..818f2354994a3 100644 --- a/src/librbd/image/CloneRequest.cc +++ b/src/librbd/image/CloneRequest.cc @@ -388,7 +388,9 @@ void CloneRequest::v2_child_attach() { librados::ObjectWriteOperation op; cls_client::child_attach(&op, m_parent_image_ctx->snap_id, - {m_imctx->md_ctx.get_id(), m_imctx->id}); + {m_imctx->md_ctx.get_id(), + m_imctx->md_ctx.get_namespace(), + m_imctx->id}); auto aio_comp = create_rados_callback< CloneRequest, &CloneRequest::handle_v2_child_attach>(this); diff --git a/src/librbd/image/DetachChildRequest.cc b/src/librbd/image/DetachChildRequest.cc index b91cc0d19d04b..d29c575cb5103 100644 --- a/src/librbd/image/DetachChildRequest.cc +++ b/src/librbd/image/DetachChildRequest.cc @@ -63,7 +63,9 @@ void DetachChildRequest::clone_v2_child_detach() { librados::ObjectWriteOperation op; cls_client::child_detach(&op, m_parent_spec.snap_id, - {m_image_ctx.md_ctx.get_id(), m_image_ctx.id}); + {m_image_ctx.md_ctx.get_id(), + m_image_ctx.md_ctx.get_namespace(), + m_image_ctx.id}); librados::Rados rados(m_image_ctx.md_ctx); int r = rados.ioctx_create2(m_parent_spec.pool_id, m_parent_io_ctx); diff --git a/src/test/cls_rbd/test_cls_rbd.cc b/src/test/cls_rbd/test_cls_rbd.cc index c03c4dfd81446..5723988cd2d43 100644 --- a/src/test/cls_rbd/test_cls_rbd.cc +++ b/src/test/cls_rbd/test_cls_rbd.cc @@ -2500,10 +2500,10 @@ TEST_F(TestClsRbd, clone_parent) ASSERT_EQ(-ENOENT, child_detach(&ioctx, oid, 123, {})); ASSERT_EQ(-ENOENT, child_detach(&ioctx, oid, 345, {})); - ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "image1"})); - ASSERT_EQ(-EEXIST, child_attach(&ioctx, oid, 123, {1, "image1"})); - ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "image2"})); - ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {2, "image2"})); + ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "", "image1"})); + ASSERT_EQ(-EEXIST, child_attach(&ioctx, oid, 123, {1, "", "image1"})); + ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "", "image2"})); + ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {2, "", "image2"})); cls::rbd::SnapshotInfo snap; ASSERT_EQ(0, snapshot_get(&ioctx, oid, 123, &snap)); @@ -2529,7 +2529,7 @@ TEST_F(TestClsRbd, clone_parent) ASSERT_EQ(0, children_list(&ioctx, oid, 123, &child_images)); cls::rbd::ChildImageSpecs expected_child_images = { - {1, "image1"}, {1, "image2"}, {2, "image2"}}; + {1, "", "image1"}, {1, "", "image2"}, {2, "", "image2"}}; ASSERT_EQ(expected_child_images, child_images); // move snapshot to the trash @@ -2545,17 +2545,17 @@ TEST_F(TestClsRbd, clone_parent) ASSERT_EQ(0, op_features_get(&ioctx, oid, &op_features)); ASSERT_TRUE((op_features & expected_op_features) == expected_op_features); - expected_child_images = {{1, "image1"}, {2, "image2"}}; - ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {1, "image2"})); + expected_child_images = {{1, "", "image1"}, {2, "", "image2"}}; + ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {1, "", "image2"})); ASSERT_EQ(0, children_list(&ioctx, oid, 123, &child_images)); ASSERT_EQ(expected_child_images, child_images); - ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {2, "image2"})); + ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {2, "", "image2"})); ASSERT_EQ(0, op_features_get(&ioctx, oid, &op_features)); ASSERT_TRUE((op_features & expected_op_features) == expected_op_features); - ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {1, "image1"})); + ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {1, "", "image1"})); ASSERT_EQ(-ENOENT, children_list(&ioctx, oid, 123, &child_images)); ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 234)); @@ -2568,6 +2568,37 @@ TEST_F(TestClsRbd, clone_parent) ASSERT_TRUE((op_features & expected_op_features) == 0); } +TEST_F(TestClsRbd, clone_parent_ns) +{ + librados::IoCtx ioctx; + ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx)); + + string oid = get_temp_image_name(); + ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1)); + ASSERT_EQ(0, snapshot_add(&ioctx, oid, 123, "user_snap")); + + ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "ns1", "image1"})); + ASSERT_EQ(-EEXIST, child_attach(&ioctx, oid, 123, {1, "ns1", "image1"})); + ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "ns2", "image1"})); + + cls::rbd::ChildImageSpecs child_images; + ASSERT_EQ(0, children_list(&ioctx, oid, 123, &child_images)); + + cls::rbd::ChildImageSpecs expected_child_images = { + {1, "ns1", "image1"}, {1, "ns2", "image1"}}; + ASSERT_EQ(expected_child_images, child_images); + + expected_child_images = {{1, "ns1", "image1"}}; + ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {1, "ns2", "image1"})); + ASSERT_EQ(0, children_list(&ioctx, oid, 123, &child_images)); + ASSERT_EQ(expected_child_images, child_images); + + ASSERT_EQ(0, child_detach(&ioctx, oid, 123, {1, "ns1", "image1"})); + ASSERT_EQ(-ENOENT, children_list(&ioctx, oid, 123, &child_images)); + + ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 123)); +} + TEST_F(TestClsRbd, clone_child) { librados::IoCtx ioctx; diff --git a/src/test/librbd/image/test_mock_CloneRequest.cc b/src/test/librbd/image/test_mock_CloneRequest.cc index d892b70dad9bb..94b89265d72e6 100644 --- a/src/test/librbd/image/test_mock_CloneRequest.cc +++ b/src/test/librbd/image/test_mock_CloneRequest.cc @@ -260,7 +260,8 @@ public: void expect_child_attach(MockImageCtx &mock_image_ctx, int r) { bufferlist bl; encode(mock_image_ctx.snap_id, bl); - encode(cls::rbd::ChildImageSpec{m_ioctx.get_id(), mock_image_ctx.id}, bl); + encode(cls::rbd::ChildImageSpec{m_ioctx.get_id(), "", mock_image_ctx.id}, + bl); EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), exec(mock_image_ctx.header_oid, _, StrEq("rbd"), diff --git a/src/test/librbd/image/test_mock_DetachChildRequest.cc b/src/test/librbd/image/test_mock_DetachChildRequest.cc index 2fea0b461f854..58c6378ac1e93 100644 --- a/src/test/librbd/image/test_mock_DetachChildRequest.cc +++ b/src/test/librbd/image/test_mock_DetachChildRequest.cc @@ -81,7 +81,7 @@ public: bufferlist bl; encode(parent_spec.snap_id, bl); - encode(cls::rbd::ChildImageSpec{mock_image_ctx.md_ctx.get_id(), + encode(cls::rbd::ChildImageSpec{mock_image_ctx.md_ctx.get_id(), "", mock_image_ctx.id}, bl); EXPECT_CALL(mock_io_ctx_impl, -- 2.39.5