]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-objectstore-tool: Enhanced dump command replaces dump-info
authorDavid Zafman <dzafman@redhat.com>
Thu, 15 Oct 2015 05:04:05 +0000 (22:04 -0700)
committerDavid Zafman <dzafman@redhat.com>
Thu, 25 Feb 2016 20:50:25 +0000 (12:50 -0800)
Show object stat information from objectstore
Show SnapSet if present
Add --head for search by object name

Signed-off-by: David Zafman <dzafman@redhat.com>
(cherry picked from commit 1688debf7892d36c773c12d7d0b1b9b4cddc5f98)

src/test/ceph_objectstore_tool.py
src/tools/ceph_objectstore_tool.cc

index 848444d6ee7960a7076a11926023d0975d11757f..49f28ec883e6ca888add612c26e970cd4a970ccc 100755 (executable)
@@ -1036,6 +1036,28 @@ def main(argv):
     except:
         pass
 
+    # Test dump
+    print "Test dump"
+    for nspace in db.keys():
+        for basename in db[nspace].keys():
+            file = os.path.join(DATADIR, nspace + "-" + basename + "__head")
+            JSON = db[nspace][basename]['json']
+            GETNAME = "/tmp/getbytes.{pid}".format(pid=pid)
+            for pg in OBJREPPGS:
+                OSDS = get_osds(pg, OSDDIR)
+                for osd in OSDS:
+                    DIR = os.path.join(OSDDIR, os.path.join(osd, os.path.join("current", "{pg}_head".format(pg=pg))))
+                    fnames = [f for f in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, f))
+                              and f.split("_")[0] == basename and f.split("_")[4] == nspace]
+                    if not fnames:
+                        continue
+                    cmd = (CFSD_PREFIX + " '{json}' dump | grep '\"snap\": 1,' > /dev/null").format(osd=osd, json=JSON)
+                    logging.debug(cmd)
+                    ret = call(cmd, shell=True)
+                    if ret != 0:
+                        logging.error("Invalid dump for {json}".format(json=JSON))
+                        ERRORS += 1
+
     print "Test list-attrs get-attr"
     ATTRFILE = r"/tmp/attrs.{pid}".format(pid=pid)
     VALFILE = r"/tmp/val.{pid}".format(pid=pid)
