]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: expand migration spec to include an optional free-form source spec
authorJason Dillaman <dillaman@redhat.com>
Thu, 15 Oct 2020 18:32:15 +0000 (14:32 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 22 Oct 2020 13:40:40 +0000 (09:40 -0400)
This source-spec will include a JSON-encoded structure describing the source
format and protocol for accessing the source image data.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/cls/rbd/cls_rbd_types.cc
src/cls/rbd/cls_rbd_types.h
src/librbd/Types.h
src/librbd/api/Migration.cc
src/librbd/image/RefreshRequest.cc
src/test/cls_rbd/test_cls_rbd.cc
src/test/librbd/io/test_mock_CopyupRequest.cc

index a331b37c23b0832b661e43967be40acf38a8186d..ce424f7c36a1eb296a3b17d9faace3f0e1761b4a 100644 (file)
@@ -1219,7 +1219,12 @@ std::ostream& operator<<(std::ostream& os,
 }
 
 void MigrationSpec::encode(bufferlist& bl) const {
-  ENCODE_START(2, 1, bl);
+  uint8_t min_version = 1;
+  if (!source_spec.empty()) {
+    min_version = 3;
+  }
+
+  ENCODE_START(3, min_version, bl);
   encode(header_type, bl);
   encode(pool_id, bl);
   encode(pool_namespace, bl);
@@ -1232,11 +1237,12 @@ void MigrationSpec::encode(bufferlist& bl) const {
   encode(state, bl);
   encode(state_description, bl);
   encode(static_cast<uint8_t>(mirror_image_mode), bl);
+  encode(source_spec, bl);
   ENCODE_FINISH(bl);
 }
 
 void MigrationSpec::decode(bufferlist::const_iterator& bl) {
-  DECODE_START(2, bl);
+  DECODE_START(3, bl);
   decode(header_type, bl);
   decode(pool_id, bl);
   decode(pool_namespace, bl);
@@ -1253,7 +1259,10 @@ void MigrationSpec::decode(bufferlist::const_iterator& bl) {
     decode(int_mode, bl);
     mirror_image_mode = static_cast<MirrorImageMode>(int_mode);
   }
- DECODE_FINISH(bl);
+  if (struct_v >= 3) {
+    decode(source_spec, bl);
+  }
+  DECODE_FINISH(bl);
 }
 
 std::ostream& operator<<(std::ostream& os,
@@ -1270,10 +1279,15 @@ std::ostream& operator<<(std::ostream& os,
 
 void MigrationSpec::dump(Formatter *f) const {
   f->dump_stream("header_type") << header_type;
-  f->dump_int("pool_id", pool_id);
-  f->dump_string("pool_namespace", pool_namespace);
-  f->dump_string("image_name", image_name);
-  f->dump_string("image_id", image_id);
+  if (header_type == MIGRATION_HEADER_TYPE_SRC ||
+      source_spec.empty()) {
+    f->dump_int("pool_id", pool_id);
+    f->dump_string("pool_namespace", pool_namespace);
+    f->dump_string("image_name", image_name);
+    f->dump_string("image_id", image_id);
+  } else {
+    f->dump_string("source_spec", source_spec);
+  }
   f->dump_stream("snap_seqs") << snap_seqs;
   f->dump_unsigned("overlap", overlap);
   f->dump_bool("mirroring", mirroring);
@@ -1283,20 +1297,29 @@ void MigrationSpec::dump(Formatter *f) const {
 void MigrationSpec::generate_test_instances(std::list<MigrationSpec*> &o) {
   o.push_back(new MigrationSpec());
   o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC, 1, "ns",
-                                "image_name", "image_id", {{1, 2}}, 123, true,
-                                MIRROR_IMAGE_MODE_SNAPSHOT, true,
+                                "image_name", "image_id", "", {{1, 2}}, 123,
+                                true, MIRROR_IMAGE_MODE_SNAPSHOT, true,
+                                MIGRATION_STATE_PREPARED, "description"));
+  o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_DST, -1, "", "", "",
+                                "{\"format\": \"raw\"}", {{1, 2}}, 123,
+                                true, MIRROR_IMAGE_MODE_SNAPSHOT, true,
                                 MIGRATION_STATE_PREPARED, "description"));
 }
 
 std::ostream& operator<<(std::ostream& os,
                          const MigrationSpec& migration_spec) {
   os << "["
-     << "header_type=" << migration_spec.header_type << ", "
-     << "pool_id=" << migration_spec.pool_id << ", "
-     << "pool_namespace=" << migration_spec.pool_namespace << ", "
-     << "image_name=" << migration_spec.image_name << ", "
-     << "image_id=" << migration_spec.image_id << ", "
-     << "snap_seqs=" << migration_spec.snap_seqs << ", "
+     << "header_type=" << migration_spec.header_type << ", ";
+  if (migration_spec.header_type == MIGRATION_HEADER_TYPE_SRC ||
+      migration_spec.source_spec.empty()) {
+    os << "pool_id=" << migration_spec.pool_id << ", "
+       << "pool_namespace=" << migration_spec.pool_namespace << ", "
+       << "image_name=" << migration_spec.image_name << ", "
+       << "image_id=" << migration_spec.image_id << ", ";
+  } else {
+     os << "source_spec=" << migration_spec.source_spec << ", ";
+  }
+  os << "snap_seqs=" << migration_spec.snap_seqs << ", "
      << "overlap=" << migration_spec.overlap << ", "
      << "flatten=" << migration_spec.flatten << ", "
      << "mirroring=" << migration_spec.mirroring << ", "
index c6bfad032c199a2f0acb602cb99fef382bfca46a..3e7ca77fa87c04ade9029a508009a0bf9b342b24 100644 (file)
@@ -950,6 +950,7 @@ struct MigrationSpec {
   std::string pool_namespace;
   std::string image_name;
   std::string image_id;
+  std::string source_spec;
   std::map<uint64_t, uint64_t> snap_seqs;
   uint64_t overlap = 0;
   bool flatten = false;
@@ -962,14 +963,15 @@ struct MigrationSpec {
   }
   MigrationSpec(MigrationHeaderType header_type, int64_t pool_id,
                 const std::string& pool_namespace,
-                const std::string &image_name, const std::string &image_id,
+                const std::string& image_name, const std::string &image_id,
+                const std::string& source_spec,
                 const std::map<uint64_t, uint64_t> &snap_seqs, uint64_t overlap,
                 bool mirroring, MirrorImageMode mirror_image_mode, bool flatten,
                 MigrationState state, const std::string &state_description)
     : header_type(header_type), pool_id(pool_id),
       pool_namespace(pool_namespace), image_name(image_name),
-      image_id(image_id), snap_seqs(snap_seqs), overlap(overlap),
-      flatten(flatten), mirroring(mirroring),
+      image_id(image_id), source_spec(source_spec), snap_seqs(snap_seqs),
+      overlap(overlap), flatten(flatten), mirroring(mirroring),
       mirror_image_mode(mirror_image_mode), state(state),
       state_description(state_description) {
   }
@@ -983,10 +985,11 @@ struct MigrationSpec {
   inline bool operator==(const MigrationSpec& ms) const {
     return header_type == ms.header_type && pool_id == ms.pool_id &&
       pool_namespace == ms.pool_namespace && image_name == ms.image_name &&
-      image_id == ms.image_id && snap_seqs == ms.snap_seqs &&
-      overlap == ms.overlap && flatten == ms.flatten &&
-      mirroring == ms.mirroring && mirror_image_mode == ms.mirror_image_mode &&
-      state == ms.state && state_description == ms.state_description;
+      image_id == ms.image_id && source_spec == ms.source_spec &&
+      snap_seqs == ms.snap_seqs && overlap == ms.overlap &&
+      flatten == ms.flatten && mirroring == ms.mirroring &&
+      mirror_image_mode == ms.mirror_image_mode && state == ms.state &&
+      state_description == ms.state_description;
   }
 };
 
index d6d7abe9acaf32e1cb9c717125a26f9da6678850..f1c7d6c5d1756dda459ec4ffe011853e2398224a 100644 (file)
@@ -115,6 +115,7 @@ struct MigrationInfo {
   std::string pool_namespace;
   std::string image_name;
   std::string image_id;
+  std::string source_spec;
   deep_copy::SnapMap snap_map;
   uint64_t overlap = 0;
   bool flatten = false;
@@ -123,15 +124,16 @@ struct MigrationInfo {
   }
   MigrationInfo(int64_t pool_id, const std::string& pool_namespace,
                 const std::string& image_name, const std::string& image_id,
+                const std::string& source_spec,
                 const deep_copy::SnapMap &snap_map, uint64_t overlap,
                 bool flatten)
     : pool_id(pool_id), pool_namespace(pool_namespace), image_name(image_name),
-      image_id(image_id), snap_map(snap_map), overlap(overlap),
-      flatten(flatten) {
+      image_id(image_id), source_spec(source_spec), snap_map(snap_map),
+      overlap(overlap), flatten(flatten) {
   }
 
   bool empty() const {
-    return pool_id == -1;
+    return (pool_id == -1 && source_spec.empty());
   }
 };
 
index 312cbe2accc97d479479c0e5e61b29a0a35290c2..cec63ce54f09f5cebe70de76e8d7e410f2ca1bfe 100644 (file)
@@ -683,12 +683,12 @@ Migration<I>::Migration(I *src_image_ctx, librados::IoCtx& dst_io_ctx,
     m_mirror_image_mode(mirror_image_mode), m_prog_ctx(prog_ctx),
     m_src_migration_spec(cls::rbd::MIGRATION_HEADER_TYPE_SRC,
                          m_dst_io_ctx.get_id(), m_dst_io_ctx.get_namespace(),
-                         m_dst_image_name, m_dst_image_id, {}, 0, mirroring,
+                         m_dst_image_name, m_dst_image_id, "", {}, 0, mirroring,
                          mirror_image_mode, flatten, state, state_description),
     m_dst_migration_spec(cls::rbd::MIGRATION_HEADER_TYPE_DST,
                          src_image_ctx->md_ctx.get_id(),
                          src_image_ctx->md_ctx.get_namespace(),
-                         m_src_image_ctx->name, m_src_image_ctx->id, {}, 0,
+                         m_src_image_ctx->name, m_src_image_ctx->id, "", {}, 0,
                          mirroring, mirror_image_mode, flatten, state,
                          state_description) {
   m_src_io_ctx.dup(src_image_ctx->md_ctx);
@@ -1369,7 +1369,7 @@ int Migration<I>::create_dst_image() {
 
   m_dst_migration_spec = {cls::rbd::MIGRATION_HEADER_TYPE_DST,
                           m_src_io_ctx.get_id(), m_src_io_ctx.get_namespace(),
-                          m_src_image_name, m_src_image_id, snap_seqs, size,
+                          m_src_image_name, m_src_image_id, "", snap_seqs, size,
                           m_mirroring, m_mirror_image_mode, m_flatten,
                           cls::rbd::MIGRATION_STATE_PREPARING, ""};
 
index ce125e2ce398fb274a12caee137e083985824548..9b7138815af550a666672076173af9aaf1aa1b65 100644 (file)
@@ -1489,9 +1489,17 @@ int RefreshRequest<I>::get_migration_info(ParentImageInfo *parent_md,
     return 0;
   }
 
-  parent_md->spec.pool_id = m_migration_spec.pool_id;
-  parent_md->spec.pool_namespace = m_migration_spec.pool_namespace;
-  parent_md->spec.image_id = m_migration_spec.image_id;
+  if (!m_migration_spec.source_spec.empty()) {
+    // use special pool id just to indicate a parent (migration source image)
+    // exists
+    parent_md->spec.pool_id = std::numeric_limits<int64_t>::max();
+    parent_md->spec.pool_namespace = "";
+    parent_md->spec.image_id = "";
+  } else {
+    parent_md->spec.pool_id = m_migration_spec.pool_id;
+    parent_md->spec.pool_namespace = m_migration_spec.pool_namespace;
+    parent_md->spec.image_id = m_migration_spec.image_id;
+  }
   parent_md->spec.snap_id = CEPH_NOSNAP;
   parent_md->overlap = std::min(m_size, m_migration_spec.overlap);
 
@@ -1521,8 +1529,9 @@ int RefreshRequest<I>::get_migration_info(ParentImageInfo *parent_md,
   }
 
   *migration_info = {m_migration_spec.pool_id, m_migration_spec.pool_namespace,
-                     m_migration_spec.image_name, m_migration_spec.image_id, {},
-                     overlap, m_migration_spec.flatten};
+                     m_migration_spec.image_name, m_migration_spec.image_id,
+                     m_migration_spec.source_spec, {}, overlap,
+                     m_migration_spec.flatten};
   *migration_info_valid = true;
 
   deep_copy::util::compute_snap_map(m_image_ctx.cct, 0, CEPH_NOSNAP, {},
index cb79e064dc404af6f31dbde5e683416b8f82844f..d01e04704ff6424f9229f37de5134fb013244dcf 100644 (file)
@@ -3123,8 +3123,9 @@ TEST_F(TestClsRbd, migration)
   string oid = get_temp_image_name();
   ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1));
 
-  cls::rbd::MigrationSpec migration_spec(cls::rbd::MIGRATION_HEADER_TYPE_DST, 1,
-                                         "name", "ns", "id", {}, 0, false,
+  cls::rbd::MigrationSpec migration_spec(cls::rbd::MIGRATION_HEADER_TYPE_DST,
+                                         -1, "", "", "",
+                                         "{\"format\": \"raw\"}", {}, 0, false,
                                          cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
                                          false,
                                          cls::rbd::MIGRATION_STATE_PREPARING,
@@ -3195,7 +3196,7 @@ TEST_F(TestClsRbd, migration_v1)
   ASSERT_EQ(0, ioctx.write(oid, header, header.length(), 0));
 
   cls::rbd::MigrationSpec migration_spec(cls::rbd::MIGRATION_HEADER_TYPE_DST, 1,
-                                         "name", "ns", "id", {}, 0, false,
+                                         "name", "ns", "id", "", {}, 0, false,
                                          cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
                                          false,
                                          cls::rbd::MIGRATION_STATE_PREPARING,
index 716c27969249f6c8f63f10090c9fa3bebb61c29d..70f1f17fd63aecdcd1d174704730557031eefa59 100644 (file)
@@ -584,7 +584,8 @@ TEST_F(TestMockIoCopyupRequest, DeepCopy) {
 
   MockAbstractObjectWriteRequest mock_write_request;
   MockObjectCopyRequest mock_object_copy_request;
-  mock_image_ctx.migration_info = {1, "", "", "image id", {}, ictx->size, true};
+  mock_image_ctx.migration_info = {1, "", "", "image id", "", {}, ictx->size,
+                                   true};
   expect_is_empty_write_op(mock_write_request, false);
   expect_object_copy(mock_image_ctx, mock_object_copy_request, true, 0);
 
@@ -630,7 +631,7 @@ TEST_F(TestMockIoCopyupRequest, DeepCopyOnRead) {
   InSequence seq;
 
   MockObjectCopyRequest mock_object_copy_request;
-  mock_image_ctx.migration_info = {1, "", "", "image id", {}, ictx->size,
+  mock_image_ctx.migration_info = {1, "", "", "image id", "", {}, ictx->size,
                                    false};
   expect_object_copy(mock_image_ctx, mock_object_copy_request, true, 0);
 
@@ -680,7 +681,7 @@ TEST_F(TestMockIoCopyupRequest, DeepCopyWithPostSnaps) {
 
   MockAbstractObjectWriteRequest mock_write_request;
   MockObjectCopyRequest mock_object_copy_request;
-  mock_image_ctx.migration_info = {1, "", "", "image id",
+  mock_image_ctx.migration_info = {1, "", "", "image id", "",
                                    {{CEPH_NOSNAP, {2, 1}}},
                                    ictx->size, true};
   expect_is_empty_write_op(mock_write_request, false);
@@ -752,7 +753,7 @@ TEST_F(TestMockIoCopyupRequest, DeepCopyWithPreAndPostSnaps) {
 
   MockAbstractObjectWriteRequest mock_write_request;
   MockObjectCopyRequest mock_object_copy_request;
-  mock_image_ctx.migration_info = {1, "", "", "image id",
+  mock_image_ctx.migration_info = {1, "", "", "image id", "",
                                    {{CEPH_NOSNAP, {2, 1}}, {10, {1}}},
                                    ictx->size, true};
   expect_is_empty_write_op(mock_write_request, false);
@@ -1018,7 +1019,8 @@ TEST_F(TestMockIoCopyupRequest, DeepCopyError) {
 
   MockAbstractObjectWriteRequest mock_write_request;
   MockObjectCopyRequest mock_object_copy_request;
-  mock_image_ctx.migration_info = {1, "", "", "image id", {}, ictx->size, true};
+  mock_image_ctx.migration_info = {1, "", "", "image id", "", {}, ictx->size,
+                                   true};
   expect_is_empty_write_op(mock_write_request, false);
   expect_object_copy(mock_image_ctx, mock_object_copy_request, true, -EPERM);