summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zafman <david.zafman@inktank.com>2013-02-22 20:36:28 -0800
committerDavid Zafman <david.zafman@inktank.com>2013-03-04 23:16:50 -0800
commit818f3d298e2d070451c49b67d2c0150f0ca35960 (patch)
tree8bea8c7546ae88c1c17ee836956f01c14e0a600d
parentdb4ccc0827e4fc4b6755712eee6a3a3a95ac27a0 (diff)
downloadceph-818f3d298e2d070451c49b67d2c0150f0ca35960.tar.gz
Add rados listsnaps command
Signed-off-by: David Zafman <david.zafman@inktank.com>
-rw-r--r--src/rados.cc127
1 files changed, 126 insertions, 1 deletions
diff --git a/src/rados.cc b/src/rados.cc
index bbd3badc082..e4679bea887 100644
--- a/src/rados.cc
+++ b/src/rados.cc
@@ -15,7 +15,7 @@
#include "include/types.h"
#include "include/rados/librados.hpp"
-#include "include/rados/rados_types.h"
+#include "include/rados/rados_types.hpp"
#include "rados_sync.h"
using namespace librados;
@@ -83,6 +83,7 @@ void usage(ostream& out)
" rmsnap <snap-name> remove snap <snap-name>\n"
" rollback <obj-name> <snap-name> roll back object to snap <snap-name>\n"
"\n"
+" listsnaps <obj-name> list the snapshots of this object\n"
" bench <seconds> write|seq|rand [-t concurrent_operations] [--no-cleanup]\n"
" default is 16 concurrent IOs and 4 MB ops\n"
" default is to clean up after write benchmark\n"
@@ -2022,6 +2023,130 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
for (i = lw.begin(); i != lw.end(); i++) {
cout << "watcher=client." << i->watcher_id << " cookie=" << i->cookie << std::endl;
}
+ } else if (strcmp(nargs[0], "listsnaps") == 0) {
+ if (!pool_name || nargs.size() < 2)
+ usage_exit();
+
+ string oid(nargs[1]);
+ snap_set_t ls;
+
+ ret = io_ctx.list_snaps(oid, &ls);
+ if (ret < 0) {
+ cerr << "error listing snap shots " << pool_name << "/" << oid << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
+ return 1;
+ }
+ else
+ ret = 0;
+
+ map<snap_t,string> snamemap;
+ if (formatter || pretty_format) {
+ vector<snap_t> snaps;
+ io_ctx.snap_list(&snaps);
+ for (vector<snap_t>::iterator i = snaps.begin();
+ i != snaps.end(); i++) {
+ string s;
+ if (io_ctx.snap_get_name(*i, &s) < 0)
+ continue;
+ snamemap.insert(pair<snap_t,string>(*i, s));
+ }
+ }
+
+ if (formatter) {
+ formatter->open_object_section("object");
+ formatter->dump_string("name", oid);
+ formatter->open_array_section("clones");
+ } else {
+ cout << oid << ":" << std::endl;
+ cout << "cloneid snaps size overlap" << std::endl;
+ }
+
+ for (std::vector<clone_info_t>::iterator ci = ls.clones.begin();
+ ci != ls.clones.end(); ci++) {
+
+ if (formatter) formatter->open_object_section("clone");
+
+ if (ci->cloneid == clone_info_t::HEAD) {
+ if (formatter)
+ formatter->dump_string("id", "head");
+ else
+ cout << "head";
+ } else {
+ if (formatter)
+ formatter->dump_unsigned("id", ci->cloneid);
+ else
+ cout << ci->cloneid;
+ }
+
+ if (formatter)
+ formatter->open_array_section("snapshots");
+ else
+ cout << "\t";
+
+ if (!formatter && ci->snaps.empty()) {
+ cout << "-";
+ }
+ for (std::vector<snap_t>::const_iterator snapindex = ci->snaps.begin();
+ snapindex != ci->snaps.end(); ++snapindex) {
+
+ map<snap_t,string>::iterator si;
+
+ if (formatter || pretty_format) si = snamemap.find(*snapindex);
+
+ if (formatter) {
+ formatter->open_object_section("snapshot");
+ formatter->dump_unsigned("id", *snapindex);
+ if (si != snamemap.end())
+ formatter->dump_string("name", si->second);
+ formatter->close_section(); //snapshot
+ } else {
+ if (snapindex != ci->snaps.begin()) cout << ",";
+ if (!pretty_format || (si == snamemap.end()))
+ cout << *snapindex;
+ else
+ cout << si->second << "(" << *snapindex << ")";
+ }
+ }
+
+ if (formatter) {
+ formatter->close_section(); //Snapshots
+ formatter->dump_unsigned("size", ci->size);
+ } else {
+ cout << "\t" << ci->size;
+ }
+
+ if (ci->cloneid != clone_info_t::HEAD) {
+ if (formatter)
+ formatter->open_array_section("overlaps");
+ else
+ cout << "\t[";
+
+ for (std::vector< std::pair<uint64_t,uint64_t> >::iterator ovi = ci->overlap.begin();
+ ovi != ci->overlap.end(); ovi++) {
+ if (formatter) {
+ formatter->open_object_section("section");
+ formatter->dump_unsigned("start", ovi->first);
+ formatter->dump_unsigned("length", ovi->second);
+ formatter->close_section(); //section
+ } else {
+ if (ovi != ci->overlap.begin()) cout << ",";
+ cout << ovi->first << "~" << ovi->second;
+ }
+ }
+ if (formatter)
+ formatter->close_section(); //overlaps
+ else
+ cout << "]" << std::endl;
+ }
+ if (formatter) formatter->close_section(); //clone
+ }
+ if (formatter) {
+ formatter->close_section(); //clones
+ formatter->close_section(); //object
+ formatter->flush(cout);
+ } else {
+ cout << std::endl;
+ }
+
} else {
cerr << "unrecognized command " << nargs[0] << std::endl;
usage_exit();