1
0
mirror of https://github.com/ceph/ceph synced 2025-04-01 14:51:13 +00:00

librbd: replace librbd::ParentSpec with cls::rbd::ParentImageSpec

The newer struct includes support for pool namespaces.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2018-08-22 14:27:48 -04:00
parent 4c6132b676
commit 625ac30e69
41 changed files with 233 additions and 237 deletions

View File

@ -304,9 +304,11 @@ void get_parent_start(librados::ObjectReadOperation *op, snapid_t snap_id)
op->exec("rbd", "get_parent", bl);
}
int get_parent_finish(bufferlist::const_iterator *it, ParentSpec *pspec,
int get_parent_finish(bufferlist::const_iterator *it,
cls::rbd::ParentImageSpec *pspec,
uint64_t *parent_overlap)
{
*pspec = {};
try {
decode(pspec->pool_id, *it);
decode(pspec->image_id, *it);
@ -319,7 +321,7 @@ int get_parent_finish(bufferlist::const_iterator *it, ParentSpec *pspec,
}
int get_parent(librados::IoCtx *ioctx, const std::string &oid,
snapid_t snap_id, ParentSpec *pspec,
snapid_t snap_id, cls::rbd::ParentImageSpec *pspec,
uint64_t *parent_overlap)
{
librados::ObjectReadOperation op;
@ -336,7 +338,7 @@ int get_parent(librados::IoCtx *ioctx, const std::string &oid,
}
int set_parent(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, uint64_t parent_overlap)
const cls::rbd::ParentImageSpec &pspec, uint64_t parent_overlap)
{
librados::ObjectWriteOperation op;
set_parent(&op, pspec, parent_overlap);
@ -344,7 +346,10 @@ int set_parent(librados::IoCtx *ioctx, const std::string &oid,
}
void set_parent(librados::ObjectWriteOperation *op,
const ParentSpec &pspec, uint64_t parent_overlap) {
const cls::rbd::ParentImageSpec &pspec,
uint64_t parent_overlap) {
assert(pspec.pool_namespace.empty());
bufferlist in_bl;
encode(pspec.pool_id, in_bl);
encode(pspec.image_id, in_bl);
@ -467,7 +472,8 @@ int parent_detach(librados::IoCtx *ioctx, const std::string &oid) {
}
int add_child(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, const std::string &c_imageid)
const cls::rbd::ParentImageSpec &pspec,
const std::string &c_imageid)
{
librados::ObjectWriteOperation op;
add_child(&op, pspec, c_imageid);
@ -475,8 +481,11 @@ int add_child(librados::IoCtx *ioctx, const std::string &oid,
}
void add_child(librados::ObjectWriteOperation *op,
const ParentSpec pspec, const std::string &c_imageid)
const cls::rbd::ParentImageSpec& pspec,
const std::string &c_imageid)
{
assert(pspec.pool_namespace.empty());
bufferlist in;
encode(pspec.pool_id, in);
encode(pspec.image_id, in);
@ -487,8 +496,11 @@ void add_child(librados::ObjectWriteOperation *op,
}
void remove_child(librados::ObjectWriteOperation *op,
const ParentSpec &pspec, const std::string &c_imageid)
const cls::rbd::ParentImageSpec &pspec,
const std::string &c_imageid)
{
assert(pspec.pool_namespace.empty());
bufferlist in;
encode(pspec.pool_id, in);
encode(pspec.image_id, in);
@ -498,7 +510,8 @@ void remove_child(librados::ObjectWriteOperation *op,
}
int remove_child(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, const std::string &c_imageid)
const cls::rbd::ParentImageSpec &pspec,
const std::string &c_imageid)
{
librados::ObjectWriteOperation op;
remove_child(&op, pspec, c_imageid);
@ -506,7 +519,7 @@ int remove_child(librados::IoCtx *ioctx, const std::string &oid,
}
void get_children_start(librados::ObjectReadOperation *op,
const ParentSpec &pspec) {
const cls::rbd::ParentImageSpec &pspec) {
bufferlist in_bl;
encode(pspec.pool_id, in_bl);
encode(pspec.image_id, in_bl);
@ -525,7 +538,7 @@ int get_children_finish(bufferlist::const_iterator *it,
}
int get_children(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, set<string>& children)
const cls::rbd::ParentImageSpec &pspec, set<string>& children)
{
librados::ObjectReadOperation op;
get_children_start(&op, pspec);

View File

@ -9,7 +9,6 @@
#include "common/bit_vector.hpp"
#include "common/snap_types.h"
#include "include/types.h"
#include "librbd/Types.h"
class Context;
namespace librados {
@ -70,7 +69,8 @@ void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id,
uint64_t flags, uint64_t mask);
void op_features_get_start(librados::ObjectReadOperation *op);
int op_features_get_finish(bufferlist::const_iterator *it, uint64_t *op_features);
int op_features_get_finish(bufferlist::const_iterator *it,
uint64_t *op_features);
int op_features_get(librados::IoCtx *ioctx, const std::string &oid,
uint64_t *op_features);
void op_features_set(librados::ObjectWriteOperation *op,
@ -80,15 +80,17 @@ int op_features_set(librados::IoCtx *ioctx, const std::string &oid,
// NOTE: deprecate v1 parent APIs after mimic EOLed
void get_parent_start(librados::ObjectReadOperation *op, snapid_t snap_id);
int get_parent_finish(bufferlist::const_iterator *it, ParentSpec *pspec,
int get_parent_finish(bufferlist::const_iterator *it,
cls::rbd::ParentImageSpec *pspec,
uint64_t *parent_overlap);
int get_parent(librados::IoCtx *ioctx, const std::string &oid,
snapid_t snap_id, ParentSpec *pspec,
snapid_t snap_id, cls::rbd::ParentImageSpec *pspec,
uint64_t *parent_overlap);
int set_parent(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, uint64_t parent_overlap);
const cls::rbd::ParentImageSpec &pspec, uint64_t parent_overlap);
void set_parent(librados::ObjectWriteOperation *op,
const ParentSpec &pspec, uint64_t parent_overlap);
const cls::rbd::ParentImageSpec &pspec,
uint64_t parent_overlap);
int remove_parent(librados::IoCtx *ioctx, const std::string &oid);
void remove_parent(librados::ObjectWriteOperation *op);
@ -118,19 +120,23 @@ void parent_detach(librados::ObjectWriteOperation* op);
int parent_detach(librados::IoCtx *ioctx, const std::string &oid);
int add_child(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, const std::string &c_imageid);
const cls::rbd::ParentImageSpec &pspec,
const std::string &c_imageid);
void add_child(librados::ObjectWriteOperation *op,
const ParentSpec pspec, const std::string &c_imageid);
const cls::rbd::ParentImageSpec& pspec,
const std::string &c_imageid);
void remove_child(librados::ObjectWriteOperation *op,
const ParentSpec &pspec, const std::string &c_imageid);
const cls::rbd::ParentImageSpec &pspec,
const std::string &c_imageid);
int remove_child(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, const std::string &c_imageid);
const cls::rbd::ParentImageSpec &pspec,
const std::string &c_imageid);
void get_children_start(librados::ObjectReadOperation *op,
const ParentSpec &pspec);
const cls::rbd::ParentImageSpec &pspec);
int get_children_finish(bufferlist::const_iterator *it,
std::set<string> *children);
int get_children(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, set<string>& children);
const cls::rbd::ParentImageSpec& pspec, set<string>& children);
void snapshot_get_start(librados::ObjectReadOperation* op,
snapid_t snap_id);

View File

@ -389,7 +389,7 @@ public:
}
int ImageCtx::get_parent_spec(snap_t in_snap_id,
ParentSpec *out_pspec) const
cls::rbd::ParentImageSpec *out_pspec) const
{
const SnapInfo *info = get_snap_info(in_snap_id);
if (info) {
@ -487,8 +487,9 @@ public:
void ImageCtx::add_snap(cls::rbd::SnapshotNamespace in_snap_namespace,
string in_snap_name,
snap_t id, uint64_t in_size,
const ParentInfo &parent, uint8_t protection_status,
uint64_t flags, utime_t timestamp)
const ParentImageInfo &parent,
uint8_t protection_status, uint64_t flags,
utime_t timestamp)
{
ceph_assert(snap_lock.is_wlocked());
snaps.push_back(id);
@ -616,7 +617,7 @@ public:
return 0;
}
const ParentInfo* ImageCtx::get_parent_info(snap_t in_snap_id) const
const ParentImageInfo* ImageCtx::get_parent_info(snap_t in_snap_id) const
{
ceph_assert(snap_lock.is_locked());
ceph_assert(parent_lock.is_locked());
@ -630,7 +631,7 @@ public:
int64_t ImageCtx::get_parent_pool_id(snap_t in_snap_id) const
{
const ParentInfo *info = get_parent_info(in_snap_id);
const auto info = get_parent_info(in_snap_id);
if (info)
return info->spec.pool_id;
return -1;
@ -638,7 +639,7 @@ public:
string ImageCtx::get_parent_image_id(snap_t in_snap_id) const
{
const ParentInfo *info = get_parent_info(in_snap_id);
const auto info = get_parent_info(in_snap_id);
if (info)
return info->spec.image_id;
return "";
@ -646,7 +647,7 @@ public:
uint64_t ImageCtx::get_parent_snap_id(snap_t in_snap_id) const
{
const ParentInfo *info = get_parent_info(in_snap_id);
const auto info = get_parent_info(in_snap_id);
if (info)
return info->spec.snap_id;
return CEPH_NOSNAP;
@ -655,7 +656,7 @@ public:
int ImageCtx::get_parent_overlap(snap_t in_snap_id, uint64_t *overlap) const
{
ceph_assert(snap_lock.is_locked());
const ParentInfo *info = get_parent_info(in_snap_id);
const auto info = get_parent_info(in_snap_id);
if (info) {
*overlap = info->overlap;
return 0;

View File

@ -121,7 +121,7 @@ namespace librbd {
char *format_string;
std::string header_oid;
std::string id; // only used for new-format images
ParentInfo parent_md;
ParentImageInfo parent_md;
ImageCtx *parent;
ImageCtx *child = nullptr;
MigrationInfo migration_info;
@ -267,7 +267,7 @@ namespace librbd {
int get_snap_namespace(librados::snap_t in_snap_id,
cls::rbd::SnapshotNamespace *out_snap_namespace) const;
int get_parent_spec(librados::snap_t in_snap_id,
ParentSpec *pspec) const;
cls::rbd::ParentImageSpec *pspec) const;
int is_snap_protected(librados::snap_t in_snap_id,
bool *is_protected) const;
int is_snap_unprotected(librados::snap_t in_snap_id,
@ -289,7 +289,7 @@ namespace librbd {
void add_snap(cls::rbd::SnapshotNamespace in_snap_namespace,
std::string in_snap_name,
librados::snap_t id,
uint64_t in_size, const ParentInfo &parent,
uint64_t in_size, const ParentImageInfo &parent,
uint8_t protection_status, uint64_t flags, utime_t timestamp);
void rm_snap(cls::rbd::SnapshotNamespace in_snap_namespace,
std::string in_snap_name,
@ -310,7 +310,7 @@ namespace librbd {
bool *flags_set) const;
int update_flags(librados::snap_t in_snap_id, uint64_t flag, bool enabled);
const ParentInfo* get_parent_info(librados::snap_t in_snap_id) const;
const ParentImageInfo* get_parent_info(librados::snap_t in_snap_id) const;
int64_t get_parent_pool_id(librados::snap_t in_snap_id) const;
std::string get_parent_image_id(librados::snap_t in_snap_id) const;
uint64_t get_parent_snap_id(librados::snap_t in_snap_id) const;

View File

@ -57,57 +57,30 @@ enum {
typedef std::map<uint64_t, uint64_t> SnapSeqs;
/** @brief Unique identification of a parent in clone relationship.
* Cloning an image creates a child image that keeps a reference
* to its parent. This allows copy-on-write images. */
struct ParentSpec {
int64_t pool_id;
std::string image_id;
snapid_t snap_id;
ParentSpec() : pool_id(-1), snap_id(CEPH_NOSNAP) {
}
ParentSpec(int64_t pool_id, std::string image_id, snapid_t snap_id)
: pool_id(pool_id), image_id(image_id), snap_id(snap_id) {
}
bool operator==(const ParentSpec &other) {
return ((this->pool_id == other.pool_id) &&
(this->image_id == other.image_id) &&
(this->snap_id == other.snap_id));
}
bool operator!=(const ParentSpec &other) {
return !(*this == other);
}
};
/// Full information about an image's parent.
struct ParentInfo {
struct ParentImageInfo {
/// Identification of the parent.
ParentSpec spec;
cls::rbd::ParentImageSpec spec;
/** @brief Where the portion of data shared with the child image ends.
* Since images can be resized multiple times, the portion of data shared
* with the child image is not necessarily min(parent size, child size).
* If the child image is first shrunk and then enlarged, the common portion
* will be shorter. */
uint64_t overlap;
ParentInfo() : overlap(0) {
}
uint64_t overlap = 0;
};
struct SnapInfo {
std::string name;
cls::rbd::SnapshotNamespace snap_namespace;
uint64_t size;
ParentInfo parent;
ParentImageInfo parent;
uint8_t protection_status;
uint64_t flags;
utime_t timestamp;
SnapInfo(std::string _name,
const cls::rbd::SnapshotNamespace &_snap_namespace,
uint64_t _size, const ParentInfo &_parent,
uint64_t _size, const ParentImageInfo &_parent,
uint8_t _protection_status, uint64_t _flags, utime_t _timestamp)
: name(_name), snap_namespace(_snap_namespace), size(_size),
parent(_parent), protection_status(_protection_status), flags(_flags),

View File

@ -71,7 +71,8 @@ int Image<I>::list_images(librados::IoCtx& io_ctx, ImageNameToIds *images) {
}
template <typename I>
int Image<I>::list_children(I *ictx, const ParentSpec &parent_spec,
int Image<I>::list_children(I *ictx,
const cls::rbd::ParentImageSpec &parent_spec,
PoolImageIds *pool_image_ids)
{
CephContext *cct = ictx->cct;
@ -129,16 +130,19 @@ int Image<I>::list_children(I *ictx, const ParentSpec &parent_spec,
<< dendl;
return r;
}
pool_image_ids->insert({*it, image_ids});
pool_image_ids->insert({
{it->first, it->second, ictx->md_ctx.get_namespace()}, image_ids});
}
// retrieve clone v2 children attached to this snapshot
IoCtx parent_io_ctx;
r = rados.ioctx_create2(parent_spec.pool_id, parent_io_ctx);
ceph_assert(r == 0);
// TODO support clone v2 parent namespaces
parent_io_ctx.set_namespace(ictx->md_ctx.get_namespace());
if (r < 0) {
lderr(cct) << "error accessing parent image pool "
<< parent_spec.pool_id << ": " << cpp_strerror(r) << dendl;
return r;
}
parent_io_ctx.set_namespace(parent_spec.pool_namespace);
cls::rbd::ChildImageSpecs child_images;
r = cls_client::children_list(&parent_io_ctx,
@ -156,12 +160,13 @@ int Image<I>::list_children(I *ictx, const ParentSpec &parent_spec,
ldout(cct, 1) << "pool " << child_image.pool_id << " no longer exists"
<< dendl;
continue;
} else if (r < 0) {
lderr(cct) << "error accessing child image pool "
<< child_image.pool_id << ": " << cpp_strerror(r) << dendl;
}
// TODO support clone v2 child namespaces
io_ctx.set_namespace(ictx->md_ctx.get_namespace());
PoolSpec pool_spec = {child_image.pool_id, io_ctx.get_pool_name()};
PoolSpec pool_spec = {child_image.pool_id, io_ctx.get_pool_name(),
child_image.pool_namespace};
(*pool_image_ids)[pool_spec].insert(child_image.image_id);
}
@ -217,7 +222,7 @@ int Image<I>::deep_copy(I *src, librados::IoCtx& dest_md_ctx,
opts.unset(RBD_IMAGE_OPTION_FLATTEN);
}
ParentSpec parent_spec;
cls::rbd::ParentImageSpec parent_spec;
if (flatten > 0) {
parent_spec.pool_id = -1;
} else {

View File

@ -22,7 +22,7 @@ namespace api {
template <typename ImageCtxT = librbd::ImageCtx>
struct Image {
typedef std::pair<int64_t, std::string> PoolSpec;
typedef std::tuple<int64_t, std::string, std::string> PoolSpec;
typedef std::set<std::string> ImageIds;
typedef std::map<PoolSpec, ImageIds> PoolImageIds;
typedef std::map<std::string, std::string> ImageNameToIds;
@ -32,7 +32,8 @@ struct Image {
static int list_images(librados::IoCtx& io_ctx,
ImageNameToIds *images);
static int list_children(ImageCtxT *ictx, const ParentSpec &parent_spec,
static int list_children(ImageCtxT *ictx,
const cls::rbd::ParentImageSpec &parent_spec,
PoolImageIds *pool_image_ids);
static int deep_copy(ImageCtxT *ictx, librados::IoCtx& dest_md_ctx,

View File

@ -1131,7 +1131,7 @@ int Migration<I>::create_dst_image() {
ldout(m_cct, 10) << dendl;
uint64_t size;
ParentSpec parent_spec;
cls::rbd::ParentImageSpec parent_spec;
{
RWLock::RLocker snap_locker(m_src_image_ctx->snap_lock);
RWLock::RLocker parent_locker(m_src_image_ctx->parent_lock);

View File

@ -273,8 +273,10 @@ int Mirror<I>::image_disable(I *ictx, bool force) {
RWLock::RLocker l(ictx->snap_lock);
map<librados::snap_t, SnapInfo> snap_info = ictx->snap_info;
for (auto &info : snap_info) {
ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, info.first);
map< pair<int64_t, string>, set<string> > image_info;
cls::rbd::ParentImageSpec parent_spec{ictx->md_ctx.get_id(),
ictx->md_ctx.get_namespace(),
ictx->id, info.first};
map< tuple<int64_t, string, string>, set<string> > image_info;
r = Image<I>::list_children(ictx, parent_spec, &image_info);
if (r < 0) {
@ -287,16 +289,14 @@ int Mirror<I>::image_disable(I *ictx, bool force) {
librados::Rados rados(ictx->md_ctx);
for (auto &info: image_info) {
librados::IoCtx ioctx;
r = rados.ioctx_create2(info.first.first, ioctx);
r = rados.ioctx_create2(std::get<0>(info.first), ioctx);
if (r < 0) {
rollback = true;
lderr(cct) << "error accessing child image pool "
<< info.first.second << dendl;
<< std::get<1>(info.first) << dendl;
return r;
}
// TODO support clone v2 child namespaces
ioctx.set_namespace(ictx->md_ctx.get_namespace());
ioctx.set_namespace(std::get<2>(info.first));
for (auto &id_it : info.second) {
cls::rbd::MirrorImage mirror_image_internal;

View File

@ -23,7 +23,7 @@ using librbd::util::create_rados_callback;
template <typename I>
SetHeadRequest<I>::SetHeadRequest(I *image_ctx, uint64_t size,
const librbd::ParentSpec &spec,
const cls::rbd::ParentImageSpec &spec,
uint64_t parent_overlap,
Context *on_finish)
: m_image_ctx(image_ctx), m_size(size), m_parent_spec(spec),
@ -172,10 +172,7 @@ void SetHeadRequest<I>::send_attach_parent() {
finish_op_ctx->complete(0);
});
auto req = image::AttachParentRequest<I>::create(
*m_image_ctx,
{m_parent_spec.pool_id, "", m_parent_spec.image_id,
m_parent_spec.snap_id},
m_parent_overlap, ctx);
*m_image_ctx, m_parent_spec, m_parent_overlap, ctx);
req->send();
}

View File

@ -23,7 +23,7 @@ template <typename ImageCtxT = librbd::ImageCtx>
class SetHeadRequest {
public:
static SetHeadRequest* create(ImageCtxT *image_ctx, uint64_t size,
const librbd::ParentSpec &parent_spec,
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap,
Context *on_finish) {
return new SetHeadRequest(image_ctx, size, parent_spec, parent_overlap,
@ -31,8 +31,8 @@ public:
}
SetHeadRequest(ImageCtxT *image_ctx, uint64_t size,
const librbd::ParentSpec &parent_spec, uint64_t parent_overlap,
Context *on_finish);
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap, Context *on_finish);
void send();
@ -59,7 +59,7 @@ private:
ImageCtxT *m_image_ctx;
uint64_t m_size;
librbd::ParentSpec m_parent_spec;
cls::rbd::ParentImageSpec m_parent_spec;
uint64_t m_parent_overlap;
Context *m_on_finish;

View File

@ -67,7 +67,7 @@ SnapshotCopyRequest<I>::SnapshotCopyRequest(I *src_image_ctx,
template <typename I>
void SnapshotCopyRequest<I>::send() {
librbd::ParentSpec src_parent_spec;
cls::rbd::ParentImageSpec src_parent_spec;
int r = validate_parent(m_src_image_ctx, &src_parent_spec);
if (r < 0) {
lderr(m_cct) << "source image parent spec mismatch" << dendl;
@ -353,7 +353,7 @@ void SnapshotCopyRequest<I>::send_snap_create() {
uint64_t size = snap_info_it->second.size;
m_snap_namespace = snap_info_it->second.snap_namespace;
librbd::ParentSpec parent_spec;
cls::rbd::ParentImageSpec parent_spec;
uint64_t parent_overlap = 0;
if (!m_flatten && snap_info_it->second.parent.spec.pool_id != -1) {
parent_spec = m_dst_parent_spec;
@ -520,7 +520,7 @@ void SnapshotCopyRequest<I>::send_set_head() {
ldout(m_cct, 20) << dendl;
uint64_t size;
ParentSpec parent_spec;
cls::rbd::ParentImageSpec parent_spec;
uint64_t parent_overlap = 0;
{
RWLock::RLocker src_locker(m_src_image_ctx->snap_lock);
@ -621,7 +621,7 @@ void SnapshotCopyRequest<I>::error(int r) {
template <typename I>
int SnapshotCopyRequest<I>::validate_parent(I *image_ctx,
librbd::ParentSpec *spec) {
cls::rbd::ParentImageSpec *spec) {
RWLock::RLocker owner_locker(image_ctx->owner_lock);
RWLock::RLocker snap_locker(image_ctx->snap_lock);

View File

@ -97,7 +97,7 @@ private:
std::string m_snap_name;
cls::rbd::SnapshotNamespace m_snap_namespace;
librbd::ParentSpec m_dst_parent_spec;
cls::rbd::ParentImageSpec m_dst_parent_spec;
Mutex m_lock;
bool m_canceled = false;
@ -124,7 +124,7 @@ private:
void error(int r);
int validate_parent(ImageCtxT *image_ctx, librbd::ParentSpec *spec);
int validate_parent(ImageCtxT *image_ctx, cls::rbd::ParentImageSpec *spec);
Context *start_lock_op();
Context *start_lock_op(RWLock &owner_lock);

View File

@ -27,8 +27,8 @@ template <typename I>
SnapshotCreateRequest<I>::SnapshotCreateRequest(
I *dst_image_ctx, const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size, const librbd::ParentSpec &spec, uint64_t parent_overlap,
Context *on_finish)
uint64_t size, const cls::rbd::ParentImageSpec &spec,
uint64_t parent_overlap, Context *on_finish)
: m_dst_image_ctx(dst_image_ctx), m_snap_name(snap_name),
m_snap_namespace(snap_namespace), m_size(size),
m_parent_spec(spec), m_parent_overlap(parent_overlap),

View File

@ -26,7 +26,7 @@ public:
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::ParentSpec &parent_spec,
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap,
Context *on_finish) {
return new SnapshotCreateRequest(dst_image_ctx, snap_name, snap_namespace, size,
@ -37,7 +37,7 @@ public:
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::ParentSpec &parent_spec,
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap, Context *on_finish);
void send();
@ -67,7 +67,7 @@ private:
std::string m_snap_name;
cls::rbd::SnapshotNamespace m_snap_namespace;
uint64_t m_size;
librbd::ParentSpec m_parent_spec;
cls::rbd::ParentImageSpec m_parent_spec;
uint64_t m_parent_overlap;
Context *m_on_finish;

View File

@ -35,11 +35,7 @@ void AttachParentRequest<I>::attach_parent() {
librbd::cls_client::parent_attach(&op, m_parent_image_spec,
m_parent_overlap);
} else {
librbd::cls_client::set_parent(&op,
{m_parent_image_spec.pool_id,
m_parent_image_spec.image_id,
m_parent_image_spec.snap_id},
m_parent_overlap);
librbd::cls_client::set_parent(&op, m_parent_image_spec, m_parent_overlap);
}
auto aio_comp = create_rados_callback<

View File

@ -148,7 +148,8 @@ void CloneRequest<I>::handle_open_parent(int r) {
}
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};
m_pspec = {m_parent_io_ctx.get_id(), m_parent_io_ctx.get_namespace(),
m_parent_image_id, m_parent_snap_id};
validate_parent();
}
@ -327,8 +328,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.pool_id, "", m_pspec.image_id, m_pspec.snap_id},
m_size, ctx);
*m_imctx, m_pspec, m_size, ctx);
req->send();
}

View File

@ -114,7 +114,7 @@ private:
std::string m_name;
std::string m_id;
ImageOptions m_opts;
ParentSpec m_pspec;
cls::rbd::ParentImageSpec m_pspec;
ImageCtxT *m_imctx;
cls::rbd::MirrorMode m_mirror_mode = cls::rbd::MIRROR_MODE_DISABLED;
const std::string m_non_primary_global_image_id;

View File

@ -69,10 +69,13 @@ void DetachChildRequest<I>::clone_v2_child_detach() {
librados::Rados rados(m_image_ctx.md_ctx);
int r = rados.ioctx_create2(m_parent_spec.pool_id, m_parent_io_ctx);
ceph_assert(r == 0);
// TODO support clone v2 parent namespaces
m_parent_io_ctx.set_namespace(m_image_ctx.md_ctx.get_namespace());
if (r < 0) {
lderr(cct) << "error accessing parent pool: " << cpp_strerror(r)
<< dendl;
finish(r);
return;
}
m_parent_io_ctx.set_namespace(m_parent_spec.pool_namespace);
m_parent_header_name = util::header_name(m_parent_spec.image_id);

View File

@ -68,7 +68,7 @@ private:
Context* m_on_finish;
librados::IoCtx m_parent_io_ctx;
ParentSpec m_parent_spec;
cls::rbd::ParentImageSpec m_parent_spec;
std::string m_parent_header_name;
cls::rbd::SnapshotNamespace m_parent_snap_namespace;

View File

@ -24,7 +24,7 @@ using util::create_context_callback;
template <typename I>
RefreshParentRequest<I>::RefreshParentRequest(
I &child_image_ctx, const ParentInfo &parent_md,
I &child_image_ctx, const ParentImageInfo &parent_md,
const MigrationInfo &migration_info, Context *on_finish)
: m_child_image_ctx(child_image_ctx), m_parent_md(parent_md),
m_migration_info(migration_info), m_on_finish(on_finish),
@ -34,7 +34,7 @@ RefreshParentRequest<I>::RefreshParentRequest(
template <typename I>
bool RefreshParentRequest<I>::is_refresh_required(
I &child_image_ctx, const ParentInfo &parent_md,
I &child_image_ctx, const ParentImageInfo &parent_md,
const MigrationInfo &migration_info) {
ceph_assert(child_image_ctx.snap_lock.is_locked());
ceph_assert(child_image_ctx.parent_lock.is_locked());
@ -44,7 +44,7 @@ bool RefreshParentRequest<I>::is_refresh_required(
template <typename I>
bool RefreshParentRequest<I>::is_close_required(
I &child_image_ctx, const ParentInfo &parent_md,
I &child_image_ctx, const ParentImageInfo &parent_md,
const MigrationInfo &migration_info) {
return (child_image_ctx.parent != nullptr &&
!does_parent_exist(child_image_ctx, parent_md, migration_info));
@ -52,18 +52,20 @@ bool RefreshParentRequest<I>::is_close_required(
template <typename I>
bool RefreshParentRequest<I>::is_open_required(
I &child_image_ctx, const ParentInfo &parent_md,
I &child_image_ctx, const ParentImageInfo &parent_md,
const MigrationInfo &migration_info) {
return (does_parent_exist(child_image_ctx, parent_md, migration_info) &&
(child_image_ctx.parent == nullptr ||
child_image_ctx.parent->md_ctx.get_id() != parent_md.spec.pool_id ||
child_image_ctx.parent->md_ctx.get_namespace() !=
parent_md.spec.pool_namespace ||
child_image_ctx.parent->id != parent_md.spec.image_id ||
child_image_ctx.parent->snap_id != parent_md.spec.snap_id));
}
template <typename I>
bool RefreshParentRequest<I>::does_parent_exist(
I &child_image_ctx, const ParentInfo &parent_md,
I &child_image_ctx, const ParentImageInfo &parent_md,
const MigrationInfo &migration_info) {
if (child_image_ctx.child != nullptr &&
child_image_ctx.child->migration_info.empty() && parent_md.overlap == 0) {
@ -122,9 +124,7 @@ void RefreshParentRequest<I>::send_open_parent() {
send_complete(r);
return;
}
// TODO support clone v2 parent namespaces
parent_io_ctx.set_namespace(m_child_image_ctx.md_ctx.get_namespace());
parent_io_ctx.set_namespace(m_parent_md.spec.pool_namespace);
std::string image_name;
uint64_t flags = 0;

View File

@ -19,7 +19,7 @@ template <typename ImageCtxT = ImageCtx>
class RefreshParentRequest {
public:
static RefreshParentRequest *create(ImageCtxT &child_image_ctx,
const ParentInfo &parent_md,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info,
Context *on_finish) {
return new RefreshParentRequest(child_image_ctx, parent_md, migration_info,
@ -27,7 +27,7 @@ public:
}
static bool is_refresh_required(ImageCtxT &child_image_ctx,
const ParentInfo &parent_md,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info);
void send();
@ -58,11 +58,12 @@ private:
* @endverbatim
*/
RefreshParentRequest(ImageCtxT &child_image_ctx, const ParentInfo &parent_md,
RefreshParentRequest(ImageCtxT &child_image_ctx,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info, Context *on_finish);
ImageCtxT &m_child_image_ctx;
ParentInfo m_parent_md;
ParentImageInfo m_parent_md;
MigrationInfo m_migration_info;
Context *m_on_finish;
@ -72,13 +73,13 @@ private:
int m_error_result;
static bool is_close_required(ImageCtxT &child_image_ctx,
const ParentInfo &parent_md,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info);
static bool is_open_required(ImageCtxT &child_image_ctx,
const ParentInfo &parent_md,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info);
static bool does_parent_exist(ImageCtxT &child_image_ctx,
const ParentInfo &parent_md,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info);
void send_open_parent();

View File

@ -450,16 +450,8 @@ Context *RefreshRequest<I>::handle_v2_get_parent(int *result) {
auto it = m_out_bl.cbegin();
if (!m_legacy_parent) {
cls::rbd::ParentImageSpec parent_image_spec;
if (*result == 0) {
*result = cls_client::parent_get_finish(&it, &parent_image_spec);
m_parent_md.spec = {};
if (*result == 0) {
m_parent_md.spec.pool_id = parent_image_spec.pool_id;
m_parent_md.spec.image_id = parent_image_spec.image_id;
m_parent_md.spec.snap_id = parent_image_spec.snap_id;
}
*result = cls_client::parent_get_finish(&it, &m_parent_md.spec);
}
std::optional<uint64_t> parent_overlap;
@ -765,7 +757,7 @@ void RefreshRequest<I>::send_v2_refresh_parent() {
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
ParentInfo parent_md;
ParentImageInfo parent_md;
MigrationInfo migration_info;
int r = get_parent_info(m_image_ctx.snap_id, &parent_md, &migration_info);
if (!m_skip_open_parent_image && (r < 0 ||
@ -1296,7 +1288,7 @@ void RefreshRequest<I>::apply() {
uint8_t protection_status = m_image_ctx.old_format ?
static_cast<uint8_t>(RBD_PROTECTION_STATUS_UNPROTECTED) :
m_snap_protection[i];
ParentInfo parent;
ParentImageInfo parent;
if (!m_image_ctx.old_format) {
if (!m_image_ctx.migration_info.empty()) {
parent = m_image_ctx.parent_md;
@ -1369,7 +1361,7 @@ void RefreshRequest<I>::apply() {
template <typename I>
int RefreshRequest<I>::get_parent_info(uint64_t snap_id,
ParentInfo *parent_md,
ParentImageInfo *parent_md,
MigrationInfo *migration_info) {
if (get_migration_info(parent_md, migration_info)) {
return 0;
@ -1390,7 +1382,7 @@ int RefreshRequest<I>::get_parent_info(uint64_t snap_id,
}
template <typename I>
bool RefreshRequest<I>::get_migration_info(ParentInfo *parent_md,
bool RefreshRequest<I>::get_migration_info(ParentImageInfo *parent_md,
MigrationInfo *migration_info) {
if (m_migration_spec.header_type != cls::rbd::MIGRATION_HEADER_TYPE_DST ||
(m_migration_spec.state != cls::rbd::MIGRATION_STATE_PREPARED &&

View File

@ -146,13 +146,13 @@ private:
std::map<std::string, bufferlist> m_metadata;
std::string m_object_prefix;
ParentInfo m_parent_md;
ParentImageInfo m_parent_md;
bool m_head_parent_overlap = false;
cls::rbd::GroupSpec m_group_spec;
::SnapContext m_snapc;
std::vector<cls::rbd::SnapshotInfo> m_snap_infos;
std::vector<ParentInfo> m_snap_parents;
std::vector<ParentImageInfo> m_snap_parents;
std::vector<uint8_t> m_snap_protection;
std::vector<uint64_t> m_snap_flags;
@ -242,9 +242,10 @@ private:
}
void apply();
int get_parent_info(uint64_t snap_id, ParentInfo *parent_md,
int get_parent_info(uint64_t snap_id, ParentImageInfo *parent_md,
MigrationInfo *migration_info);
bool get_migration_info(ParentInfo *parent_md, MigrationInfo *migration_info);
bool get_migration_info(ParentImageInfo *parent_md,
MigrationInfo *migration_info);
};
} // namespace image

View File

@ -175,13 +175,13 @@ template <typename I>
Context *SetSnapRequest<I>::send_refresh_parent(int *result) {
CephContext *cct = m_image_ctx.cct;
ParentInfo parent_md;
ParentImageInfo parent_md;
bool refresh_parent;
{
RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
const ParentInfo *parent_info = m_image_ctx.get_parent_info(m_snap_id);
const auto parent_info = m_image_ctx.get_parent_info(m_snap_id);
if (parent_info == nullptr) {
*result = -ENOENT;
lderr(cct) << "failed to retrieve snapshot parent info" << dendl;

View File

@ -573,9 +573,13 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
}
RWLock::RLocker l(ictx->snap_lock);
snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(), snap_name);
ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, snap_id);
map< pair<int64_t, string>, set<string> > image_info;
snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(),
snap_name);
cls::rbd::ParentImageSpec parent_spec{ictx->md_ctx.get_id(),
ictx->md_ctx.get_namespace(),
ictx->id, snap_id};
map< tuple<int64_t, string, string>, set<string> > image_info;
r = api::Image<>::list_children(ictx, parent_spec, &image_info);
if (r < 0) {
@ -589,17 +593,15 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
size_t i = 0;
Rados rados(ictx->md_ctx);
for ( auto &info : image_info){
string pool = info.first.second;
string pool = std::get<1>(info.first);
IoCtx ioctx;
r = rados.ioctx_create2(info.first.first, ioctx);
r = rados.ioctx_create2(std::get<0>(info.first), ioctx);
if (r < 0) {
lderr(cct) << "Error accessing child image pool " << pool
<< dendl;
return r;
}
// TODO support clone v2 child namespaces
ioctx.set_namespace(ictx->md_ctx.get_namespace());
ioctx.set_namespace(std::get<2>(info.first));
for (auto &id_it : info.second) {
ImageCtx *imctx = new ImageCtx("", id_it, nullptr, ioctx, false);
@ -652,8 +654,10 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
}
RWLock::RLocker l(ictx->snap_lock);
ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, ictx->snap_id);
map< pair<int64_t, string>, set<string> > image_info;
cls::rbd::ParentImageSpec parent_spec{ictx->md_ctx.get_id(),
ictx->md_ctx.get_namespace(),
ictx->id, ictx->snap_id};
map< tuple<int64_t, string, string>, set<string> > image_info;
r = api::Image<>::list_children(ictx, parent_spec, &image_info);
if (r < 0) {
@ -663,15 +667,13 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
Rados rados(ictx->md_ctx);
for (auto &info : image_info) {
IoCtx ioctx;
r = rados.ioctx_create2(info.first.first, ioctx);
r = rados.ioctx_create2(std::get<0>(info.first), ioctx);
if (r < 0) {
lderr(cct) << "Error accessing child image pool " << info.first.second
<< dendl;
lderr(cct) << "Error accessing child image pool "
<< std::get<1>(info.first) << dendl;
return r;
}
// TODO support clone v2 child namespaces
ioctx.set_namespace(ictx->md_ctx.get_namespace());
ioctx.set_namespace(std::get<2>(info.first));
for (auto &id_it : info.second) {
string name;
@ -692,12 +694,16 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
trash = true;
} else if (r < 0 && r != -ENOENT) {
lderr(cct) << "Error looking up name for image id " << id_it
<< " in pool " << info.first.second << dendl;
<< " in pool " << std::get<1>(info.first)
<< (std::get<2>(info.first).empty() ?
"" : "/" + std::get<2>(info.first)) << dendl;
return r;
}
// TODO support namespaces
names->push_back(
child_info_t {
info.first.second,
std::get<1>(info.first),
name,
id_it,
trash
@ -1099,7 +1105,7 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
return -ENOENT;
}
ParentSpec parent_spec;
cls::rbd::ParentImageSpec parent_spec;
if (ictx->snap_id == CEPH_NOSNAP) {
parent_spec = ictx->parent_md.spec;

View File

@ -86,7 +86,7 @@ private:
uint64_t m_snap_id;
uint64_t m_size;
ParentInfo m_parent_info;
ParentImageInfo m_parent_info;
void send_suspend_requests();
Context *handle_suspend_requests(int *result);

View File

@ -162,7 +162,7 @@ void SnapshotRemoveRequest<I>::detach_child() {
RWLock::RLocker snap_locker(image_ctx.snap_lock);
RWLock::RLocker parent_locker(image_ctx.parent_lock);
ParentSpec our_pspec;
cls::rbd::ParentImageSpec our_pspec;
int r = image_ctx.get_parent_spec(m_snap_id, &our_pspec);
if (r < 0) {
if (r == -ENOENT) {
@ -338,7 +338,8 @@ void SnapshotRemoveRequest<I>::remove_snap_context() {
}
template <typename I>
int SnapshotRemoveRequest<I>::scan_for_parents(ParentSpec &pspec) {
int SnapshotRemoveRequest<I>::scan_for_parents(
cls::rbd::ParentImageSpec &pspec) {
I &image_ctx = this->m_image_ctx;
ceph_assert(image_ctx.snap_lock.is_locked());
ceph_assert(image_ctx.parent_lock.is_locked());

View File

@ -97,7 +97,7 @@ private:
void handle_remove_snap(int r);
void remove_snap_context();
int scan_for_parents(ParentSpec &pspec);
int scan_for_parents(cls::rbd::ParentImageSpec &pspec);
};

View File

@ -56,7 +56,7 @@ template <typename I>
class C_ScanPoolChildren : public C_AsyncObjectThrottle<I> {
public:
C_ScanPoolChildren(AsyncObjectThrottle<I> &throttle, I *image_ctx,
const ParentSpec &pspec, const Pools &pools,
const cls::rbd::ParentImageSpec &pspec, const Pools &pools,
size_t pool_idx)
: C_AsyncObjectThrottle<I>(throttle, *image_ctx), m_pspec(pspec),
m_pool(pools[pool_idx]) {
@ -97,9 +97,7 @@ public:
<< "'" << dendl;
return r;
}
// TODO support clone v2 child namespaces
m_pool_ioctx.set_namespace(image_ctx.md_ctx.get_namespace());
m_pool_ioctx.set_namespace(m_pspec.pool_namespace);
librados::ObjectReadOperation op;
cls_client::get_children_start(&op, m_pspec);
@ -142,7 +140,7 @@ protected:
}
private:
ParentSpec m_pspec;
cls::rbd::ParentImageSpec m_pspec;
Pool m_pool;
IoCtx m_pool_ioctx;
@ -258,7 +256,9 @@ void SnapshotUnprotectRequest<I>::send_scan_pool_children() {
std::list<Pool> pool_list;
rados.pool_list2(pool_list);
ParentSpec pspec(image_ctx.md_ctx.get_id(), image_ctx.id, m_snap_id);
cls::rbd::ParentImageSpec pspec(image_ctx.md_ctx.get_id(),
image_ctx.md_ctx.get_namespace(),
image_ctx.id, m_snap_id);
Pools pools(pool_list.begin(), pool_list.end());
Context *ctx = this->create_callback_context();

View File

@ -14,6 +14,7 @@
#include "cls/rbd/cls_rbd.h"
#include "cls/rbd/cls_rbd_client.h"
#include "cls/rbd/cls_rbd_types.h"
#include "librbd/Types.h"
#include "gtest/gtest.h"
#include "test/librados/test.h"
@ -24,8 +25,7 @@
using namespace std;
using namespace librbd::cls_client;
using ::librbd::ParentInfo;
using ::librbd::ParentSpec;
using ::librbd::ParentImageInfo;
using ceph::encode;
using ceph::decode;
@ -196,7 +196,7 @@ TEST_F(TestClsRbd, add_remove_child)
snapid_t snapid(10);
string parent_image = "parent_id";
set<string>children;
ParentSpec pspec(ioctx.get_id(), parent_image, snapid);
cls::rbd::ParentImageSpec pspec(ioctx.get_id(), "", parent_image, snapid);
// nonexistent children cannot be listed or removed
ASSERT_EQ(-ENOENT, get_children(&ioctx, oid, pspec, children));
@ -651,7 +651,7 @@ TEST_F(TestClsRbd, parents_v1)
librados::IoCtx ioctx;
ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
ParentSpec pspec;
cls::rbd::ParentImageSpec pspec;
uint64_t size;
ASSERT_EQ(-ENOENT, get_parent(&ioctx, "doesnotexist", CEPH_NOSNAP, &pspec, &size));
@ -665,8 +665,8 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_STREQ("", pspec.image_id.c_str());
ASSERT_EQ(pspec.snap_id, CEPH_NOSNAP);
ASSERT_EQ(size, 0ULL);
pspec = ParentSpec(-1, "parent", 3);
ASSERT_EQ(-ENOEXEC, set_parent(&ioctx, oid, ParentSpec(-1, "parent", 3), 10<<20));
pspec = {-1, "", "parent", 3};
ASSERT_EQ(-ENOEXEC, set_parent(&ioctx, oid, {-1, "", "parent", 3}, 10<<20));
ASSERT_EQ(-ENOEXEC, remove_parent(&ioctx, oid));
// new image will work
@ -679,15 +679,15 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(0, get_parent(&ioctx, oid, 123, &pspec, &size));
ASSERT_EQ(-1, pspec.pool_id);
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(-1, "parent", 3), 10<<20));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(1, "", 3), 10<<20));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(1, "parent", CEPH_NOSNAP), 10<<20));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 0));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, {-1, "", "parent", 3}, 10<<20));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, {1, "", "", 3}, 10<<20));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, {1, "", "parent", CEPH_NOSNAP}, 10<<20));
ASSERT_EQ(-EINVAL, set_parent(&ioctx, oid, {1, "", "parent", 3}, 0));
pspec = ParentSpec(1, "parent", 3);
pspec = {1, "", "parent", 3};
ASSERT_EQ(0, set_parent(&ioctx, oid, pspec, 10<<20));
ASSERT_EQ(-EEXIST, set_parent(&ioctx, oid, pspec, 10<<20));
ASSERT_EQ(-EEXIST, set_parent(&ioctx, oid, ParentSpec(2, "parent", 34), 10<<20));
ASSERT_EQ(-EEXIST, set_parent(&ioctx, oid, {2, "", "parent", 34}, 10<<20));
ASSERT_EQ(0, get_parent(&ioctx, oid, CEPH_NOSNAP, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
@ -700,7 +700,7 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(-1, pspec.pool_id);
// snapshots
ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 10<<20));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 3}, 10<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 10, "snap1"));
ASSERT_EQ(0, get_parent(&ioctx, oid, 10, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
@ -709,7 +709,7 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(size, 10ull<<20);
ASSERT_EQ(0, remove_parent(&ioctx, oid));
ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 5<<20));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 3}, 5<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 11, "snap2"));
ASSERT_EQ(0, get_parent(&ioctx, oid, 10, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
@ -738,7 +738,7 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(-1, pspec.pool_id);
// make sure set_parent takes min of our size and parent's size
ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 1<<20));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 3}, 1<<20));
ASSERT_EQ(0, get_parent(&ioctx, oid, CEPH_NOSNAP, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(pspec.image_id, "parent");
@ -746,7 +746,7 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(size, 1ull<<20);
ASSERT_EQ(0, remove_parent(&ioctx, oid));
ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 100<<20));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 3}, 100<<20));
ASSERT_EQ(0, get_parent(&ioctx, oid, CEPH_NOSNAP, &pspec, &size));
ASSERT_EQ(pspec.pool_id, 1);
ASSERT_EQ(pspec.image_id, "parent");
@ -755,7 +755,7 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(0, remove_parent(&ioctx, oid));
// make sure resize adjust parent overlap
ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 10<<20));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 3}, 10<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 14, "snap4"));
ASSERT_EQ(0, set_size(&ioctx, oid, 3 << 20));
@ -806,7 +806,7 @@ TEST_F(TestClsRbd, parents_v1)
ASSERT_EQ(0, create_image(&ioctx, oid, 33<<20, 22,
RBD_FEATURE_LAYERING | RBD_FEATURE_DEEP_FLATTEN,
"foo.", -1));
ASSERT_EQ(0, set_parent(&ioctx, oid, ParentSpec(1, "parent", 3), 100<<20));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 3}, 100<<20));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 1, "snap1"));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 2, "snap2"));
ASSERT_EQ(0, remove_parent(&ioctx, oid));
@ -931,7 +931,7 @@ TEST_F(TestClsRbd, parents_v2)
ASSERT_EQ(0, parent_detach(&ioctx, oid));
ASSERT_EQ(-ENOENT, parent_detach(&ioctx, oid));
ParentSpec on_disk_parent_spec;
cls::rbd::ParentImageSpec on_disk_parent_spec;
uint64_t legacy_parent_overlap;
ASSERT_EQ(-EXDEV, get_parent(&ioctx, oid, CEPH_NOSNAP, &on_disk_parent_spec,
&legacy_parent_overlap));
@ -965,7 +965,7 @@ TEST_F(TestClsRbd, snapshots)
std::string snap_name;
uint64_t snap_size;
uint8_t snap_order;
ParentInfo parent;
ParentImageInfo parent;
uint8_t protection_status;
utime_t snap_timestamp;
@ -2737,7 +2737,7 @@ TEST_F(TestClsRbd, clone_child)
ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22,
RBD_FEATURE_LAYERING | RBD_FEATURE_DEEP_FLATTEN,
oid, -1));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "parent", 2}, 1));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 2}, 1));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 123, "user_snap1"));
ASSERT_EQ(0, op_features_set(&ioctx, oid, RBD_OPERATION_FEATURE_CLONE_CHILD,
RBD_OPERATION_FEATURE_CLONE_CHILD));
@ -2749,7 +2749,7 @@ TEST_F(TestClsRbd, clone_child)
ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_CLONE_CHILD) == 0ULL);
ASSERT_EQ(0, set_features(&ioctx, oid, 0, RBD_FEATURE_DEEP_FLATTEN));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "parent", 2}, 1));
ASSERT_EQ(0, set_parent(&ioctx, oid, {1, "", "parent", 2}, 1));
ASSERT_EQ(0, snapshot_add(&ioctx, oid, 124, "user_snap2"));
ASSERT_EQ(0, op_features_set(&ioctx, oid, RBD_OPERATION_FEATURE_CLONE_CHILD,
RBD_OPERATION_FEATURE_CLONE_CHILD));

View File

@ -140,7 +140,7 @@ public:
MockSetHeadRequest *create_request(
librbd::MockTestImageCtx &mock_local_image_ctx, uint64_t size,
const librbd::ParentSpec &parent_spec, uint64_t parent_overlap,
const cls::rbd::ParentImageSpec &parent_spec, uint64_t parent_overlap,
Context *on_finish) {
return new MockSetHeadRequest(&mock_local_image_ctx, size, parent_spec,
parent_overlap, on_finish);
@ -230,7 +230,7 @@ TEST_F(TestMockDeepCopySetHeadRequest, RemoveSetParent) {
C_SaferCond ctx;
auto request = create_request(mock_image_ctx, m_image_ctx->size,
{123, "test", 0}, 0, &ctx);
{123, "", "test", 0}, 0, &ctx);
request->send();
ASSERT_EQ(0, ctx.wait());
}
@ -247,7 +247,7 @@ TEST_F(TestMockDeepCopySetHeadRequest, SetParentSpec) {
C_SaferCond ctx;
auto request = create_request(mock_image_ctx, m_image_ctx->size,
{123, "test", 0}, 0, &ctx);
{123, "", "test", 0}, 0, &ctx);
request->send();
ASSERT_EQ(0, ctx.wait());
}
@ -257,7 +257,7 @@ TEST_F(TestMockDeepCopySetHeadRequest, SetParentOverlap) {
librbd::MockExclusiveLock mock_exclusive_lock;
mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
mock_image_ctx.parent_md.spec = {123, "test", 0};
mock_image_ctx.parent_md.spec = {123, "", "test", 0};
mock_image_ctx.parent_md.overlap = m_image_ctx->size;
InSequence seq;
@ -284,7 +284,7 @@ TEST_F(TestMockDeepCopySetHeadRequest, SetParentError) {
C_SaferCond ctx;
auto request = create_request(mock_image_ctx, m_image_ctx->size,
{123, "test", 0}, 0, &ctx);
{123, "", "test", 0}, 0, &ctx);
request->send();
ASSERT_EQ(-ESTALE, ctx.wait());
}

View File

@ -35,7 +35,7 @@ public:
static SetHeadRequest* create(librbd::MockTestImageCtx *image_ctx,
uint64_t size,
const librbd::ParentSpec &parent_spec,
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap, Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
@ -56,7 +56,7 @@ struct SnapshotCreateRequest<librbd::MockTestImageCtx> {
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::ParentSpec &parent_spec,
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap,
Context *on_finish) {
ceph_assert(s_instance != nullptr);

View File

@ -34,7 +34,7 @@ public:
static SetHeadRequest* create(librbd::MockTestImageCtx *image_ctx,
uint64_t size,
const librbd::ParentSpec &parent_spec,
const cls::rbd::ParentImageSpec &parent_spec,
uint64_t parent_overlap, Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
@ -136,7 +136,7 @@ public:
const std::string &snap_name,
const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::ParentSpec &spec,
const cls::rbd::ParentImageSpec &spec,
uint64_t parent_overlap,
Context *on_finish) {
return new MockSnapshotCreateRequest(&mock_local_image_ctx, snap_name, snap_namespace, size,

View File

@ -145,7 +145,7 @@ TEST_F(TestMockImageDetachChildRequest, SuccessV1) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, false);
@ -161,7 +161,7 @@ TEST_F(TestMockImageDetachChildRequest, SuccessV2) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -184,7 +184,7 @@ TEST_F(TestMockImageDetachChildRequest, TrashedSnapshotSuccess) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -210,7 +210,7 @@ TEST_F(TestMockImageDetachChildRequest, TrashedSnapshotInUse) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -233,7 +233,7 @@ TEST_F(TestMockImageDetachChildRequest, TrashedSnapshotSnapshotGetError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -256,7 +256,7 @@ TEST_F(TestMockImageDetachChildRequest, TrashedSnapshotOpenParentError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -281,7 +281,7 @@ TEST_F(TestMockImageDetachChildRequest, TrashedSnapshotRemoveError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -317,7 +317,7 @@ TEST_F(TestMockImageDetachChildRequest, ChildDetachError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, true);
@ -336,7 +336,7 @@ TEST_F(TestMockImageDetachChildRequest, RemoveChildError) {
REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
MockTestImageCtx mock_image_ctx(*image_ctx);
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "parent id", 234};
mock_image_ctx.parent_md.spec = {m_ioctx.get_id(), "", "parent id", 234};
InSequence seq;
expect_test_op_features(mock_image_ctx, false);

View File

@ -40,7 +40,7 @@ template <>
struct RefreshParentRequest<MockRefreshImageCtx> {
static RefreshParentRequest* s_instance;
static RefreshParentRequest* create(MockRefreshImageCtx &mock_image_ctx,
const ParentInfo &parent_md,
const ParentImageInfo &parent_md,
const MigrationInfo &migration_info,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
@ -48,7 +48,7 @@ struct RefreshParentRequest<MockRefreshImageCtx> {
return s_instance;
}
static bool is_refresh_required(MockRefreshImageCtx &mock_image_ctx,
const ParentInfo& parent_md,
const ParentImageInfo& parent_md,
const MigrationInfo &migration_info) {
ceph_assert(s_instance != nullptr);
return s_instance->is_refresh_required();

View File

@ -173,8 +173,8 @@ struct MockImageCtx {
MOCK_CONST_METHOD2(get_snap_namespace, int(librados::snap_t,
cls::rbd::SnapshotNamespace *out_snap_namespace));
MOCK_CONST_METHOD2(get_parent_spec, int(librados::snap_t in_snap_id,
ParentSpec *pspec));
MOCK_CONST_METHOD1(get_parent_info, const ParentInfo*(librados::snap_t));
cls::rbd::ParentImageSpec *pspec));
MOCK_CONST_METHOD1(get_parent_info, const ParentImageInfo*(librados::snap_t));
MOCK_CONST_METHOD2(get_parent_overlap, int(librados::snap_t in_snap_id,
uint64_t *overlap));
MOCK_CONST_METHOD2(prune_parent_extents, uint64_t(vector<pair<uint64_t,uint64_t> >& ,
@ -195,7 +195,7 @@ struct MockImageCtx {
MOCK_METHOD8(add_snap, void(cls::rbd::SnapshotNamespace in_snap_namespace,
std::string in_snap_name,
librados::snap_t id,
uint64_t in_size, const ParentInfo &parent,
uint64_t in_size, const ParentImageInfo &parent,
uint8_t protection_status, uint64_t flags, utime_t timestamp));
MOCK_METHOD3(rm_snap, void(cls::rbd::SnapshotNamespace in_snap_namespace,
std::string in_snap_name,
@ -280,7 +280,7 @@ struct MockImageCtx {
std::string header_oid;
std::string id;
std::string name;
ParentInfo parent_md;
ParentImageInfo parent_md;
MigrationInfo migration_info;
char *format_string;
cls::rbd::GroupSpec group_spec;

View File

@ -129,7 +129,7 @@ public:
if (r < 0) {
expect.WillOnce(Return(r));
} else {
ParentSpec &parent_spec = mock_image_ctx.snap_info.rbegin()->second.parent.spec;
auto &parent_spec = mock_image_ctx.snap_info.rbegin()->second.parent.spec;
expect.WillOnce(DoAll(SetArgPointee<1>(parent_spec),
Return(0)));
}

View File

@ -729,7 +729,7 @@ TEST_F(TestInternal, ResizeCopyup)
{
// hide the parent from the snapshot
RWLock::WLocker snap_locker(ictx2->snap_lock);
ictx2->snap_info.begin()->second.parent = librbd::ParentInfo();
ictx2->snap_info.begin()->second.parent = librbd::ParentImageInfo();
}
librbd::io::ReadResult read_result{&read_bl};
@ -796,7 +796,7 @@ TEST_F(TestInternal, DiscardCopyup)
{
// hide the parent from the snapshot
RWLock::WLocker snap_locker(ictx2->snap_lock);
ictx2->snap_info.begin()->second.parent = librbd::ParentInfo();
ictx2->snap_info.begin()->second.parent = librbd::ParentImageInfo();
}
librbd::io::ReadResult read_result{&read_bl};

View File

@ -800,7 +800,7 @@ TEST_F(TestImageReplayer, MultipleReplayFailures_SingleEpoch) {
ASSERT_EQ(0, ictx->operations->snap_protect(cls::rbd::UserSnapshotNamespace(),
"foo"));
ASSERT_EQ(0, librbd::cls_client::add_child(&ictx->md_ctx, RBD_CHILDREN,
{ictx->md_ctx.get_id(),
{ictx->md_ctx.get_id(), "",
ictx->id,
ictx->snap_ids[{cls::rbd::UserSnapshotNamespace(), "foo"}]},
"dummy child id"));
@ -853,7 +853,7 @@ TEST_F(TestImageReplayer, MultipleReplayFailures_MultiEpoch) {
ASSERT_EQ(0, ictx->operations->snap_protect(cls::rbd::UserSnapshotNamespace(),
"foo"));
ASSERT_EQ(0, librbd::cls_client::add_child(&ictx->md_ctx, RBD_CHILDREN,
{ictx->md_ctx.get_id(),
{ictx->md_ctx.get_id(), "",
ictx->id,
ictx->snap_ids[{cls::rbd::UserSnapshotNamespace(),
"foo"}]},

View File

@ -101,10 +101,10 @@ private:
std::string m_local_parent_mirror_uuid;
Journaler *m_remote_journaler = nullptr;
ImageCtxT *m_remote_parent_image_ctx = nullptr;
librbd::ParentSpec m_remote_parent_spec;
cls::rbd::ParentImageSpec m_remote_parent_spec;
librados::IoCtx m_local_parent_io_ctx;
librbd::ParentSpec m_local_parent_spec;
cls::rbd::ParentImageSpec m_local_parent_spec;
bufferlist m_out_bl;
std::string m_parent_global_image_id;