diff options
author | Tad Marshall <tad@10gen.com> | 2012-09-23 19:56:01 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2012-11-06 15:41:16 -0500 |
commit | c2378fd2d764f76dfaf535a554f6d264ba1c1d92 (patch) | |
tree | a10320466cd803adfd2af8250178a80a3c513111 | |
parent | 8bb07be63af3bb27f5f03d767dbf0c7fbda07338 (diff) | |
download | mongo-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.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/dbcommands_admin.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/pdfile.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/pdfile.h | 5 |
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() |