bool up;
} rbd_mirror_image_status_t;
+typedef enum {
+ GROUP_IMAGE_STATE_ATTACHED,
+ GROUP_IMAGE_STATE_INCOMPLETE
+} rbd_group_image_state_t;
+
+typedef struct {
+ char *name;
+ int64_t pool;
+} rbd_group_image_spec_t;
+
+typedef struct {
+ rbd_group_image_spec_t spec;
+ rbd_group_image_state_t state;
+} rbd_group_image_status_t;
+
+typedef struct {
+ char *name;
+ int64_t pool;
+} rbd_group_spec_t;
+
CEPH_RBD_API void rbd_version(int *major, int *minor, int *extra);
/* image options */
CEPH_RBD_API int rbd_update_unwatch(rbd_image_t image, uint64_t handle);
+CEPH_RBD_API int rbd_group_image_add(
+ rados_ioctx_t group_p, const char *group_name,
+ rados_ioctx_t image_p, const char *image_name);
+CEPH_RBD_API int rbd_group_image_remove(
+ rados_ioctx_t group_p, const char *group_name,
+ rados_ioctx_t image_p, const char *image_name);
+CEPH_RBD_API int rbd_group_image_list(
+ rados_ioctx_t group_p, const char *group_name,
+ rbd_group_image_status_t *images,
+ size_t *image_size);
+CEPH_RBD_API int rbd_image_get_group(rados_ioctx_t image_p,
+ const char *image_name,
+ rbd_group_spec_t *group_spec);
+CEPH_RBD_API void rbd_group_spec_cleanup(rbd_group_spec_t *group_spec);
+CEPH_RBD_API void rbd_group_image_status_cleanup(
+ rbd_group_image_status_t *image
+ );
+CEPH_RBD_API void rbd_group_image_status_list_cleanup(
+ rbd_group_image_status_t *images,
+ size_t len);
#ifdef __cplusplus
}
#endif
bool up;
} mirror_image_status_t;
+ typedef rbd_group_image_state_t group_image_state_t;
+
+ typedef struct {
+ std::string name;
+ int64_t pool;
+ group_image_state_t state;
+ } group_image_status_t;
+
+ typedef struct {
+ std::string name;
+ int64_t pool;
+ } group_spec_t;
+
typedef rbd_image_info_t image_info_t;
class CEPH_RBD_API ProgressContext
int group_remove(IoCtx& io_ctx, const char *group_name);
int group_list(IoCtx& io_ctx, std::vector<std::string>& names);
+ int group_image_add(IoCtx& io_ctx, const char *group_name,
+ IoCtx& image_io_ctx, const char *image_name);
+ int group_image_remove(IoCtx& io_ctx, const char *group_name,
+ IoCtx& image_io_ctx, const char *image_name);
+ int group_image_list(IoCtx& io_ctx, const char *group_name,
+ std::vector<group_image_status_t>& images);
+
private:
/* We don't allow assignment or copying */
RBD(const RBD& rhs);
std::string *parent_snapname);
int old_format(uint8_t *old);
int size(uint64_t *size);
+ int get_group(group_spec_t *group_spec);
int features(uint64_t *features);
int update_features(uint64_t features, bool enabled);
int overlap(uint64_t *overlap);
std::string id; // only used for new-format images
parent_info parent_md;
ImageCtx *parent;
+ cls::rbd::GroupSpec group_spec;
uint64_t stripe_unit, stripe_count;
uint64_t flags;
&m_lockers,
&m_exclusive_locked,
&m_lock_tag, &m_snapc,
- &m_parent_md);
+ &m_parent_md,
+ &m_group_spec);
}
if (*result < 0) {
lderr(cct) << "failed to retrieve mutable metadata: "
m_image_ctx.parent_md = m_parent_md;
}
+ m_image_ctx.group_spec = m_group_spec;
+
for (size_t i = 0; i < m_snapc.snaps.size(); ++i) {
std::vector<librados::snap_t>::const_iterator it = std::find(
m_image_ctx.snaps.begin(), m_image_ctx.snaps.end(),
uint64_t m_flags;
std::string m_object_prefix;
parent_info m_parent_md;
+ cls::rbd::GroupSpec m_group_spec;
::SnapContext m_snapc;
std::vector<std::string> m_snap_names;
#include "include/stringify.h"
#include "cls/rbd/cls_rbd.h"
+#include "cls/rbd/cls_rbd_types.h"
#include "cls/rbd/cls_rbd_client.h"
#include "cls/journal/cls_journal_types.h"
#include "cls/journal/cls_journal_client.h"
return -EBUSY;
}
+ cls::rbd::GroupSpec s;
+ r = cls_client::image_get_group(&io_ctx, header_oid, s);
+ if (s.is_valid()) {
+ lderr(cct) << "image is in a consistency group - not removing" << dendl;
+ ictx->owner_lock.put_read();
+ ictx->state->close();
+ return -EMLINK;
+ }
+
trim_image(ictx, 0, prog_ctx);
ictx->parent_lock.get_read();
CephContext *cct((CephContext *)io_ctx.cct());
ldout(cct, 20) << "group_remove " << &io_ctx << " " << group_name << dendl;
+ std::vector<group_image_status_t> images;
+ int r = group_image_list(io_ctx, group_name, images);
+ if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "error listing group images" << dendl;
+ return r;
+ }
+
+ for (auto i : images) {
+ librados::Rados rados(io_ctx);
+ IoCtx image_ioctx;
+ rados.ioctx_create2(i.pool, image_ioctx);
+ r = group_image_remove(io_ctx, group_name, image_ioctx, i.name.c_str());
+ if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "error removing image from a group" << dendl;
+ return r;
+ }
+ }
+
std::string group_id;
- int r = cls_client::dir_get_id(&io_ctx, RBD_GROUP_DIRECTORY,
- std::string(group_name), &group_id);
+ r = cls_client::dir_get_id(&io_ctx, RBD_GROUP_DIRECTORY,
+ std::string(group_name), &group_id);
if (r < 0 && r != -ENOENT) {
lderr(cct) << "error getting id of group" << dendl;
return r;
return 0;
}
+
+ int group_image_add(librados::IoCtx& group_ioctx, const char *group_name,
+ librados::IoCtx& image_ioctx, const char *image_name)
+ {
+ CephContext *cct = (CephContext *)group_ioctx.cct();
+ ldout(cct, 20) << "group_image_add " << &group_ioctx
+ << " group name " << group_name << " image "
+ << &image_ioctx << " name " << image_name << dendl;
+
+ string group_id;
+
+ int r = cls_client::dir_get_id(&group_ioctx, RBD_GROUP_DIRECTORY, group_name, &group_id);
+ if (r < 0) {
+ lderr(cct) << "error reading consistency group id object: "
+ << cpp_strerror(r)
+ << dendl;
+ return r;
+ }
+ string group_header_oid = util::group_header_name(group_id);
+
+
+ ldout(cct, 20) << "adding image to group name " << group_name
+ << " group id " << group_header_oid << dendl;
+
+ string image_id;
+
+ r = cls_client::dir_get_id(&image_ioctx, RBD_DIRECTORY, image_name, &image_id);
+ if (r < 0) {
+ lderr(cct) << "error reading image id object: "
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+
+ string image_header_oid = util::header_name(image_id);
+
+ ldout(cct, 20) << "adding image " << image_name
+ << " image id " << image_header_oid << dendl;
+
+ cls::rbd::GroupImageStatus incomplete_st(image_id, image_ioctx.get_id(),
+ cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE);
+ cls::rbd::GroupImageStatus attached_st(image_id, image_ioctx.get_id(),
+ cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED);
+
+ r = cls_client::group_image_set(&group_ioctx, group_header_oid,
+ incomplete_st);
+
+ cls::rbd::GroupSpec group_spec(group_id, group_ioctx.get_id());
+
+ if (r < 0) {
+ lderr(cct) << "error adding image reference to consistency group: "
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+
+ r = cls_client::image_add_group(&image_ioctx, image_header_oid,
+ group_spec);
+ if (r < 0) {
+ lderr(cct) << "error adding group reference to image: "
+ << cpp_strerror(-r) << dendl;
+ cls::rbd::GroupImageSpec spec(image_id, image_ioctx.get_id());
+ cls_client::group_image_remove(&group_ioctx, group_header_oid, spec);
+ // Ignore errors in the clean up procedure.
+ return r;
+ }
+
+ r = cls_client::group_image_set(&group_ioctx, group_header_oid,
+ attached_st);
+
+ return r;
+ }
+
+ int group_image_remove(librados::IoCtx& group_ioctx, const char *group_name,
+ librados::IoCtx& image_ioctx, const char *image_name)
+ {
+ CephContext *cct = (CephContext *)group_ioctx.cct();
+ ldout(cct, 20) << "group_remove_image " << &group_ioctx
+ << " group name " << group_name << " image "
+ << &image_ioctx << " name " << image_name << dendl;
+
+ string group_id;
+
+ int r = cls_client::dir_get_id(&group_ioctx, RBD_GROUP_DIRECTORY, group_name, &group_id);
+ if (r < 0) {
+ lderr(cct) << "error reading consistency group id object: "
+ << cpp_strerror(r)
+ << dendl;
+ return r;
+ }
+ string group_header_oid = util::group_header_name(group_id);
+
+ ldout(cct, 20) << "adding image to group name " << group_name
+ << " group id " << group_header_oid << dendl;
+
+ string image_id;
+ r = cls_client::dir_get_id(&image_ioctx, RBD_DIRECTORY, image_name, &image_id);
+ if (r < 0) {
+ lderr(cct) << "error reading image id object: "
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+
+ string image_header_oid = util::header_name(image_id);
+
+ ldout(cct, 20) << "removing image " << image_name
+ << " image id " << image_header_oid << dendl;
+
+ cls::rbd::GroupSpec group_spec(group_id, group_ioctx.get_id());
+
+ cls::rbd::GroupImageStatus incomplete_st(image_id, image_ioctx.get_id(),
+ cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE);
+
+ cls::rbd::GroupImageSpec spec(image_id, image_ioctx.get_id());
+
+ r = cls_client::group_image_set(&group_ioctx, group_header_oid,
+ incomplete_st);
+
+ if (r < 0) {
+ lderr(cct) << "couldn't put image into removing state: "
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+
+ r = cls_client::image_remove_group(&image_ioctx, image_header_oid,
+ group_spec);
+ if ((r < 0) && (r != -ENOENT)) {
+ lderr(cct) << "couldn't remove group reference from image"
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+
+ r = cls_client::group_image_remove(&group_ioctx, group_header_oid, spec);
+ if (r < 0) {
+ lderr(cct) << "couldn't remove image from group"
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+
+ return 0;
+ }
+
+ int group_image_list(librados::IoCtx& group_ioctx,
+ const char *group_name,
+ std::vector<group_image_status_t>& images)
+ {
+ CephContext *cct = (CephContext *)group_ioctx.cct();
+ ldout(cct, 20) << "group_image_list " << &group_ioctx
+ << " group name " << group_name << dendl;
+
+ string group_id;
+
+ int r = cls_client::dir_get_id(&group_ioctx, RBD_GROUP_DIRECTORY,
+ group_name, &group_id);
+ if (r < 0) {
+ lderr(cct) << "error reading consistency group id object: "
+ << cpp_strerror(r)
+ << dendl;
+ return r;
+ }
+ string group_header_oid = util::group_header_name(group_id);
+
+ ldout(cct, 20) << "listing images in group name "
+ << group_name << " group id " << group_header_oid << dendl;
+
+ std::vector<cls::rbd::GroupImageStatus> image_ids;
+
+ const int max_read = 1024;
+ do {
+ std::vector<cls::rbd::GroupImageStatus> image_ids_page;
+ cls::rbd::GroupImageSpec start_last;
+
+ r = cls_client::group_image_list(&group_ioctx, group_header_oid,
+ start_last, max_read, image_ids_page);
+
+ if (r < 0) {
+ lderr(cct) << "error reading image list from consistency group: "
+ << cpp_strerror(-r) << dendl;
+ return r;
+ }
+ image_ids.insert(image_ids.end(),
+ image_ids_page.begin(), image_ids_page.end());
+
+ if (image_ids_page.size() > 0)
+ start_last = image_ids_page.rbegin()->spec;
+
+ r = image_ids_page.size();
+ } while (r == max_read);
+
+ for (auto i : image_ids) {
+ librados::Rados rados(group_ioctx);
+ IoCtx ioctx;
+ rados.ioctx_create2(i.spec.pool_id, ioctx);
+ std::string image_name;
+ r = cls_client::dir_get_name(&ioctx, RBD_DIRECTORY,
+ i.spec.image_id, &image_name);
+ if (r < 0) {
+ return r;
+ }
+
+ images.push_back(
+ group_image_status_t {
+ image_name,
+ i.spec.pool_id,
+ static_cast<group_image_state_t>(i.state)});
+ }
+
+ return 0;
+ }
+
+ int image_get_group(ImageCtx *ictx, group_spec_t *group_spec)
+ {
+ int r = ictx->state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ if (-1 != ictx->group_spec.pool_id) {
+ librados::Rados rados(ictx->md_ctx);
+ IoCtx ioctx;
+ rados.ioctx_create2(ictx->group_spec.pool_id, ioctx);
+
+ std::string group_name;
+ r = cls_client::dir_get_name(&ioctx, RBD_GROUP_DIRECTORY,
+ ictx->group_spec.group_id, &group_name);
+ if (r < 0)
+ return r;
+ group_spec->pool = ictx->group_spec.pool_id;
+ group_spec->name = group_name;
+ } else {
+ group_spec->pool = -1;
+ group_spec->name = "";
+ }
+
+ return 0;
+ }
+
+
}
int group_create(librados::IoCtx& io_ctx, const char *imgname);
int group_remove(librados::IoCtx& io_ctx, const char *group_name);
int group_list(librados::IoCtx& io_ctx, std::vector<std::string>& names);
+ int group_image_add(librados::IoCtx& group_ioctx, const char *group_name,
+ librados::IoCtx& image_ioctx, const char *image_name);
+ int group_image_remove(librados::IoCtx& group_ioctx, const char *group_name,
+ librados::IoCtx& image_ioctx, const char *image_name);
+ int group_image_list(librados::IoCtx& group_ioctx, const char *group_name,
+ std::vector<group_image_status_t>& images);
+ int image_get_group(ImageCtx *ictx, group_spec_t *group_spec);
}
#endif
}
};
+void group_image_status_cpp_to_c(const librbd::group_image_status_t &cpp_status,
+ rbd_group_image_status_t *c_status) {
+ c_status->spec.name = strdup(cpp_status.name.c_str());
+ c_status->spec.pool = cpp_status.pool;
+ c_status->state = cpp_status.state;
+}
+
+void group_spec_cpp_to_c(const librbd::group_spec_t &cpp_spec,
+ rbd_group_spec_t *c_spec) {
+ c_spec->name = strdup(cpp_spec.name.c_str());
+ c_spec->pool = cpp_spec.pool;
+}
+
void mirror_image_info_cpp_to_c(const librbd::mirror_image_info_t &cpp_info,
rbd_mirror_image_info_t *c_info) {
c_info->global_id = strdup(cpp_info.global_id.c_str());
return r;
}
+ int RBD::group_image_add(IoCtx& group_ioctx, const char *group_name,
+ IoCtx& image_ioctx, const char *image_name)
+ {
+ TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
+ tracepoint(librbd, group_image_add_enter, group_ioctx.get_pool_name().c_str(),
+ group_ioctx.get_id(), group_name, image_ioctx.get_pool_name().c_str(),
+ image_ioctx.get_id(), image_name);
+ int r = librbd::group_image_add(group_ioctx, group_name, image_ioctx, image_name);
+ tracepoint(librbd, group_image_add_exit, r);
+ return r;
+ }
+
+ int RBD::group_image_remove(IoCtx& group_ioctx, const char *group_name,
+ IoCtx& image_ioctx, const char *image_name)
+ {
+ TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
+ tracepoint(librbd, group_image_remove_enter, group_ioctx.get_pool_name().c_str(),
+ group_ioctx.get_id(), group_name, image_ioctx.get_pool_name().c_str(),
+ image_ioctx.get_id(), image_name);
+ int r = librbd::group_image_remove(group_ioctx, group_name, image_ioctx, image_name);
+ tracepoint(librbd, group_image_remove_exit, r);
+ return r;
+ }
+
+ int RBD::group_image_list(IoCtx& group_ioctx, const char *group_name,
+ std::vector<group_image_status_t>& images)
+ {
+ TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
+ tracepoint(librbd, group_image_list_enter, group_ioctx.get_pool_name().c_str(),
+ group_ioctx.get_id(), group_name);
+ int r = librbd::group_image_list(group_ioctx, group_name, images);
+ tracepoint(librbd, group_image_list_exit, r);
+ return r;
+ }
+
+
RBD::AioCompletion::AioCompletion(void *cb_arg, callback_t complete_cb)
{
pc = reinterpret_cast<void*>(librbd::AioCompletion::create(
return r;
}
+ int Image::get_group(group_spec_t *group_spec)
+ {
+ ImageCtx *ictx = (ImageCtx *)ctx;
+ tracepoint(librbd, image_get_group_enter, ictx->name.c_str());
+ int r = librbd::image_get_group(ictx, group_spec);
+ tracepoint(librbd, image_get_group_exit, r);
+ return r;
+ }
+
int Image::features(uint64_t *features)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, group_list_exit, (int)expected_size);
return (int)expected_size;
}
+
+extern "C" int rbd_group_image_add(
+ rados_ioctx_t group_p, const char *group_name,
+ rados_ioctx_t image_p, const char *image_name)
+{
+ librados::IoCtx group_ioctx;
+ librados::IoCtx image_ioctx;
+
+ librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
+ librados::IoCtx::from_rados_ioctx_t(image_p, image_ioctx);
+
+ TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
+ tracepoint(librbd, group_image_add_enter, group_ioctx.get_pool_name().c_str(),
+ group_ioctx.get_id(), group_name, image_ioctx.get_pool_name().c_str(),
+ image_ioctx.get_id(), image_name);
+
+ int r = librbd::group_image_add(group_ioctx, group_name, image_ioctx, image_name);
+
+ tracepoint(librbd, group_image_add_exit, r);
+ return r;
+}
+
+extern "C" int rbd_group_image_remove(
+ rados_ioctx_t group_p, const char *group_name,
+ rados_ioctx_t image_p, const char *image_name)
+{
+ librados::IoCtx group_ioctx;
+ librados::IoCtx image_ioctx;
+
+ librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
+ librados::IoCtx::from_rados_ioctx_t(image_p, image_ioctx);
+
+ TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
+ tracepoint(librbd, group_image_remove_enter, group_ioctx.get_pool_name().c_str(),
+ group_ioctx.get_id(), group_name, image_ioctx.get_pool_name().c_str(),
+ image_ioctx.get_id(), image_name);
+
+ int r = librbd::group_image_remove(group_ioctx, group_name, image_ioctx, image_name);
+
+ tracepoint(librbd, group_image_remove_exit, r);
+ return r;
+}
+
+extern "C" int rbd_group_image_list(rados_ioctx_t group_p,
+ const char *group_name,
+ rbd_group_image_status_t *images,
+ size_t *image_size)
+{
+ librados::IoCtx group_ioctx;
+ librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
+
+ TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
+ tracepoint(librbd, group_image_list_enter, group_ioctx.get_pool_name().c_str(),
+ group_ioctx.get_id(), group_name);
+
+ std::vector<librbd::group_image_status_t> cpp_images;
+ int r = librbd::group_image_list(group_ioctx, group_name, cpp_images);
+
+ if (r == -ENOENT) {
+ tracepoint(librbd, group_image_list_exit, 0);
+ return 0;
+ }
+
+ if (r < 0) {
+ tracepoint(librbd, group_image_list_exit, r);
+ return r;
+ }
+
+ if (*image_size < cpp_images.size()) {
+ tracepoint(librbd, group_image_list_exit, -ERANGE);
+ return -ERANGE;
+ }
+
+ for (size_t i = 0; i < cpp_images.size(); ++i) {
+ group_image_status_cpp_to_c(cpp_images[i], &images[i]);
+ }
+
+ tracepoint(librbd, group_image_list_exit, r);
+ return r;
+}
+
+extern "C" int rbd_image_get_group(rados_ioctx_t image_p,
+ const char *image_name,
+ rbd_group_spec_t *c_group_spec)
+{
+ librados::IoCtx io_ctx;
+ librados::IoCtx::from_rados_ioctx_t(image_p, io_ctx);
+
+ librbd::ImageCtx *ictx = new librbd::ImageCtx(image_name, "", "", io_ctx, false);
+ int r = ictx->state->open();
+ if (r < 0) {
+ delete ictx;
+ tracepoint(librbd, open_image_exit, r);
+ return r;
+ }
+
+ tracepoint(librbd, image_get_group_enter, ictx->name.c_str());
+ librbd::group_spec_t group_spec;
+ r = librbd::image_get_group(ictx, &group_spec);
+ group_spec_cpp_to_c(group_spec, c_group_spec);
+ tracepoint(librbd, image_get_group_exit, r);
+ ictx->state->close();
+ return r;
+}
+
+extern "C" void rbd_group_spec_cleanup(rbd_group_spec_t *group_spec) {
+ free(group_spec->name);
+}
+
+extern "C" void rbd_group_image_status_cleanup(
+ rbd_group_image_status_t *image) {
+ free(image->spec.name);
+}
+
+extern "C" void rbd_group_image_status_list_cleanup(
+ rbd_group_image_status_t *images,
+ size_t len) {
+ for (size_t i = 0; i < len; ++i) {
+ rbd_group_image_status_cleanup(&images[i]);
+ }
+}
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
.WillOnce(DoDefault());
+ EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
+ exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("image_get_group"), _, _, _))
+ .WillOnce(DoDefault());
EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _))
.WillOnce(DoDefault());
assert(s_instance != nullptr);
return s_instance;
}
-
MockImageCtx(librbd::ImageCtx &image_ctx)
: image_ctx(&image_ctx),
cct(image_ctx.cct),
name(image_ctx.name),
parent_md(image_ctx.parent_md),
format_string(image_ctx.format_string),
+ group_spec(image_ctx.group_spec),
layout(image_ctx.layout),
aio_work_queue(new MockAioImageRequestWQ()),
op_work_queue(new MockContextWQ()),
std::string name;
parent_info parent_md;
char *format_string;
+ cls::rbd::GroupSpec group_spec;
file_layout_t layout;
ASSERT_EQ(0, rbd.group_list(ioctx, groups));
ASSERT_EQ(0U, groups.size());
}
+
+TEST_F(TestLibCG, add_image)
+{
+ librados::IoCtx ioctx;
+ ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+
+ const char *group_name = "mycg";
+ const char *image_name = "myimage";
+ librbd::RBD rbd;
+ ASSERT_EQ(0, rbd.group_create(ioctx, group_name));
+ int order = 14;
+ ASSERT_EQ(0, rbd.create2(ioctx, image_name, 65535,
+ RBD_FEATURE_LAYERING, &order)); // Specified features make image of new format.
+
+ ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx, image_name));
+
+ vector<librbd::group_image_status_t> images;
+ ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, images));
+ ASSERT_EQ(1U, images.size());
+ ASSERT_EQ("myimage", images[0].name);
+ ASSERT_EQ(ioctx.get_id(), images[0].pool);
+
+ ASSERT_EQ(0, rbd.group_image_remove(ioctx, group_name, ioctx, image_name));
+
+ images.clear();
+ ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, images));
+ ASSERT_EQ(0U, images.size());
+}
if (it != image_names.end()) {
printf("found %s\n", expected);
image_names.erase(it);
+ printf("erased %s\n", expected);
} else {
ADD_FAILURE() << "Unable to find image " << expected;
va_end(ap);
ctf_integer(int, retval, retval)
)
)
+
+TRACEPOINT_EVENT(librbd, group_image_add_enter,
+ TP_ARGS(
+ const char*, pool_name,
+ int64_t, id,
+ const char*, group_name,
+ const char*, image_pool_name,
+ int64_t, image_id,
+ const char*, image_name),
+ TP_FIELDS(
+ ctf_string(pool_name, pool_name)
+ ctf_integer(int64_t, id, id)
+ ctf_string(group_name, group_name)
+ ctf_string(image_pool_name, image_pool_name)
+ ctf_integer(int64_t, image_id, image_id)
+ ctf_string(image_name, image_name)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, group_image_add_exit,
+ TP_ARGS(
+ int, retval),
+ TP_FIELDS(
+ ctf_integer(int, retval, retval)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, group_image_remove_enter,
+ TP_ARGS(
+ const char*, pool_name,
+ int64_t, id,
+ const char*, group_name,
+ const char*, image_pool_name,
+ int64_t, image_id,
+ const char*, image_name),
+ TP_FIELDS(
+ ctf_string(pool_name, pool_name)
+ ctf_integer(int64_t, id, id)
+ ctf_string(group_name, group_name)
+ ctf_string(image_pool_name, image_pool_name)
+ ctf_integer(int64_t, image_id, image_id)
+ ctf_string(image_name, image_name)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, group_image_remove_exit,
+ TP_ARGS(
+ int, retval),
+ TP_FIELDS(
+ ctf_integer(int, retval, retval)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, group_image_list_enter,
+ TP_ARGS(
+ const char*, pool_name,
+ int64_t, id,
+ const char*, group_name),
+ TP_FIELDS(
+ ctf_string(pool_name, pool_name)
+ ctf_integer(int64_t, id, id)
+ ctf_string(group_name, group_name)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, group_image_list_exit,
+ TP_ARGS(
+ int, retval),
+ TP_FIELDS(
+ ctf_integer(int, retval, retval)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, image_get_group_enter,
+ TP_ARGS(
+ const char*, image_name),
+ TP_FIELDS(
+ ctf_string(image_name, image_name)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, image_get_group_exit,
+ TP_ARGS(
+ int, retval),
+ TP_FIELDS(
+ ctf_integer(int, retval, retval)
+ )
+)