}
static int do_disk_usage(librbd::RBD &rbd, librados::IoCtx &io_ctx,
- const char *imgname, const char *snapname,
- Formatter *f) {
+ const char *imgname, const char *snapname,
+ const char *from_snapname, Formatter *f) {
std::vector<std::string> names;
int r = rbd.list(io_ctx, names);
if (r == -ENOENT) {
tbl.define_column("USED", TextTable::RIGHT, TextTable::RIGHT);
}
+ uint32_t count = 0;
uint64_t used_size = 0;
uint64_t total_prov = 0;
uint64_t total_used = 0;
continue;
}
+ bool found_from_snap = (from_snapname == nullptr);
std::string last_snap_name;
std::sort(snap_list.begin(), snap_list.end(),
boost::bind(&librbd::snap_info_t::id, _1) <
goto out;
}
- if (imgname == NULL || (snapname != NULL && snap->name == snapname)) {
+ 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, tbl, f,
&used_size);
total_prov += snap->size;
}
total_used += used_size;
+ ++count;
+ }
+
+ if (!found_from_snap && from_snapname != nullptr &&
+ snap->name == from_snapname) {
+ found_from_snap = true;
+ }
+ if (snapname != nullptr && snap->name == snapname) {
+ break;
}
last_snap_name = snap->name;
}
}
total_prov += info.size;
total_used += used_size;
+ ++count;
}
}
f->close_section();
f->flush(std::cout);
} else {
- if (imgname == NULL) {
+ if (count > 1) {
tbl << "<TOTAL>"
<< stringify(si_t(total_prov))
<< stringify(si_t(total_used))
at::add_image_or_snap_spec_options(positional, options,
at::ARGUMENT_MODIFIER_NONE);
at::add_format_options(options);
+ options->add_options()
+ (at::FROM_SNAPSHOT_NAME.c_str(), po::value<std::string>(),
+ "snapshot starting point");
}
int execute(const po::variables_map &vm) {
int r = utils::get_pool_image_snapshot_names(
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
&snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED,
- utils::SPEC_VALIDATION_NONE, false);
+ utils::SPEC_VALIDATION_NONE, vm.count(at::FROM_SNAPSHOT_NAME));
if (r < 0) {
return r;
}
+ std::string from_snap_name;
+ if (vm.count(at::FROM_SNAPSHOT_NAME)) {
+ from_snap_name = vm[at::FROM_SNAPSHOT_NAME].as<std::string>();
+ }
+
at::Format::Formatter formatter;
r = utils::get_formatter(vm, &formatter);
if (r < 0) {
r = do_disk_usage(rbd, io_ctx,
image_name.empty() ? nullptr: image_name.c_str() ,
snap_name.empty() ? nullptr : snap_name.c_str(),
+ from_snap_name.empty() ? nullptr : from_snap_name.c_str(),
formatter.get());
if (r < 0) {
std::cerr << "du failed: " << cpp_strerror(r) << std::endl;