Merge pull request #17532 from dillaman/wip-21179

rbd: support iterating over metadata items when listing

Reviewed-by: Mykola Golub <mgolub@mirantis.com>
This commit is contained in:
Mykola Golub 2017-09-07 11:31:45 +03:00 committed by GitHub
commit 24ed122735

View File

@ -33,52 +33,66 @@ int get_key(const po::variables_map &vm, std::string *key) {
return 0;
}
const uint32_t MAX_KEYS = 64;
} // anonymous namespace
static int do_metadata_list(librbd::Image& image, Formatter *f)
{
std::map<std::string, bufferlist> pairs;
int r;
TextTable tbl;
r = image.metadata_list("", 0, &pairs);
if (r < 0) {
std::cerr << "failed to list metadata of image : " << cpp_strerror(r)
<< std::endl;
return r;
}
if (f) {
f->open_object_section("metadatas");
} else {
tbl.define_column("Key", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("Value", TextTable::LEFT, TextTable::LEFT);
}
if (!pairs.empty()) {
bool one = (pairs.size() == 1);
if (!f) {
std::cout << "There " << (one ? "is " : "are ") << pairs.size()
<< " metadata" << (one ? "" : "s") << " on this image.\n";
size_t count = 0;
std::string last_key;
bool more_results = true;
while (more_results) {
std::map<std::string, bufferlist> pairs;
r = image.metadata_list(last_key, MAX_KEYS, &pairs);
if (r < 0) {
std::cerr << "failed to list metadata of image : " << cpp_strerror(r)
<< std::endl;
return r;
}
for (std::map<std::string, bufferlist>::iterator it = pairs.begin();
it != pairs.end(); ++it) {
std::string val(it->second.c_str(), it->second.length());
if (f) {
f->dump_string(it->first.c_str(), val.c_str());
} else {
tbl << it->first << val.c_str() << TextTable::endrow;
more_results = (pairs.size() == MAX_KEYS);
if (!pairs.empty()) {
if (count == 0) {
if (f) {
f->open_object_section("metadatas");
} else {
tbl.define_column("Key", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("Value", TextTable::LEFT, TextTable::LEFT);
}
}
last_key = pairs.rbegin()->first;
count += pairs.size();
for (auto kv : pairs) {
std::string val(kv.second.c_str(), kv.second.length());
if (f) {
f->dump_string(kv.first.c_str(), val.c_str());
} else {
tbl << kv.first << val << TextTable::endrow;
}
}
}
if (!f)
std::cout << tbl;
}
if (f) {
f->close_section();
f->flush(std::cout);
if (f == nullptr) {
bool single = (count == 1);
std::cout << "There " << (single ? "is" : "are") << " " << count << " "
<< (single ? "metadatum" : "metadata") << " on this image"
<< (count == 0 ? "." : ":") << std::endl;
}
if (count > 0) {
if (f) {
f->close_section();
f->flush(std::cout);
} else {
std::cout << std::endl << tbl;
}
}
return 0;
}