}
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);
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);
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,
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);
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 << ", "
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;
}
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) {
}
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;
}
};
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;
}
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());
}
};
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);
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, ""};
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);
}
*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, {},
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,
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,
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);
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);
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);
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);
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);