]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools: Check for overlaps in internal "complete" table for DBObjectMap
authorDavid Zafman <dzafman@redhat.com>
Wed, 8 Feb 2017 18:02:40 +0000 (10:02 -0800)
committerDavid Zafman <dzafman@redhat.com>
Wed, 26 Apr 2017 21:03:18 +0000 (14:03 -0700)
Changed check to return an error count and fix tool error message

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

Conflicts:
src/os/filestore/DBObjectMap.h (trivial)

src/os/ObjectMap.h
src/os/filestore/DBObjectMap.cc
src/os/filestore/DBObjectMap.h
src/test/ObjectMap/test_object_map.cc
src/tools/ceph_osdomap_tool.cc

index c4efc7fbc202a1b3d978ee83263bef3bd25860db..a07142a09c48149e323ce779408a11135fe66953 100644 (file)
@@ -137,7 +137,7 @@ public:
     const SequencerPosition *spos=0   ///< [in] Sequencer
     ) { return 0; }
 
-  virtual bool check(std::ostream &out) { return true; }
+  virtual int check(std::ostream &out) { return 0; }
 
   typedef KeyValueDB::GenericIteratorImpl ObjectMapIteratorImpl;
   typedef ceph::shared_ptr<ObjectMapIteratorImpl> ObjectMapIterator;
index ccc6bbf52260783d3d6077e1ea4e41c3d162ef6f..11f1480273c33da517570e1fc6961e543493d3b3 100644 (file)
@@ -54,9 +54,9 @@ static void append_escaped(const string &in, string *out)
   }
 }
 
-bool DBObjectMap::check(std::ostream &out)
+int DBObjectMap::check(std::ostream &out)
 {
-  bool retval = true;
+  int errors = 0;
   map<uint64_t, uint64_t> parent_to_num_children;
   map<uint64_t, uint64_t> parent_to_actual_num_children;
   KeyValueDB::Iterator iter = db->get_iterator(HOBJECT_TO_SEQ);
@@ -68,6 +68,20 @@ bool DBObjectMap::check(std::ostream &out)
       header.decode(bliter);
       if (header.seq != 0)
        parent_to_actual_num_children[header.seq] = header.num_children;
+
+      // Check complete table
+      boost::optional<string> prev;
+      KeyValueDB::Iterator complete_iter = db->get_iterator(USER_PREFIX + header_key(header.seq) + COMPLETE_PREFIX);
+      for (complete_iter->seek_to_first(); complete_iter->valid();
+           complete_iter->next()) {
+         if (prev && prev >= complete_iter->key()) {
+             out << "Bad complete for " << header.oid << std::endl;
+             errors++;
+             break;
+         }
+         prev = string(complete_iter->value().c_str(), complete_iter->value().length() - 1);
+      }
+
       if (header.parent == 0)
        break;
 
@@ -83,7 +97,7 @@ bool DBObjectMap::check(std::ostream &out)
       db->get(sys_parent_prefix(header), to_get, &got);
       if (got.empty()) {
        out << "Missing: seq " << header.parent << std::endl;
-       retval = false;
+       errors++;
        break;
       } else {
        bl = got.begin()->second;
@@ -100,11 +114,11 @@ bool DBObjectMap::check(std::ostream &out)
       out << "Invalid: seq " << i->first << " recorded children: "
          << parent_to_actual_num_children[i->first] << " found: "
          << i->second << std::endl;
-      retval = false;
+      errors++;
     }
     parent_to_actual_num_children.erase(i->first);
   }
-  return retval;
+  return errors;
 }
 
 string DBObjectMap::ghobject_key(const ghobject_t &oid)
index 26d435320f5396d6e240b964d82f75b219cacc83..a05d23019b9e5048b93485276d6c3cee0a44c500 100644 (file)
@@ -212,7 +212,7 @@ public:
   int upgrade_to_v2();
 
   /// Consistency check, debug, there must be no parallel writes
-  bool check(std::ostream &out);
+  int check(std::ostream &out);
 
   /// Ensure that all previous operations are durable
   int sync(const ghobject_t *oid=0, const SequencerPosition *spos=0);
index a99e920083047f2fc63219bec043f6b8ad0edc9a..6985b142060c27bff944edb299c4160e3e8a483d 100644 (file)
@@ -542,7 +542,7 @@ public:
 
   virtual void TearDown() {
     std::cerr << "Checking..." << std::endl;
-    assert(db->check(std::cerr));
+    assert(db->check(std::cerr) == 0);
   }
 };
 
index 269ff44643da6497c61fd572946c28d5087f103e..f760b0a554cd5b5959c643e48d8b204964fed34b 100644 (file)
@@ -150,8 +150,8 @@ int main(int argc, char **argv) {
     }
   } else if (cmd == "check") {
     r = omap.check(std::cout);
-    if (!r) {
-      std::cerr << "check got: " << cpp_strerror(r) << std::endl;
+    if (r > 0) {
+      std::cerr << "check got " << r << " error(s)" << std::endl;
       goto done;
     }
     std::cout << "check succeeded" << std::endl;