The newer struct includes support for pool namespaces.
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
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);
}
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;
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
#include "common/bit_vector.hpp"
#include "common/snap_types.h"
#include "include/types.h"
-#include "librbd/Types.h"
class Context;
namespace librados {
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,
// 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);
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);
}
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) {
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);
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());
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;
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 "";
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;
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;
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;
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,
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,
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;
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),
}
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;
<< 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,
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);
}
opts.unset(RBD_IMAGE_OPTION_FLATTEN);
}
- ParentSpec parent_spec;
+ cls::rbd::ParentImageSpec parent_spec;
if (flatten > 0) {
parent_spec.pool_id = -1;
} else {
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;
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,
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);
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) {
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;
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),
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();
}
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,
}
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();
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;
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;
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;
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);
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);
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;
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);
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),
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,
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();
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;
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<
}
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();
}
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();
}
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;
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);
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;
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),
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());
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));
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) {
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;
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,
}
static bool is_refresh_required(ImageCtxT &child_image_ctx,
- const ParentInfo &parent_md,
+ const ParentImageInfo &parent_md,
const MigrationInfo &migration_info);
void send();
* @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;
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();
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;
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 ||
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;
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;
}
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 &&
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;
}
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
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;
}
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) {
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);
}
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) {
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;
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
return -ENOENT;
}
- ParentSpec parent_spec;
+ cls::rbd::ParentImageSpec parent_spec;
if (ictx->snap_id == CEPH_NOSNAP) {
parent_spec = ictx->parent_md.spec;
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);
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) {
}
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());
void handle_remove_snap(int r);
void remove_snap_context();
- int scan_for_parents(ParentSpec &pspec);
+ int scan_for_parents(cls::rbd::ParentImageSpec &pspec);
};
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]) {
<< "'" << 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);
}
private:
- ParentSpec m_pspec;
+ cls::rbd::ParentImageSpec m_pspec;
Pool m_pool;
IoCtx m_pool_ioctx;
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();
#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"
using namespace std;
using namespace librbd::cls_client;
-using ::librbd::ParentInfo;
-using ::librbd::ParentSpec;
+using ::librbd::ParentImageInfo;
using ceph::encode;
using ceph::decode;
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));
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));
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
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);
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);
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);
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");
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");
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));
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));
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));
std::string snap_name;
uint64_t snap_size;
uint8_t snap_order;
- ParentInfo parent;
+ ParentImageInfo parent;
uint8_t protection_status;
utime_t snap_timestamp;
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));
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));
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);
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());
}
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());
}
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;
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());
}
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;
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);
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;
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,
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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();
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> >& ,
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,
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;
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)));
}
{
// 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};
{
// 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};
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"));
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"}]},
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;