]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools, test: Add ceph-objectstore-tool to operate on the meta collection
authorDavid Zafman <dzafman@redhat.com>
Thu, 4 Jun 2015 17:37:42 +0000 (10:37 -0700)
committerDavid Zafman <dzafman@redhat.com>
Fri, 10 Jul 2015 17:10:43 +0000 (10:10 -0700)
Signed-off-by: David Zafman <dzafman@redhat.com>
src/test/ceph_objectstore_tool.py
src/tools/ceph_objectstore_tool.cc

index 3bb1d342278b712ab4167c581da601a5d1ffb53d..c23206bf4f882b04585260941414d9d3d2841dc3 100755 (executable)
@@ -677,7 +677,7 @@ def main(argv):
     tmpfd.close()
     lines = get_lines(TMPFILE)
     JSONOBJ = sorted(set(lines))
-    (pgid, jsondict) = json.loads(JSONOBJ[0])[0]
+    (pgid, coll, jsondict) = json.loads(JSONOBJ[0])[0]
 
     # retrieve all objects in a given PG
     tmpfd = open(OTHERFILE, "a")
@@ -690,9 +690,9 @@ def main(argv):
     tmpfd.close()
     lines = get_lines(OTHERFILE)
     JSONOBJ = sorted(set(lines))
-    (other_pgid, other_jsondict) = json.loads(JSONOBJ[0])[0]
+    (other_pgid, other_coll, other_jsondict) = json.loads(JSONOBJ[0])[0]
 
-    if pgid != other_pgid or jsondict != other_jsondict:
+    if pgid != other_pgid or jsondict != other_jsondict or coll != other_coll:
         logging.error("the first line of --op list is different "
                       "from the first line of --op list --pgid {pg}".format(pg=pgid))
         ERRORS += 1
@@ -708,9 +708,9 @@ def main(argv):
     tmpfd.close()
     lines = get_lines(OTHERFILE)
     JSONOBJ = sorted(set(lines))
-    (other_pgid, other_jsondict) in json.loads(JSONOBJ[0])[0]
+    (other_pgid, other_coll, other_jsondict) in json.loads(JSONOBJ[0])[0]
 
-    if pgid != other_pgid or jsondict != other_jsondict:
+    if pgid != other_pgid or jsondict != other_jsondict or coll != other_coll:
         logging.error("the first line of --op list is different "
                       "from the first line of --op list --pgid {pg} {object}".format(pg=pgid, object=jsondict['oid']))
         ERRORS += 1
@@ -946,6 +946,48 @@ def main(argv):
                         logging.error("Not all keys found, remaining keys:")
                         print values
 
+    print "Test --op meta-list"
+    tmpfd = open(TMPFILE, "w")
+    cmd = (CFSD_PREFIX + "--op meta-list").format(osd=ONEOSD)
+    logging.debug(cmd)
+    ret = call(cmd, shell=True, stdout=tmpfd)
+    if ret != 0:
+        logging.error("Bad exit status {ret} from --op meta-list request".format(ret=ret))
+        ERRORS += 1
+
+    print "Test get-bytes on meta"
+    tmpfd.close()
+    lines = get_lines(TMPFILE)
+    JSONOBJ = sorted(set(lines))
+    for JSON in JSONOBJ:
+        (pgid, jsondict) = json.loads(JSON)
+        if pgid != "meta":
+            logging.error("pgid incorrect for --op meta-list {pgid}".format(pgid=pgid))
+            ERRORS += 1
+        if jsondict['namespace'] != "":
+            logging.error("namespace non null --op meta-list {ns}".format(ns=jsondict['namespace']))
+            ERRORS += 1
+        logging.info(JSON)
+        try:
+            os.unlink(GETNAME)
+        except:
+            pass
+        cmd = (CFSD_PREFIX + "'{json}' get-bytes {fname}").format(osd=ONEOSD, json=JSON, fname=GETNAME)
+        logging.debug(cmd)
+        ret = call(cmd, shell=True)
+        if ret != 0:
+            logging.error("Bad exit status {ret}".format(ret=ret))
+            ERRORS += 1
+
+    try:
+        os.unlink(GETNAME)
+    except:
+        pass
+    try:
+        os.unlink(TESTNAME)
+    except:
+        pass
+
     print "Test pg info"
     for pg in ALLREPPGS + ALLECPGS:
         for osd in get_osds(pg, OSDDIR):
