struct rbd_image *next;
};
struct rbd_image_data {
- struct rbd_image *images;
- void *buf;
+ struct rbd_image *images;
+ rbd_image_spec_t *image_specs;
+ size_t image_spec_count;
};
struct rbd_image_data rbd_image_data;
enumerate_images(struct rbd_image_data *data)
{
struct rbd_image **head = &data->images;
- char *ibuf = NULL;
- size_t ibuf_len = 0;
struct rbd_image *im, *next;
- char *ip;
int ret;
if (*head != NULL) {
im = next;
}
*head = NULL;
- free(data->buf);
- data->buf = NULL;
+ rbd_image_spec_list_cleanup(data->image_specs,
+ data->image_spec_count);
+ free(data->image_specs);
+ data->image_specs = NULL;
+ data->image_spec_count = 0;
}
- ret = rbd_list(ioctx, ibuf, &ibuf_len);
- if (ret == -ERANGE) {
- ceph_assert(ibuf_len > 0);
- ibuf = (char*) malloc(ibuf_len);
- if (!ibuf) {
- simple_err("Failed to get ibuf", -ENOMEM);
- return;
+ while (true) {
+ ret = rbd_list2(ioctx, data->image_specs,
+ &data->image_spec_count);
+ if (ret == -ERANGE) {
+ data->image_specs = static_cast<rbd_image_spec_t *>(
+ realloc(data->image_specs,
+ sizeof(rbd_image_spec_t) * data->image_spec_count));
+ } else if (ret < 0) {
+ simple_err("Failed to list images", ret);
+ } else {
+ break;
}
- } else if (ret < 0) {
- simple_err("Failed to get ibuf_len", ret);
- return;
- }
-
- ret = rbd_list(ioctx, ibuf, &ibuf_len);
- if (ret < 0) {
- simple_err("Failed to populate ibuf", ret);
- free(ibuf);
- return;
}
- ceph_assert(ret == (int)ibuf_len);
fprintf(stderr, "pool %s: ", pool_name);
- for (ip = ibuf; ip < &ibuf[ibuf_len]; ip += strlen(ip) + 1) {
+ for (size_t idx = 0; idx < data->image_spec_count; ++idx) {
if ((mount_image_name == NULL) ||
((strlen(mount_image_name) > 0) &&
- (strcmp(ip, mount_image_name) == 0))) {
- fprintf(stderr, "%s, ", ip);
+ (strcmp(data->image_specs[idx].name, mount_image_name) == 0))) {
+ fprintf(stderr, "%s, ", data->image_specs[idx].name);
im = static_cast<rbd_image*>(malloc(sizeof(*im)));
- im->image_name = ip;
+ im->image_name = data->image_specs[idx].name;
im->next = *head;
*head = im;
}
}
fprintf(stderr, "\n");
- data->buf = ibuf;
}
int
int main(int argc, const char *argv[])
{
+ memset(&rbd_image_data, 0, sizeof(rbd_image_data));
+
// librados will filter out -f/-d options from command-line
std::map<std::string, bool> filter_args = {
{"-f", false},
int
librbd_get_size(struct rbd_ctx *ctx, uint64_t *size)
{
- rbd_image_info_t info;
int ret;
- ret = rbd_stat(ctx->image, &info, sizeof(info));
+ ret = rbd_get_size(ctx->image, size);
if (ret < 0) {
- prt("rbd_stat failed\n");
+ prt("rbd_get_size failed\n");
return ret;
}
- *size = info.size;
-
return 0;
}
static bool rbd_image_has_parent(struct rbd_ctx *ctx)
{
int ret;
+ rbd_linked_image_spec_t parent_image;
+ rbd_snap_spec_t parent_snap;
- ret = rbd_get_parent_info(ctx->image, NULL, 0, NULL, 0, NULL, 0);
- if (ret < 0 && ret != -ENOENT) {
+ ret = rbd_get_parent(ctx->image, &parent_image, &parent_snap);
+ if (ret < 0 && ret != -ENOENT) {
prterrcode("rbd_get_parent_info", ret);
exit(1);
}
+ rbd_linked_image_spec_cleanup(&parent_image);
+ rbd_snap_spec_cleanup(&parent_snap);
return !ret;
}
static int do_disk_usage(librbd::RBD &rbd, librados::IoCtx &io_ctx,
const char *imgname, const char *snapname,
const char *from_snapname, bool exact, Formatter *f) {
- std::vector<std::string> names;
- int r = rbd.list(io_ctx, names);
+ std::vector<librbd::image_spec_t> images;
+ int r = rbd.list2(io_ctx, &images);
if (r == -ENOENT) {
r = 0;
} else if (r < 0) {
uint64_t snap_id = CEPH_NOSNAP;
uint64_t from_id = CEPH_NOSNAP;
bool found = false;
- std::sort(names.begin(), names.end());
- for (std::vector<string>::const_iterator name = names.begin();
- name != names.end(); ++name) {
- if (imgname != NULL && *name != imgname) {
+ for (auto& image_spec : images) {
+ if (imgname != NULL && image_spec.name != imgname) {
continue;
}
found = true;
librbd::Image image;
- r = rbd.open_read_only(io_ctx, image, name->c_str(), NULL);
+ r = rbd.open_read_only(io_ctx, image, image_spec.name.c_str(), NULL);
if (r < 0) {
if (r != -ENOENT) {
- std::cerr << "rbd: error opening " << *name << ": " << cpp_strerror(r)
- << std::endl;
+ std::cerr << "rbd: error opening " << image_spec.name << ": "
+ << cpp_strerror(r) << std::endl;
}
continue;
}
goto out;
}
if ((features & RBD_FEATURE_FAST_DIFF) == 0) {
- std::cerr << "warning: fast-diff map is not enabled for " << *name << ". "
- << "operation may be slow." << std::endl;
+ std::cerr << "warning: fast-diff map is not enabled for "
+ << image_spec.name << ". " << "operation may be slow."
+ << std::endl;
}
librbd::image_info_t info;
std::vector<librbd::snap_info_t> snap_list;
r = image.snap_list(snap_list);
if (r < 0) {
- std::cerr << "rbd: error opening " << *name << " snapshots: "
+ std::cerr << "rbd: error opening " << image_spec.name << " snapshots: "
<< cpp_strerror(r) << std::endl;
continue;
}
for (std::vector<librbd::snap_info_t>::const_iterator snap =
snap_list.begin(); snap != snap_list.end(); ++snap) {
librbd::Image snap_image;
- r = rbd.open_read_only(io_ctx, snap_image, name->c_str(),
+ r = rbd.open_read_only(io_ctx, snap_image, image_spec.name.c_str(),
snap->name.c_str());
if (r < 0) {
- std::cerr << "rbd: error opening snapshot " << *name << "@"
+ std::cerr << "rbd: error opening snapshot " << image_spec.name << "@"
<< snap->name << ": " << cpp_strerror(r) << std::endl;
goto out;
}
if (imgname == nullptr || found_from_snap ||
(found_from_snap && snapname != nullptr && snap->name == snapname)) {
- r = compute_image_disk_usage(*name, snap->name, last_snap_name,
- snap_image, snap->size, exact, tbl, f,
- &used_size);
+ r = compute_image_disk_usage(image_spec.name, snap->name,
+ last_snap_name, snap_image, snap->size,
+ exact, tbl, f, &used_size);
if (r < 0) {
goto out;
}
}
if (snapname == NULL) {
- r = compute_image_disk_usage(*name, "", last_snap_name, image, info.size,
- exact, tbl, f, &used_size);
+ r = compute_image_disk_usage(image_spec.name, "", last_snap_name, image,
+ info.size, exact, tbl, f, &used_size);
if (r < 0) {
goto out;
}
}
f->close_section();
f->flush(std::cout);
- } else if (!names.empty()) {
+ } else if (!images.empty()) {
if (count > 1) {
tbl << "<TOTAL>"
<< stringify(byte_u_t(total_prov))
// use the alphabetical list of image names for pool-level
// mirror image operations
librbd::RBD rbd;
- int r = rbd.list(m_io_ctx, m_image_names);
+ int r = rbd.list2(m_io_ctx, &m_images);
if (r < 0 && r != -ENOENT) {
std::cerr << "rbd: failed to list images within pool" << std::endl;
return r;
}
- for (auto &image_name : m_image_names) {
- auto request = m_factory(image_name);
+ for (auto &image : m_images) {
+ auto request = m_factory(image.name);
request->send();
}
OrderedThrottle m_throttle;
- std::vector<std::string> m_image_names;
+ std::vector<librbd::image_spec_t> m_images;
};
time_str = time_str.substr(0, time_str.length() - 1);
bool has_parent = false;
- std::string pool, image, snap, parent;
- r = im.parent_info(&pool, &image, &snap);
+ std::string parent;
+ librbd::linked_image_spec_t parent_image;
+ librbd::snap_spec_t parent_snap;
+ r = im.get_parent(&parent_image, &parent_snap);
if (r == -ENOENT) {
r = 0;
} else if (r < 0) {
return r;
} else {
- parent = pool + "/" + image + "@" + snap;
+ parent = parent_image.pool_name + "/";
+ if (!parent_image.pool_namespace.empty()) {
+ parent += parent_image.pool_namespace + "/";
+ }
+ parent += parent_image.image_name + "@" + parent_snap.name;
has_parent = true;
}
delete_status(entry.deferment_end_time));
if (has_parent) {
f->open_object_section("parent");
- f->dump_string("pool", pool);
- f->dump_string("image", image);
- f->dump_string("snapshot", snap);
+ f->dump_string("pool", parent_image.pool_name);
+ f->dump_string("pool_namespace", parent_image.pool_namespace);
+ f->dump_string("image", parent_image.image_name);
+ f->dump_string("snapshot", parent_snap.name);
f->close_section();
}
f->close_section();