summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage.weil@dreamhost.com>2012-02-23 20:30:44 -0800
committerSage Weil <sage@newdream.net>2012-02-24 11:24:44 -0800
commit91fbc687ebc595aa376e4a378f72af183e8c7e91 (patch)
treecee47e50204f937245ef28dbf21c85ef017e4ec5
parent6c257c4d1244f0c246712bfa401abd559f4d7a8c (diff)
downloadceph-91fbc687ebc595aa376e4a378f72af183e8c7e91.tar.gz
osd: 'pg <pgid> list_missing <json hobject_t offset>'
Dump missing objects in json. If more key is non-zero, user should ask for more by passing the last object as the offset for the next request. Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
-rw-r--r--src/osd/ReplicatedPG.cc52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc
index 6eaf0f25850..929452d9f30 100644
--- a/src/osd/ReplicatedPG.cc
+++ b/src/osd/ReplicatedPG.cc
@@ -41,6 +41,9 @@
#include "common/config.h"
#include "include/compat.h"
+#include "json_spirit/json_spirit_value.h"
+#include "json_spirit/json_spirit_reader.h"
+
#define DOUT_SUBSYS osd
#define DOUT_PREFIX_ARGS this, osd->whoami, get_osdmap()
#undef dout_prefix
@@ -312,6 +315,55 @@ int ReplicatedPG::do_command(vector<string>& cmd, ostream& ss,
mark_all_unfound_lost(mode);
return 0;
}
+ else if (cmd.size() >= 1 && cmd[0] == "list_missing") {
+ JSONFormatter jf(true);
+ hobject_t offset;
+ if (cmd.size() > 1) {
+ json_spirit::Value v;
+ try {
+ if (!json_spirit::read(cmd[1], v))
+ throw std::runtime_error("bad json");
+ offset.decode(v);
+ } catch (std::runtime_error& e) {
+ ss << "error parsing offset: " << e.what();
+ return -EINVAL;
+ }
+ }
+ jf.open_object_section("missing");
+ jf.open_object_section("offset");
+ offset.dump(&jf);
+ jf.close_section();
+ jf.dump_int("num_missing", missing.num_missing());
+ jf.dump_int("num_unfound", get_num_unfound());
+ jf.open_array_section("objects");
+ map<hobject_t,pg_missing_t::item>::iterator p = missing.missing.upper_bound(offset);
+ uint32_t num = 0;
+ set<int> empty;
+ bufferlist bl;
+ while (p != missing.missing.end() && num < 5) {
+ jf.open_object_section("object");
+ jf.open_object_section("oid");
+ p->first.dump(&jf);
+ jf.close_section();
+ p->second.dump(&jf); // have, need keys
+ jf.open_array_section("locations");
+ map<hobject_t,set<int> >::iterator q = missing_loc.find(p->first);
+ if (q != missing_loc.end())
+ for (set<int>::iterator r = q->second.begin(); r != q->second.end(); ++r)
+ jf.dump_int("osd", *r);
+ jf.close_section();
+ jf.close_section();
+ ++p;
+ num++;
+ }
+ jf.close_section();
+ jf.dump_int("more", p != missing.missing.end());
+ jf.close_section();
+ stringstream jss;
+ jf.flush(jss);
+ odata.append(jss);
+ return 0;
+ };
ss << "unknown command " << cmd;
return -EINVAL;