]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
objectstore_tool: refactor list-lost and fix-lost
authorLoic Dachary <ldachary@redhat.com>
Wed, 26 Nov 2014 16:30:30 +0000 (17:30 +0100)
committerDavid Zafman <dzafman@redhat.com>
Tue, 3 Mar 2015 19:20:58 +0000 (11:20 -0800)
Abstract out the PG exploration loops and encapsulate the list-lost and
fix-lost semantic in a callable object.

Signed-off-by: Loic Dachary <ldachary@redhat.com>
(cherry picked from commit d9e747b1bdb53d1fe543ef311e3db35fb78d8051)

src/tools/ceph_objectstore_tool.cc

index 7840c65e607df45c88e1ec439dec437687ae2579..55d808b1c6798c9d54ac3d32330b423b665c7703 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <boost/program_options/variables_map.hpp>
 #include <boost/program_options/parsers.hpp>
+#include <boost/scoped_ptr.hpp>
 
 #include <stdlib.h>
 
@@ -345,6 +346,108 @@ struct metadata_section {
   }
 };
 
+struct action_on_object_t {
+  virtual ~action_on_object_t() {}
+  virtual int call(ObjectStore *store, coll_t coll, ghobject_t &ghobj, object_info_t &oi) = 0;
+};
+
+int _action_on_all_objects_in_pg(ObjectStore *store, coll_t coll, action_on_object_t &action, bool debug)
+{
+  unsigned LIST_AT_A_TIME = 100;
+  int r;
+  ghobject_t next;
+  while (!next.is_max()) {
+    vector<ghobject_t> list;
+    r = store->collection_list_partial(
+                                      coll,
+                                      next,
+                                      LIST_AT_A_TIME,
+                                      LIST_AT_A_TIME,
+                                      CEPH_NOSNAP,
+                                      &list,
+                                      &next);
+    if (r < 0) {
+      cerr << "Error listing collection: " << coll << ", "
+          << cpp_strerror(r) << std::endl;
+      return r;
+    }
+    for (vector<ghobject_t>::iterator obj = list.begin();
+        obj != list.end();
+        ++obj) {
+      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;
+      }
+      r = action.call(store, coll, *obj, oi);
+      if (r < 0)
+       return r;
+    }
+  }
+  return 0;
+}
+
+int action_on_all_objects_in_pg(ObjectStore *store, coll_t coll, action_on_object_t &action, bool debug)
+{
+  int r = _action_on_all_objects_in_pg(store, coll, action, debug);
+  store->sync_and_flush();
+  return r;
+}
+
+int _action_on_all_objects(ObjectStore *store, action_on_object_t &action, bool debug)
+{
+  unsigned scanned = 0;
+  int r = 0;
+  vector<coll_t> colls_to_check;
+  vector<coll_t> candidates;
+  r = store->list_collections(candidates);
+  if (r < 0) {
+    cerr << "Error listing collections: " << cpp_strerror(r) << std::endl;
+    return r;
+  }
+  for (vector<coll_t>::iterator i = candidates.begin();
+       i != candidates.end();
+       ++i) {
+    spg_t pgid;
+    snapid_t snap;
+    if (i->is_pg(pgid, snap)) {
+      colls_to_check.push_back(*i);
+    }
+  }
+
+  if (debug)
+    cerr << colls_to_check.size() << " pgs to scan" << std::endl;
+  for (vector<coll_t>::iterator i = colls_to_check.begin();
+       i != colls_to_check.end();
+       ++i, ++scanned) {
+    if (debug)
+      cerr << "Scanning " << *i << ", " << scanned << "/"
+          << colls_to_check.size() << " completed" << std::endl;
+    r = _action_on_all_objects_in_pg(store, *i, action, debug);
+    if (r < 0)
+      return r;
+  }
+  return 0;
+}
+
+int action_on_all_objects(ObjectStore *store, action_on_object_t &action, bool debug)
+{
+  int r = _action_on_all_objects(store, action, debug);
+  store->sync_and_flush();
+  return r;
+}
 hobject_t infos_oid = OSD::make_infos_oid();
 hobject_t biginfo_oid, log_oid;
 
@@ -1801,6 +1904,35 @@ int do_set_omaphdr(ObjectStore *store, coll_t coll, ghobject_t &ghobj, int fd)
   return 0;
 }
 
