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;
}
}
-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);
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;
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;
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)
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);
}
} 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;