]> git.apps.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>
Tue, 28 Mar 2017 16:32:36 +0000 (09:32 -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 1c29ac7c39ede813f53c69162182720874250b02..4afa9b1acf79c0ee4629803ddc02257b92c502fb 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 1d7d84af34287e95aeda2cfbb08c9993ac47825e..2b3b9f4dcb3341672a55ddfb7bd1a5f648d22c5f 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 a38e579e16f30757ae88f04f11d37c0ec448fb02..cbb5a776eed2148a18542a9db6fb795039408990 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;