+struct do_list_lost : public action_on_object_t {
+  virtual int call(ObjectStore *store, coll_t coll, ghobject_t &ghobj, object_info_t &oi) {
+    if (oi.is_lost())
+      cout << coll << "/" << ghobj << " is lost" << std::endl;
+    return 0;
+  }
+};
+
+struct do_fix_lost : public action_on_object_t {
+  virtual int call(ObjectStore *store, coll_t coll, ghobject_t &ghobj, object_info_t &oi) {
+    if (oi.is_lost()) {
+      cout << coll << "/" << ghobj << " is lost, fixing" << std::endl;
+      oi.clear_flag(object_info_t::FLAG_LOST);
+      bufferlist bl;
+      ::encode(oi, bl);
+      ObjectStore::Transaction t;
+      t.setattr(coll, ghobj, OI_ATTR, bl);
+      int r = store->apply_transaction(t);
+      if (r < 0) {
+       cerr << "Error getting fixing attr on : " << make_pair(coll, ghobj)
+            << ", "
+            << cpp_strerror(r) << std::endl;
+       return r;
+      }
+    }
+    return 0;
+  }
+};
+
 void usage(po::options_description &desc)
 {
     cerr << std::endl;
@@ -2253,102 +2385,18 @@ int main(int argc, char **argv)
   }
 
   if (op == "list-lost" || op == "fix-lost") {
-    unsigned LIST_AT_A_TIME = 100;
-    unsigned scanned = 0;
-    int r = 0;
-    vector<coll_t> colls_to_check;
-    if (pgidstr.length()) {
-      colls_to_check.push_back(coll_t(pgid));
-    } else {
-      vector<coll_t> candidates;
-      r = fs->list_collections(candidates);
-      if (r < 0) {
-        cerr << "Error listing collections: " << cpp_strerror(r) << std::endl;
-        goto UMOUNT;
-      }
-      for (vector<coll_t>::iterator i = candidates.begin();
-           i != candidates.end();
-           ++i) {
-        spg_t pgid;
-        snapid_t snap;
-        if (i->is_pg(pgid, snap)) {
-          colls_to_check.push_back(*i);
-        }
-      }
-    }
-
-    cout << colls_to_check.size() << " pgs to scan" << std::endl;
-    for (vector<coll_t>::iterator i = colls_to_check.begin();
-         i != colls_to_check.end();
-         ++i, ++scanned) {
-      cout << "Scanning " << *i << ", " << scanned << "/"
-           << colls_to_check.size() << " completed" << std::endl;
-      ghobject_t next;
-      while (!next.is_max()) {
-        vector<ghobject_t> list;
-        r = fs->collection_list_partial(
-          *i,
-          next,
-          LIST_AT_A_TIME,
-          LIST_AT_A_TIME,
-          CEPH_NOSNAP,
-          &list,
-          &next);
-        if (r < 0) {
-          cerr << "Error listing collection: " << *i << ", "
-               << cpp_strerror(r) << std::endl;
-          goto UMOUNT;
-        }
-        for (vector<ghobject_t>::iterator obj = list.begin();
-             obj != list.end();
-             ++obj) {
-          bufferlist attr;
-          r = fs->getattr(*i, *obj, OI_ATTR, attr);
-          if (r < 0) {
-            cerr << "Error getting attr on : " << make_pair(*i, *obj) << ", "
-                 << cpp_strerror(r) << std::endl;
-            goto UMOUNT;
-          }
-          object_info_t oi;
-          bufferlist::iterator bp = attr.begin();
-          try {
-            ::decode(oi, bp);
-          } catch (...) {
-            r = -EINVAL;
-            cerr << "Error getting attr on : " << make_pair(*i, *obj) << ", "
-                 << cpp_strerror(r) << std::endl;
-            goto UMOUNT;
-          }
-          if (oi.is_lost()) {
-            if (op == "list-lost") {
-              cout << *i << "/" << *obj << " is lost" << std::endl;
-            }
-            if (op == "fix-lost") {
-              cout << *i << "/" << *obj << " is lost, fixing" << std::endl;
-              oi.clear_flag(object_info_t::FLAG_LOST);
-              bufferlist bl2;
-              ::encode(oi, bl2);
-              ObjectStore::Transaction t;
-              t.setattr(*i, *obj, OI_ATTR, bl2);
-              r = fs->apply_transaction(t);
-              if (r < 0) {
-                cerr << "Error getting fixing attr on : " << make_pair(*i, *obj)
-                     << ", "
-                     << cpp_strerror(r) << std::endl;
-                goto UMOUNT;
-              }
-            }
-          }
-        }
-      }
-    }
-    cout << "Completed" << std::endl;
-
-   UMOUNT:
-    fs->sync_and_flush();
-    ret = r;
+    boost::scoped_ptr<action_on_object_t> action;
+    if (op == "list-lost")
+      action.reset(new do_list_lost());
+    if (op == "fix-lost")
+      action.reset(new do_fix_lost());
+    if (pgidstr.length())
+      ret = action_on_all_objects_in_pg(fs, coll_t(pgid), *action, debug);
+    else
+      ret = action_on_all_objects(fs, *action, debug);
     goto out;
   }
+  }
 
   r = fs->list_collections(ls);
   if (r < 0) {