index 72f830295b4a1d1b24d496e4de97dcc551063583..22596428efe19a9b96b7c679e27094d2bf79b46b 100644 (file)
@@ -571,10 +571,14 @@ struct pgid_object_list {
 struct lookup_ghobject : public action_on_object_t {
   pgid_object_list _objects;
   const string _name;
+  bool _need_snapset;
 
-  lookup_ghobject(const string& name) : _name(name) { }
+  lookup_ghobject(const string& name, bool need_snapset = false) : _name(name),
+                 _need_snapset(need_snapset) { }
 
   virtual int call(ObjectStore *store, coll_t coll, ghobject_t &ghobj, object_info_t &oi) {
+    if (_need_snapset && !ghobj.hobj.has_snapset())
+      return 0;
     if (_name.length() == 0 || ghobj.hobj.oid.name == _name)
       _objects.insert(coll, ghobj);
     return 0;
@@ -2273,10 +2277,11 @@ int do_import(ObjectStore *store, OSDSuperblock& sb, bool force, string pgidstr)
   return 0;
 }
 
-int do_list(ObjectStore *store, string pgidstr, string object, Formatter *formatter, bool debug, bool human_readable)
+int do_list(ObjectStore *store, string pgidstr, string object,
+           Formatter *formatter, bool debug, bool human_readable, bool head)
 {
   int r;
-  lookup_ghobject lookup(object);
+  lookup_ghobject lookup(object, head);
   if (pgidstr.length() > 0) {
     r = action_on_all_objects_in_pg(store, pgidstr, lookup, debug);
   } else {
@@ -2643,31 +2648,85 @@ struct do_fix_lost : public action_on_object_t {
   }
 };
 
-int print_obj_info(ObjectStore *store, coll_t coll, ghobject_t &ghobj, Formatter* formatter)
+int get_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj, SnapSet &ss)
 {
   bufferlist attr;
-  int r = store->getattr(coll, ghobj, OI_ATTR, attr);
+  int r = store->getattr(coll, ghobj, SS_ATTR, attr);
   if (r < 0) {
-    cerr << "Error getting attr on : " << make_pair(coll, ghobj) << ", "
+    cerr << "Error getting snapset on : " << make_pair(coll, ghobj) << ", "
        << cpp_strerror(r) << std::endl;
     return r;
   }
-  object_info_t oi;
   bufferlist::iterator bp = attr.begin();
   try {
-    ::decode(oi, bp);
+    ::decode(ss, bp);
   } catch (...) {
     r = -EINVAL;
-    cerr << "Error getting attr on : " << make_pair(coll, ghobj) << ", "
+    cerr << "Error decoding snapset on : " << make_pair(coll, ghobj) << ", "
          << cpp_strerror(r) << std::endl;
     return r;
   }
-  formatter->open_object_section("info");
-  oi.dump(formatter);
+  return 0;
+}
+
+int print_obj_info(ObjectStore *store, coll_t coll, ghobject_t &ghobj, Formatter* formatter)
+{
+  int r = 0;
+  formatter->open_object_section("obj");
+  formatter->open_object_section("id");
+  ghobj.dump(formatter);
+  formatter->close_section();
+
+  bufferlist attr;
+  int gr = store->getattr(coll, ghobj, OI_ATTR, attr);
+  if (gr < 0) {
+    r = gr;
+    cerr << "Error getting attr on : " << make_pair(coll, ghobj) << ", "
+       << cpp_strerror(r) << std::endl;
+  } else {
+    object_info_t oi;
+    bufferlist::iterator bp = attr.begin();
+    try {
+      ::decode(oi, bp);
+      formatter->open_object_section("info");
+      oi.dump(formatter);
+      formatter->close_section();
+    } catch (...) {
+      r = -EINVAL;
+      cerr << "Error decoding attr on : " << make_pair(coll, ghobj) << ", "
+           << cpp_strerror(r) << std::endl;
+    }
+  }
+  struct stat st;
+  int sr =  store->stat(coll, ghobj, &st, true);
+  if (sr < 0) {
+    r = sr;
+    cerr << "Error stat on : " << make_pair(coll, ghobj) << ", "
+         << cpp_strerror(r) << std::endl;
+  } else {
+    formatter->open_object_section("stat");
+    formatter->dump_int("size", st.st_size);
+    formatter->dump_int("blksize", st.st_blksize);
+    formatter->dump_int("blocks", st.st_blocks);
+    formatter->dump_int("nlink", st.st_nlink);
+    formatter->close_section();
+  }
+
+  if (ghobj.hobj.has_snapset()) {
+    SnapSet ss;
+    int snr = get_snapset(store, coll, ghobj, ss);
+    if (snr < 0) {
+      r = snr;
+    } else {
+      formatter->open_object_section("SnapSet");
+      ss.dump(formatter);
+      formatter->close_section();
+    }
+  }
   formatter->close_section();
   formatter->flush(cout);
   cout << std::endl;
-  return 0;
+  return r;
 }
 
 void usage(po::options_description &desc)
@@ -2685,7 +2744,7 @@ void usage(po::options_description &desc)
     cerr << "ceph-objectstore-tool ... <object> list-attrs" << std::endl;
     cerr << "ceph-objectstore-tool ... <object> list-omap" << std::endl;
     cerr << "ceph-objectstore-tool ... <object> remove" << std::endl;
-    cerr << "ceph-objectstore-tool ... <object> dump-info" << std::endl;
+    cerr << "ceph-objectstore-tool ... <object> dump" << std::endl;
     cerr << std::endl;
     cerr << "ceph-objectstore-tool import-rados <pool> [file]" << std::endl;
     cerr << std::endl;
@@ -2728,6 +2787,7 @@ int main(int argc, char **argv)
   bool human_readable, no_overwrite;
   bool force;
   Formatter *formatter;
+  bool head;
 
   po::options_description desc("Allowed options");
   desc.add_options()
@@ -2753,6 +2813,7 @@ int main(int argc, char **argv)
     ("force", "Ignore some types of errors and proceed with operation - USE WITH CAUTION: CORRUPTION POSSIBLE NOW OR IN THE FUTURE")
     ("skip-journal-replay", "Disable journal replay")
     ("skip-mount-omap", "Disable mounting of omap")
+    ("head", "Find head/snapdir when searching for objects by name")
     ("dry-run", "Don't modify the objectstore")
     ("no-overwrite", "For import-rados don't overwrite existing files")
     ;
@@ -2814,6 +2875,8 @@ int main(int argc, char **argv)
   if (vm.count("skip-mount-omap"))
     flags |= SKIP_MOUNT_OMAP;
 
+  head = (vm.count("head") > 0);
+
   vector<const char *> ceph_options;
   env_to_vec(ceph_options);
   ceph_options.reserve(ceph_options.size() + ceph_option_strings.size());
@@ -3078,7 +3141,7 @@ int main(int argc, char **argv)
     json_spirit::Value v;
     try {
       if (!json_spirit::read(object, v)) {
-       lookup_ghobject lookup(object);
+       lookup_ghobject lookup(object, head);
        if (action_on_all_objects(fs, lookup, debug)) {
          throw std::runtime_error("Internal error");
        } else {
@@ -3361,7 +3424,7 @@ int main(int argc, char **argv)
   }
 
   if (op == "list") {
-    ret = do_list(fs, pgidstr, object, formatter, debug, human_readable);
+    ret = do_list(fs, pgidstr, object, formatter, debug, human_readable, head);
     if (ret < 0) {
       cerr << "do_list failed: " << cpp_strerror(ret) << std::endl;
     }
@@ -3610,7 +3673,13 @@ int main(int argc, char **argv)
        if (fd != STDIN_FILENO)
          close(fd);
         goto out;
-      } else if (objcmd == "dump-info") {
+      } else if (objcmd == "dump") {
+       // There should not be any other arguments
+       if (vm.count("arg1") || vm.count("arg2")) {
+         usage(desc);
+         ret = 1;
+         goto out;
+       }
        ret = print_obj_info(fs, coll, ghobj, formatter);
        goto out;
       }