diff options
author | Eric Milkie <milkie@10gen.com> | 2014-06-06 15:39:33 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2014-06-06 17:59:32 -0400 |
commit | f65ef0b5c272d94f500ea615e36023b45cdf088e (patch) | |
tree | 60ad7868057e03287d19029e9f2519ad1ad91793 | |
parent | 5dfc754e10bc411b0d23b6ec1bdadfe3c72ad91c (diff) | |
download | mongo-f65ef0b5c272d94f500ea615e36023b45cdf088e.tar.gz |
SERVER-14186 check for ismaster under write lock
We need to check master-ness under a write lock before doing a logOp() or else
the server might shut down.
-rw-r--r-- | src/mongo/db/commands/mr.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 51 |
2 files changed, 41 insertions, 12 deletions
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp index 752bcfc0d88..6d2b5ea2050 100644 --- a/src/mongo/db/commands/mr.cpp +++ b/src/mongo/db/commands/mr.cpp @@ -393,6 +393,7 @@ namespace mongo { { // create temp collection and insert the indexes from temporary storage Client::WriteContext tempCtx( _config.tempNamespace ); + uassert(10001, "no longer master", isMasterNs(_config.tempNamespace.c_str())); Collection* tempColl = tempCtx.ctx().db()->getCollection( _config.tempNamespace ); if ( !tempColl ) { CollectionOptions options; @@ -618,6 +619,7 @@ namespace mongo { verify( _onDisk ); Client::WriteContext ctx( ns ); + uassert(10004, "no longer master", isMasterNs(ns.c_str())); Collection* coll = ctx.ctx().db()->getCollection( ns ); if ( !coll ) uasserted(13630, str::stream() << "attempted to insert into nonexistent" << diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index e9c08fe3ef3..a0b57a81757 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -1473,18 +1473,6 @@ namespace mongo { return; } - bool canRunHere = - isMaster( dbname.c_str() ) || - c->slaveOk() || - ( c->slaveOverrideOk() && ( queryOptions & QueryOption_SlaveOk ) ) || - fromRepl; - - if ( ! canRunHere ) { - result.append( "note" , "from execCommand" ); - appendCommandStatus(result, false, "not master"); - return; - } - if ( ! c->maintenanceOk() && theReplSet && ! isMaster( dbname.c_str() ) && ! theReplSet->isSecondary() ) { result.append( "note" , "from execCommand" ); appendCommandStatus(result, false, "node is recovering"); @@ -1536,6 +1524,19 @@ namespace mongo { if ( c->locktype() == Command::NONE ) { verify( !c->lockGlobally() ); + + bool canRunHere = + isMaster( dbname.c_str() ) || + c->slaveOk() || + ( c->slaveOverrideOk() && ( queryOptions & QueryOption_SlaveOk ) ) || + fromRepl; + + if ( ! canRunHere ) { + result.append( "note" , "from execCommand" ); + appendCommandStatus(result, false, "not master"); + return; + } + // we also trust that this won't crash retval = true; @@ -1552,6 +1553,19 @@ namespace mongo { if( c->lockGlobally() ) lk.reset( new Lock::GlobalRead() ); Client::ReadContext ctx(ns, storageGlobalParams.dbpath); // read locks + + bool canRunHere = + isMaster( dbname.c_str() ) || + c->slaveOk() || + ( c->slaveOverrideOk() && ( queryOptions & QueryOption_SlaveOk ) ) || + fromRepl; + + if ( ! canRunHere ) { + result.append( "note" , "from execCommand" ); + appendCommandStatus(result, false, "not master"); + return; + } + client.curop()->ensureStarted(); retval = _execCommand(c, dbname, cmdObj, queryOptions, errmsg, result, fromRepl); } @@ -1570,6 +1584,19 @@ namespace mongo { scoped_ptr<Lock::ScopedLock> lk( global ? static_cast<Lock::ScopedLock*>( new Lock::GlobalWrite() ) : static_cast<Lock::ScopedLock*>( new Lock::DBWrite( dbname ) ) ); + + bool canRunHere = + isMaster( dbname.c_str() ) || + c->slaveOk() || + ( c->slaveOverrideOk() && ( queryOptions & QueryOption_SlaveOk ) ) || + fromRepl; + + if ( ! canRunHere ) { + result.append( "note" , "from execCommand" ); + appendCommandStatus(result, false, "not master"); + return; + } + client.curop()->ensureStarted(); Client::Context ctx(dbname, storageGlobalParams.dbpath); retval = _execCommand(c, dbname, cmdObj, queryOptions, errmsg, result, fromRepl); |