summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTad Marshall <tad@10gen.com>2012-09-23 19:56:01 -0400
committerEric Milkie <milkie@10gen.com>2012-11-06 15:41:16 -0500
commitc2378fd2d764f76dfaf535a554f6d264ba1c1d92 (patch)
treea10320466cd803adfd2af8250178a80a3c513111
parent8bb07be63af3bb27f5f03d767dbf0c7fbda07338 (diff)
downloadmongo-c2378fd2d764f76dfaf535a554f6d264ba1c1d92.tar.gz
SERVER-7045 check all extents in validate command, report results
Move the Extent::validates() routine from pdfile.h to pdfile.cpp, make it return messages for errors it finds, call it for every extent instead of just for the first extent. Check extent DiskLoc against 'myLoc'.
-rw-r--r--src/mongo/db/compact.cpp2
-rw-r--r--src/mongo/db/dbcommands_admin.cpp18
-rw-r--r--src/mongo/db/pdfile.cpp39
-rw-r--r--src/mongo/db/pdfile.h5
4 files changed, 53 insertions, 11 deletions
diff --git a/src/mongo/db/compact.cpp b/src/mongo/db/compact.cpp
index 4c258ef62a7..847a77b01e0 100644
--- a/src/mongo/db/compact.cpp
+++ b/src/mongo/db/compact.cpp
@@ -63,7 +63,7 @@ namespace mongo {
Extent *e = diskloc.ext();
e->assertOk();
- verify( e->validates() );
+ verify( e->validates(diskloc) );
unsigned skipped = 0;
{
diff --git a/src/mongo/db/dbcommands_admin.cpp b/src/mongo/db/dbcommands_admin.cpp
index b1b46e8c0b0..2bedc168264 100644
--- a/src/mongo/db/dbcommands_admin.cpp
+++ b/src/mongo/db/dbcommands_admin.cpp
@@ -203,11 +203,13 @@ namespace mongo {
while( !el.isNull() ) {
Extent *e = el.ext();
e->assertOk();
- el = e->xnext;
- ne++;
if ( full )
extentData << e->dump();
-
+ if (!e->validates(el, &errors)) {
+ valid = false;
+ }
+ el = e->xnext;
+ ne++;
killCurrentOp.checkForInterrupt();
}
result.append("extentCount", ne);
@@ -231,9 +233,13 @@ namespace mongo {
try {
result.append("firstExtentDetails", d->firstExtent.ext()->dump());
-
- valid = valid && d->firstExtent.ext()->validates() &&
- d->firstExtent.ext()->xprev.isNull();
+ if (!d->firstExtent.ext()->xprev.isNull()) {
+ StringBuilder sb;
+ sb << "'xprev' pointer in first extent " << d->firstExtent.toString()
+ << " is not null";
+ errors << sb.str();
+ valid=false;
+ }
}
catch (...) {
errors << "exception firstextent";
diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp
index 701616014e0..3967e158e6d 100644
--- a/src/mongo/db/pdfile.cpp
+++ b/src/mongo/db/pdfile.cpp
@@ -700,6 +700,45 @@ namespace mongo {
return emptyLoc;
}
+ bool Extent::validates(const DiskLoc diskLoc, BSONArrayBuilder* errors) {
+ bool extentOk = true;
+ if (myLoc != diskLoc) {
+ if (errors) {
+ StringBuilder sb;
+ sb << "extent " << diskLoc.toString()
+ << " self-pointer is " << myLoc.toString();
+ *errors << sb.str();
+ }
+ extentOk = false;
+ }
+ if (firstRecord.isNull() != lastRecord.isNull()) {
+ if (errors) {
+ StringBuilder sb;
+ if (firstRecord.isNull()) {
+ sb << "in extent " << diskLoc.toString()
+ << ", firstRecord is null but lastRecord is "
+ << lastRecord.toString();
+ }
+ else {
+ sb << "in extent " << diskLoc.toString()
+ << ", firstRecord is " << firstRecord.toString()
+ << " but lastRecord is null";
+ }
+ *errors << sb.str();
+ }
+ extentOk = false;
+ }
+ if (length < 0) {
+ if (errors) {
+ StringBuilder sb;
+ sb << "negative length extent " << diskLoc.toString();
+ *errors << sb.str();
+ }
+ extentOk = false;
+ }
+ return extentOk;
+ }
+
/*
Record* Extent::newRecord(int len) {
if( firstEmptyRegion.isNull() )8
diff --git a/src/mongo/db/pdfile.h b/src/mongo/db/pdfile.h
index d1904f928b9..af224bac8da 100644
--- a/src/mongo/db/pdfile.h
+++ b/src/mongo/db/pdfile.h
@@ -330,10 +330,7 @@ namespace mongo {
static int HeaderSize() { return sizeof(Extent)-4; }
- bool validates() {
- return !(firstRecord.isNull() ^ lastRecord.isNull()) &&
- length >= 0 && !myLoc.isNull();
- }
+ bool validates(const DiskLoc diskLoc, BSONArrayBuilder* errors = NULL);
BSONObj dump() {
return BSON( "loc" << myLoc.toString() << "xnext" << xnext.toString() << "xprev" << xprev.toString()