]> 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>
Mon, 27 Mar 2017 15:33:04 +0000 (08:33 -0700)
Changed check to return an error count and fix tool error message

Signed-off-by: David Zafman <dzafman@redhat.com>
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 f7c2f5f1d1c24e9effccff732f408a62232acfa9..05361820af3195a6c394525ca68a88342ab49ae0 100644 (file)
@@ -138,7 +138,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 62e5499079b3243fb0c8d8860128bc41595693cd..ec99addce47129d54df22f5393911bd050ba4443 100644 (file)
@@ -55,9 +55,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);
@@ -69,6 +69,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;
 
@@ -84,7 +98,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;
@@ -101,11 +115,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 8e1e6b8eb0982b22b5dd3b7363868e1c2667b3dc..79a0f271a1a3d955d086f1076ccf83bdd8258b11 100644 (file)
@@ -213,7 +213,7 @@ public:
   int upgrade_to_v2();
 
   /// Consistency check, debug, there must be no parallel writes
-  bool check(std::ostream &out) override;
+  int check(std::ostream &out) override;
 
   /// Ensure that all previous operations are durable
   int sync(const ghobject_t *oid=0, const SequencerPosition *spos=0) override;
index 5ad1bf9930a99a2ca0ce8fbd1eae5197051b31bf..c91095f3f5ce233a7d117635e00668fb3eba184e 100644 (file)
@@ -542,7 +542,7 @@ public:
 
   void TearDown() override {
     std::cerr << "Checking..." << std::endl;
-    assert(db->check(std::cerr));
+    assert(db->check(std::cerr) == 0);
   }
 };
 
index 12ba7426e3dea9c2bb8e556a30514f4c211a09fb..4a97c4dbd02c9d8d0a9aa848853d8780887bcf2c 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;