#include "common/Formatter.h"
#include "common/TextTable.h"
#include <iostream>
+#include <boost/bind.hpp>
#include <boost/program_options.hpp>
#include "global/global_context.h"
{
int r = 0;
librbd::image_info_t info;
- std::string pool, image, snap, parent;
+ std::string parent;
// handle second-nth trips through loop
- r = w->img.parent_info(&pool, &image, &snap);
- if (r < 0 && r != -ENOENT)
+ librbd::linked_image_spec_t parent_image_spec;
+ librbd::snap_spec_t parent_snap_spec;
+ r = w->img.get_parent(&parent_image_spec, &parent_snap_spec);
+ if (r < 0 && r != -ENOENT) {
return r;
+ }
+
bool has_parent = false;
if (r != -ENOENT) {
- parent = pool + "/" + image + "@" + snap;
+ parent = parent_image_spec.pool_name + "/";
+ if (!parent_image_spec.pool_namespace.empty()) {
+ parent += parent_image_spec.pool_namespace + "/";
+ }
+ parent += parent_image_spec.image_name + "@" + parent_snap_spec.name;
has_parent = true;
}
f->dump_unsigned("size", info.size);
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_spec.pool_name);
+ f->dump_string("pool_namespace", parent_image_spec.pool_namespace);
+ f->dump_string("image", parent_image_spec.image_name);
+ f->dump_string("snapshot", parent_snap_spec.name);
f->close_section();
}
f->dump_int("format", old_format ? 1 : 2);
std::vector<librbd::snap_info_t> snaplist;
if (w->img.snap_list(snaplist) >= 0 && !snaplist.empty()) {
+ snaplist.erase(remove_if(snaplist.begin(),
+ snaplist.end(),
+ boost::bind(utils::is_not_user_snap_namespace, &w->img, _1)),
+ snaplist.end());
for (std::vector<librbd::snap_info_t>::iterator s = snaplist.begin();
s != snaplist.end(); ++s) {
bool is_protected;
r = w->img.snap_is_protected(s->name.c_str(), &is_protected);
if (r < 0)
return r;
- if (w->img.parent_info(&pool, &image, &snap) >= 0) {
- parent = pool + "/" + image + "@" + snap;
+ if (w->img.get_parent(&parent_image_spec, &parent_snap_spec) >= 0) {
+ parent = parent_image_spec.pool_name + "/";
+ if (!parent_image_spec.pool_namespace.empty()) {
+ parent += parent_image_spec.pool_namespace + "/";
+ }
+ parent += parent_image_spec.image_name + "@" + parent_snap_spec.name;
has_parent = true;
}
if (f) {
f->dump_unsigned("size", s->size);
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_spec.pool_name);
+ f->dump_string("pool_namespace", parent_image_spec.pool_namespace);
+ f->dump_string("image", parent_image_spec.image_name);
+ f->dump_string("snapshot", parent_snap_spec.name);
f->close_section();
}
f->dump_int("format", old_format ? 1 : 2);
}
}
- return r < 0 ? r : 0;
+ return 0;
}
-int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
+int do_list(const std::string &pool_name, const std::string& namespace_name,
+ bool lflag, int threads, Formatter *f) {
std::vector<WorkerEntry*> workers;
- std::vector<std::string> names;
+ std::vector<librbd::image_spec_t> images;
librados::Rados rados;
librbd::RBD rbd;
librados::IoCtx ioctx;
threads = 32;
}
- int r = utils::init(pool_name, &rados, &ioctx);
+ int r = utils::init(pool_name, namespace_name, &rados, &ioctx);
if (r < 0) {
return r;
}
- r = rbd.list(ioctx, names);
+ utils::disable_cache();
+
+ r = rbd.list2(ioctx, &images);
if (r < 0)
return r;
if (!lflag) {
if (f)
f->open_array_section("images");
- for (std::vector<std::string>::const_iterator i = names.begin();
- i != names.end(); ++i) {
+ for (auto& image : images) {
if (f)
- f->dump_string("name", *i);
+ f->dump_string("name", image.name);
else
- std::cout << *i << std::endl;
+ std::cout << image.name << std::endl;
}
if (f) {
f->close_section();
f->open_array_section("images");
} else {
tbl.define_column("NAME", TextTable::LEFT, TextTable::LEFT);
- tbl.define_column("SIZE", TextTable::RIGHT, TextTable::RIGHT);
+ tbl.define_column("SIZE", TextTable::LEFT, TextTable::RIGHT);
tbl.define_column("PARENT", TextTable::LEFT, TextTable::LEFT);
- tbl.define_column("FMT", TextTable::RIGHT, TextTable::RIGHT);
+ tbl.define_column("FMT", TextTable::LEFT, TextTable::RIGHT);
tbl.define_column("PROT", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("LOCK", TextTable::LEFT, TextTable::LEFT);
}
- for (int left = 0; left < std::min(threads, (int)names.size()); left++) {
+ for (size_t left = 0; left < std::min<size_t>(threads, images.size());
+ left++) {
workers.push_back(new WorkerEntry());
}
- auto i = names.begin();
+ auto i = images.begin();
while (true) {
size_t workers_idle = 0;
for (auto comp : workers) {
comp->completion = nullptr;
// we want it to fall through in this case
case STATE_IDLE:
- if (i == names.end()) {
+ if (i == images.end()) {
workers_idle++;
continue;
}
- comp->name = *i;
+ comp->name = i->name;
comp->completion = new librbd::RBD::AioCompletion(nullptr, nullptr);
- r = rbd.aio_open_read_only(ioctx, comp->img, i->c_str(), NULL, comp->completion);
+ r = rbd.aio_open_read_only(ioctx, comp->img, i->name.c_str(), nullptr,
+ comp->completion);
i++;
comp->state = STATE_OPENED;
break;
r = comp->completion->get_return_value();
comp->completion->release();
if (r < 0) {
- if (r != -ENOENT) {
- std::cerr << "rbd: error opening " << *i << ": " << cpp_strerror(r)
- << std::endl;
- }
+ std::cerr << "rbd: error opening " << comp->name << ": "
+ << cpp_strerror(r) << std::endl;
+
// in any event, continue to next image
comp->state = STATE_IDLE;
continue;
}
r = list_process_image(&rados, comp, lflag, f, tbl);
if (r < 0) {
- std::cerr << "rbd: error processing image " << comp->name << ": " << cpp_strerror(r)
- << std::endl;
+ std::cerr << "rbd: error processing image " << comp->name << ": "
+ << cpp_strerror(r) << std::endl;
}
comp->completion = new librbd::RBD::AioCompletion(nullptr, nullptr);
r = comp->img.aio_close(comp->completion);
if (f) {
f->close_section();
f->flush(std::cout);
- } else if (!names.empty()) {
+ } else if (!images.empty()) {
std::cout << tbl;
}
po::options_description *options) {
options->add_options()
("long,l", po::bool_switch(), "long listing format");
- at::add_pool_options(positional, options);
+ at::add_pool_options(positional, options, true);
at::add_format_options(options);
}
-int execute(const po::variables_map &vm) {
+int execute(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ std::string pool_name;
+ std::string namespace_name;
size_t arg_index = 0;
- std::string pool_name = utils::get_pool_name(vm, &arg_index);
+ int r = utils::get_pool_and_namespace_names(vm, true, false, &pool_name,
+ &namespace_name, &arg_index);
+ if (r < 0) {
+ return r;
+ }
at::Format::Formatter formatter;
- int r = utils::get_formatter(vm, &formatter);
+ r = utils::get_formatter(vm, &formatter);
if (r < 0) {
return r;
}
- r = do_list(pool_name, vm["long"].as<bool>(),
- g_conf->get_val<int64_t>("rbd_concurrent_management_ops"),
+ r = do_list(pool_name, namespace_name, vm["long"].as<bool>(),
+ g_conf().get_val<uint64_t>("rbd_concurrent_management_ops"),
formatter.get());
if (r < 0) {
- std::cerr << "rbd: list: " << cpp_strerror(r) << std::endl;
+ std::cerr << "rbd: listing images failed: " << cpp_strerror(r)
+ << std::endl;
return r;
}