index 6454b348486682acb94837b4ad0936c8dbe221c6..ee07946496fd6bf717d133980729e06b0e74379e 100644 (file)
@@ -97,22 +97,24 @@ int _action_on_all_objects_in_pg(ObjectStore *store, coll_t coll, action_on_obje
         ++obj) {
       if (obj->is_pgmeta())
        continue;
-      bufferlist attr;
-      r = store->getattr(coll, *obj, OI_ATTR, attr);
-      if (r < 0) {
-       cerr << "Error getting attr on : " << make_pair(coll, *obj) << ", "
-            << cpp_strerror(r) << std::endl;
-       return r;
-      }
       object_info_t oi;
-      bufferlist::iterator bp = attr.begin();
-      try {
-       ::decode(oi, bp);
-      } catch (...) {
-       r = -EINVAL;
-       cerr << "Error getting attr on : " << make_pair(coll, *obj) << ", "
-            << cpp_strerror(r) << std::endl;
-       return r;
+      if (coll != coll_t::meta()) {
+        bufferlist attr;
+        r = store->getattr(coll, *obj, OI_ATTR, attr);
+        if (r < 0) {
+         cerr << "Error getting attr on : " << make_pair(coll, *obj) << ", "
+              << cpp_strerror(r) << std::endl;
+         return r;
+        }
+        bufferlist::iterator bp = attr.begin();
+        try {
+         ::decode(oi, bp);
+        } catch (...) {
+         r = -EINVAL;
+         cerr << "Error getting attr on : " << make_pair(coll, *obj) << ", "
+              << cpp_strerror(r) << std::endl;
+         return r;
+        }
       }
       r = action.call(store, coll, *obj, oi);
       if (r < 0)
@@ -229,8 +231,11 @@ struct pgid_object_list {
         ++i) {
       f->open_array_section("pgid_object");
       spg_t pgid;
-      if (i->first.is_pg(&pgid))
+      bool is_pg = i->first.is_pg(&pgid);
+      if (is_pg)
         f->dump_string("pgid", stringify(pgid));
+      if (!is_pg || !human_readable)
+        f->dump_string("coll", i->first.to_str());
       f->open_object_section("ghobject");
       i->second.dump(f);
       f->close_section();
@@ -1386,6 +1391,18 @@ int do_list(ObjectStore *store, string pgidstr, string object, Formatter *format
   return 0;
 }
 
+int do_meta(ObjectStore *store, string object, Formatter *formatter, bool debug, bool human_readable)
+{
+  int r;
+  lookup_ghobject lookup(object);
+  r = action_on_all_objects_in_exact_pg(store, coll_t::meta(), lookup, debug);
+  if (r)
+    return r;
+  lookup.dump(formatter, human_readable);
+  formatter->flush(cout);
+  return 0;
+}
+
 int do_remove_object(ObjectStore *store, coll_t coll, ghobject_t &ghobj)
 {
   spg_t pg;
@@ -1835,7 +1852,7 @@ int main(int argc, char **argv)
     ("pgid", po::value<string>(&pgidstr),
      "PG id, mandatory for info, log, remove, export, rm-past-intervals")
     ("op", po::value<string>(&op),
-     "Arg is one of [info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super]")
+     "Arg is one of [info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super, meta-list]")
     ("file", po::value<string>(&file),
      "path of file to export or import")
     ("format", po::value<string>(&format)->default_value("json-pretty"),
@@ -1991,7 +2008,7 @@ int main(int argc, char **argv)
   // Special list handling.  Treating pretty_format as human readable,
   // with one object per line and not an enclosing array.
   human_readable = ends_with(format, "-pretty");
-  if (op == "list" && human_readable) {
+  if ((op == "list" || op == "meta-list") && human_readable) {
     // Remove -pretty from end of format which we know is there
     format = format.substr(0, format.size() - strlen("-pretty"));
   }
@@ -2156,19 +2173,23 @@ int main(int argc, char **argv)
            throw std::runtime_error(ss.str());
          }
          string object_pgidstr = i->get_str();
-         spg_t object_pgid;
-         object_pgid.parse(object_pgidstr.c_str());
-         if (pgidstr.length() > 0) {
-           if (object_pgid != pgid) {
-             ss << "object '" << object
-                << "' has a pgid different from the --pgid="
-                << pgidstr << " option";
-             throw std::runtime_error(ss.str());
+          if (object_pgidstr != "meta") {
+           spg_t object_pgid;
+           object_pgid.parse(object_pgidstr.c_str());
+           if (pgidstr.length() > 0) {
+             if (object_pgid != pgid) {
+               ss << "object '" << object
+                  << "' has a pgid different from the --pgid="
+                  << pgidstr << " option";
+               throw std::runtime_error(ss.str());
+             }
+           } else {
+             pgidstr = object_pgidstr;
+             pgid = object_pgid;
            }
-         } else {
-           pgidstr = object_pgidstr;
-           pgid = object_pgid;
-         }
+          } else {
+            pgidstr = object_pgidstr;
+          }
          ++i;
          v = *i;
        }
@@ -2178,7 +2199,7 @@ int main(int argc, char **argv)
          ss << "Decode object json error: " << e.what();
          throw std::runtime_error(ss.str());
        }
-        if ((uint64_t)pgid.pgid.m_pool != (uint64_t)ghobj.hobj.pool) {
+        if (pgidstr != "meta" && (uint64_t)pgid.pgid.m_pool != (uint64_t)ghobj.hobj.pool) {
           cerr << "Object pool and pgid pool don't match" << std::endl;
           ret = 1;
           goto out;
@@ -2362,6 +2383,14 @@ int main(int argc, char **argv)
     goto out;
   }
 
+  if (op == "meta-list") {
+    ret = do_meta(fs, object, formatter, debug, human_readable);
+    if (ret < 0) {
+      cerr << "do_meta failed: " << cpp_strerror(ret) << std::endl;
+    }
+    goto out;
+  }
+
   ret = fs->list_collections(ls);
   if (ret < 0) {
     cerr << "failed to list pgs: " << cpp_strerror(ret) << std::endl;
@@ -2375,6 +2404,13 @@ int main(int argc, char **argv)
   for (it = ls.begin(); it != ls.end(); ++it) {
     spg_t tmppgid;
 
+    if (pgidstr == "meta") {
+      if (it->to_str() == "meta")
+        break;
+      else
+        continue;
+    }
+
     if (!it->is_pg(&tmppgid)) {
       continue;
     }
@@ -2652,7 +2688,7 @@ int main(int argc, char **argv)
         cout << "Removal succeeded" << std::endl;
       }
     } else {
-      cerr << "Must provide --op (info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super)"
+      cerr << "Must provide --op (info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super, meta-list)"
        << std::endl;
       usage(desc);
       ret = 1;