diff options
Diffstat (limited to 'src/mongo/db/commands')
28 files changed, 167 insertions, 118 deletions
diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops.cpp index ef3c2ea2ab9..37c72610627 100644 --- a/src/mongo/db/commands/apply_ops.cpp +++ b/src/mongo/db/commands/apply_ops.cpp @@ -127,7 +127,7 @@ namespace mongo { // operations are applied. We are already locked globally at this point, so taking // a DBWrite on the namespace creates a nested lock, and yields are disallowed for // operations that hold a nested lock. - Lock::DBWrite lk(ns); + Lock::DBWrite lk(txn->lockState(), ns); invariant(Lock::nested()); Client::Context ctx(ns); diff --git a/src/mongo/db/commands/auth_schema_upgrade_d.cpp b/src/mongo/db/commands/auth_schema_upgrade_d.cpp index 3a52792615e..4f63bacd173 100644 --- a/src/mongo/db/commands/auth_schema_upgrade_d.cpp +++ b/src/mongo/db/commands/auth_schema_upgrade_d.cpp @@ -147,7 +147,7 @@ namespace { if (!status.isOK()) return appendCommandStatus(result, status); - status = authzManager->upgradeSchema(maxSteps, writeConcern); + status = authzManager->upgradeSchema(txn, maxSteps, writeConcern); if (status.isOK()) result.append("done", true); return appendCommandStatus(result, status); diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index 651ecb6cca9..144ea90b01b 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -160,7 +160,7 @@ namespace mongo { if (mechanism.empty()) { mechanism = "MONGODB-CR"; } - Status status = _authenticate(mechanism, user, cmdObj); + Status status = _authenticate(txn, mechanism, user, cmdObj); audit::logAuthentication(ClientBasic::getCurrent(), mechanism, user, @@ -184,22 +184,24 @@ namespace mongo { return true; } - Status CmdAuthenticate::_authenticate(const std::string& mechanism, + Status CmdAuthenticate::_authenticate(OperationContext* txn, + const std::string& mechanism, const UserName& user, const BSONObj& cmdObj) { if (mechanism == "MONGODB-CR") { - return _authenticateCR(user, cmdObj); + return _authenticateCR(txn, user, cmdObj); } #ifdef MONGO_SSL if (mechanism == "MONGODB-X509") { - return _authenticateX509(user, cmdObj); + return _authenticateX509(txn, user, cmdObj); } #endif return Status(ErrorCodes::BadValue, "Unsupported mechanism: " + mechanism); } - Status CmdAuthenticate::_authenticateCR(const UserName& user, const BSONObj& cmdObj) { + Status CmdAuthenticate::_authenticateCR( + OperationContext* txn, const UserName& user, const BSONObj& cmdObj) { if (user == internalSecurity.user->getName() && serverGlobalParams.clusterAuthMode.load() == @@ -246,7 +248,7 @@ namespace mongo { } User* userObj; - Status status = getGlobalAuthorizationManager()->acquireUser(user, &userObj); + Status status = getGlobalAuthorizationManager()->acquireUser(txn, user, &userObj); if (!status.isOK()) { // Failure to find the privilege document indicates no-such-user, a fact that we do not // wish to reveal to the client. So, we return AuthenticationFailed rather than passing @@ -275,7 +277,7 @@ namespace mongo { AuthorizationSession* authorizationSession = ClientBasic::getCurrent()->getAuthorizationSession(); - status = authorizationSession->addAndAuthorizeUser(user); + status = authorizationSession->addAndAuthorizeUser(txn, user); if (!status.isOK()) { return status; } @@ -317,7 +319,8 @@ namespace mongo { return true; } - Status CmdAuthenticate::_authenticateX509(const UserName& user, const BSONObj& cmdObj) { + Status CmdAuthenticate::_authenticateX509( + OperationContext* txn, const UserName& user, const BSONObj& cmdObj) { if (!getSSLManager()) { return Status(ErrorCodes::ProtocolError, "SSL support is required for the MONGODB-X509 mechanism."); @@ -356,7 +359,7 @@ namespace mongo { return Status(ErrorCodes::BadValue, _x509AuthenticationDisabledMessage); } - Status status = authorizationSession->addAndAuthorizeUser(user); + Status status = authorizationSession->addAndAuthorizeUser(txn, user); if (!status.isOK()) { return status; } diff --git a/src/mongo/db/commands/authentication_commands.h b/src/mongo/db/commands/authentication_commands.h index 4ccfb464aa7..e6b0dd87ab5 100644 --- a/src/mongo/db/commands/authentication_commands.h +++ b/src/mongo/db/commands/authentication_commands.h @@ -71,11 +71,14 @@ namespace mongo { * mechanism, and ProtocolError, indicating an error in the use of the authentication * protocol. */ - Status _authenticate(const std::string& mechanism, + Status _authenticate(OperationContext* txn, + const std::string& mechanism, const UserName& user, const BSONObj& cmdObj); - Status _authenticateCR(const UserName& user, const BSONObj& cmdObj); - Status _authenticateX509(const UserName& user, const BSONObj& cmdObj); + Status _authenticateCR( + OperationContext* txn, const UserName& user, const BSONObj& cmdObj); + Status _authenticateX509( + OperationContext* txn, const UserName& user, const BSONObj& cmdObj); bool _clusterIdMatch(const std::string& subjectName, const std::string& srvSubjectName); }; diff --git a/src/mongo/db/commands/clone.cpp b/src/mongo/db/commands/clone.cpp index b75ee5ceb69..2e367e3dfaf 100644 --- a/src/mongo/db/commands/clone.cpp +++ b/src/mongo/db/commands/clone.cpp @@ -118,7 +118,7 @@ namespace mongo { set<string> clonedColls; - Lock::DBWrite dbXLock(dbname); + Lock::DBWrite dbXLock(txn->lockState(), dbname); Client::Context context( dbname ); Cloner cloner; diff --git a/src/mongo/db/commands/collection_to_capped.cpp b/src/mongo/db/commands/collection_to_capped.cpp index d2a909f4af4..0186a17b643 100644 --- a/src/mongo/db/commands/collection_to_capped.cpp +++ b/src/mongo/db/commands/collection_to_capped.cpp @@ -153,7 +153,7 @@ namespace mongo { return false; } - Lock::DBWrite dbXLock(dbname); + Lock::DBWrite dbXLock(txn->lockState(), dbname); Client::Context ctx(dbname); Status status = cloneCollectionAsCapped( txn, ctx.db(), from, to, size, temp, true ); diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp index 3355e222570..1002ec82ffd 100644 --- a/src/mongo/db/commands/compact.cpp +++ b/src/mongo/db/commands/compact.cpp @@ -140,7 +140,7 @@ namespace mongo { compactOptions.validateDocuments = cmdObj["validate"].trueValue(); - Lock::DBWrite lk(ns.ns()); + Lock::DBWrite lk(txn->lockState(), ns.ns()); BackgroundOperation::assertNoBgOpInProgForNs(ns.ns()); Client::Context ctx(ns); diff --git a/src/mongo/db/commands/copydb.cpp b/src/mongo/db/commands/copydb.cpp index 0db7a7950bb..db0025f43b2 100644 --- a/src/mongo/db/commands/copydb.cpp +++ b/src/mongo/db/commands/copydb.cpp @@ -155,8 +155,8 @@ namespace mongo { // SERVER-4328 todo lock just the two db's not everything for the fromself case scoped_ptr<Lock::ScopedLock> lk( fromSelf ? - static_cast<Lock::ScopedLock*>( new Lock::GlobalWrite() ) : - static_cast<Lock::ScopedLock*>( new Lock::DBWrite( todb ) ) ); + static_cast<Lock::ScopedLock*>(new Lock::GlobalWrite()) : + static_cast<Lock::ScopedLock*>(new Lock::DBWrite(txn->lockState(), todb))); Cloner cloner; string username = cmdObj.getStringField( "username" ); diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index 2519bc75cc4..841f9522ace 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -57,7 +57,7 @@ namespace mongo { ActionSet actions; actions.addAction(ActionType::createIndex); Privilege p(parseResourcePattern(dbname, cmdObj), actions); - if ( client->getAuthorizationSession()->isAuthorizedForPrivilege(p) ) + if (client->getAuthorizationSession()->isAuthorizedForPrivilege(p)) return Status::OK(); return Status(ErrorCodes::Unauthorized, "Unauthorized"); } @@ -132,9 +132,7 @@ namespace mongo { // as many calls are ensureIndex (and hence no-ops), this is good so its a shared // lock for common calls. We only take write lock if needed. // Note: createIndexes command does not currently respect shard versioning. - Client::ReadContext readContext( ns, - storageGlobalParams.dbpath, - false /* doVersion */ ); + Client::ReadContext readContext(txn, ns, false /* doVersion */); const Collection* collection = readContext.ctx().db()->getCollection( ns.ns() ); if ( collection ) { for ( size_t i = 0; i < specs.size(); i++ ) { @@ -164,9 +162,7 @@ namespace mongo { // now we know we have to create index(es) // Note: createIndexes command does not currently respect shard versioning. - Client::WriteContext writeContext( ns.ns(), - storageGlobalParams.dbpath, - false /* doVersion */ ); + Client::WriteContext writeContext(txn, ns.ns(), false /* doVersion */ ); Database* db = writeContext.ctx().db(); Collection* collection = db->getCollection( txn, ns.ns() ); diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index cddac188c94..3899e7f522d 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -145,7 +145,7 @@ namespace mongo { list<string> colls; const string ns = parseNs(dbname, cmdObj); - Client::ReadContext ctx(ns); + Client::ReadContext ctx(txn, ns); Database* db = ctx.ctx().db(); if ( db ) db->getDatabaseCatalogEntry()->getCollectionNamespaces( &colls ); diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp index bc05c80195a..4c3a6bb5955 100644 --- a/src/mongo/db/commands/distinct.cpp +++ b/src/mongo/db/commands/distinct.cpp @@ -90,7 +90,7 @@ namespace mongo { long long nscannedObjects = 0; // full objects looked at long long n = 0; // matches - Client::ReadContext ctx(ns); + Client::ReadContext ctx(txn, ns); Collection* collection = ctx.ctx().db()->getCollection( ns ); diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index ab9144b7c96..c68aede5bc3 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -93,7 +93,7 @@ namespace mongo { CmdDropIndexes() : Command("dropIndexes", false, "deleteIndexes") { } bool run(OperationContext* txn, const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& anObjBuilder, bool fromRepl) { - Lock::DBWrite dbXLock(dbname); + Lock::DBWrite dbXLock(txn->lockState(), dbname); bool ok = wrappedRun(txn, dbname, jsobj, errmsg, anObjBuilder); if (ok && !fromRepl) repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), jsobj); @@ -220,7 +220,7 @@ namespace mongo { MONGO_TLOG(0) << "CMD: reIndex " << toDeleteNs << endl; - Lock::DBWrite dbXLock(dbname); + Lock::DBWrite dbXLock(txn->lockState(), dbname); Client::Context ctx(toDeleteNs); Collection* collection = ctx.db()->getCollection( toDeleteNs ); diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp index 79b93f14e28..37d777b2da3 100644 --- a/src/mongo/db/commands/find_and_modify.cpp +++ b/src/mongo/db/commands/find_and_modify.cpp @@ -93,7 +93,7 @@ namespace mongo { return false; } - Lock::DBWrite dbXLock(dbname); + Lock::DBWrite dbXLock(txn->lockState(), dbname); Client::Context ctx(ns); return runNoDirectClient( txn, ns , @@ -133,7 +133,7 @@ namespace mongo { BSONObjBuilder& result, string& errmsg) { - Lock::DBWrite lk( ns ); + Lock::DBWrite lk(txn->lockState(), ns); Client::Context cx( ns ); Collection* collection = cx.db()->getCollection( txn, ns ); @@ -325,7 +325,7 @@ namespace mongo { } } - Lock::DBWrite dbXLock(dbname); + Lock::DBWrite dbXLock(txn->lockState(), dbname); Client::Context ctx(ns); BSONObj out = db.findOne(ns, q, fields); diff --git a/src/mongo/db/commands/geonear.cpp b/src/mongo/db/commands/geonear.cpp index 5976d8a4e3d..ebbdd6efd69 100644 --- a/src/mongo/db/commands/geonear.cpp +++ b/src/mongo/db/commands/geonear.cpp @@ -76,7 +76,7 @@ namespace mongo { return false; } - Client::ReadContext ctx(ns); + Client::ReadContext ctx(txn, ns); Database* db = ctx.ctx().db(); if ( !db ) { diff --git a/src/mongo/db/commands/group.cpp b/src/mongo/db/commands/group.cpp index 6e80bbef1f6..94920e4d61e 100644 --- a/src/mongo/db/commands/group.cpp +++ b/src/mongo/db/commands/group.cpp @@ -254,7 +254,7 @@ namespace mongo { finalize = p["finalize"]._asCode(); const string ns = parseNs(dbname, jsobj); - Client::ReadContext ctx(ns); + Client::ReadContext ctx(txn, ns); return group( ctx.ctx().db() , ns , q , key , keyf , reduce._asCode() , reduce.type() != CodeWScope ? 0 : reduce.codeWScopeScopeDataUnsafe() , diff --git a/src/mongo/db/commands/index_filter_commands.cpp b/src/mongo/db/commands/index_filter_commands.cpp index 60346f782c4..efc92edd3a3 100644 --- a/src/mongo/db/commands/index_filter_commands.cpp +++ b/src/mongo/db/commands/index_filter_commands.cpp @@ -124,7 +124,7 @@ namespace mongo { string& errmsg, BSONObjBuilder& result, bool fromRepl) { string ns = parseNs(dbname, cmdObj); - Status status = runIndexFilterCommand(ns, cmdObj, &result); + Status status = runIndexFilterCommand(txn, ns, cmdObj, &result); if (!status.isOK()) { addStatus(status, result); @@ -144,8 +144,9 @@ namespace mongo { ss << helpText; } - Status IndexFilterCommand::checkAuthForCommand(ClientBasic* client, const std::string& dbname, - const BSONObj& cmdObj) { + Status IndexFilterCommand::checkAuthForCommand(ClientBasic* client, + const std::string& dbname, + const BSONObj& cmdObj) { AuthorizationSession* authzSession = client->getAuthorizationSession(); ResourcePattern pattern = parseResourcePattern(dbname, cmdObj); @@ -159,9 +160,12 @@ namespace mongo { ListFilters::ListFilters() : IndexFilterCommand("planCacheListFilters", "Displays index filters for all query shapes in a collection.") { } - Status ListFilters::runIndexFilterCommand(const string& ns, BSONObj& cmdObj, BSONObjBuilder* bob) { + Status ListFilters::runIndexFilterCommand(OperationContext* txn, + const string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob) { // This is a read lock. The query settings is owned by the collection. - Client::ReadContext readCtx(ns); + Client::ReadContext readCtx(txn, ns); Client::Context& ctx = readCtx.ctx(); QuerySettings* querySettings; PlanCache* unused; @@ -218,9 +222,12 @@ namespace mongo { "Clears index filter for a single query shape or, " "if the query shape is omitted, all filters for the collection.") { } - Status ClearFilters::runIndexFilterCommand(const string& ns, BSONObj& cmdObj, BSONObjBuilder* bob) { + Status ClearFilters::runIndexFilterCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob) { // This is a read lock. The query settings is owned by the collection. - Client::ReadContext readCtx(ns); + Client::ReadContext readCtx(txn, ns); Client::Context& ctx = readCtx.ctx(); QuerySettings* querySettings; PlanCache* planCache; @@ -306,9 +313,12 @@ namespace mongo { SetFilter::SetFilter() : IndexFilterCommand("planCacheSetFilter", "Sets index filter for a query shape. Overrides existing filter.") { } - Status SetFilter::runIndexFilterCommand(const string& ns, BSONObj& cmdObj, BSONObjBuilder* bob) { + Status SetFilter::runIndexFilterCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob) { // This is a read lock. The query settings is owned by the collection. - Client::ReadContext readCtx(ns); + Client::ReadContext readCtx(txn, ns); Client::Context& ctx = readCtx.ctx(); QuerySettings* querySettings; PlanCache* planCache; diff --git a/src/mongo/db/commands/index_filter_commands.h b/src/mongo/db/commands/index_filter_commands.h index a08ddd816db..f6ba8fa9efb 100644 --- a/src/mongo/db/commands/index_filter_commands.h +++ b/src/mongo/db/commands/index_filter_commands.h @@ -76,7 +76,8 @@ namespace mongo { * One action type defined for index filter commands: * - planCacheIndexFilter */ - virtual Status checkAuthForCommand(ClientBasic* client, const std::string& dbname, + virtual Status checkAuthForCommand(ClientBasic* client, + const std::string& dbname, const BSONObj& cmdObj); /** @@ -85,7 +86,9 @@ namespace mongo { * Should contain just enough logic to invoke run*Command() function * in query_settings.h */ - virtual Status runIndexFilterCommand(const std::string& ns, BSONObj& cmdObj, + virtual Status runIndexFilterCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, BSONObjBuilder* bob) = 0; private: @@ -102,7 +105,10 @@ namespace mongo { public: ListFilters(); - virtual Status runIndexFilterCommand(const std::string& ns, BSONObj& cmdObj, BSONObjBuilder* bob); + virtual Status runIndexFilterCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob); /** * Looks up index filters from collection's query settings. @@ -121,7 +127,10 @@ namespace mongo { public: ClearFilters(); - virtual Status runIndexFilterCommand(const std::string& ns, BSONObj& cmdObj, BSONObjBuilder* bob); + virtual Status runIndexFilterCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob); /** * If query shape is provided, clears index filter for a query. @@ -149,7 +158,10 @@ namespace mongo { public: SetFilter(); - virtual Status runIndexFilterCommand(const std::string& ns, BSONObj& cmdObj, BSONObjBuilder* bob); + virtual Status runIndexFilterCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob); /** * Sets index filter for a query shape. diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp index af99dfa6818..97c5d1fb9b5 100644 --- a/src/mongo/db/commands/mr.cpp +++ b/src/mongo/db/commands/mr.cpp @@ -342,7 +342,7 @@ namespace mongo { if (_useIncremental) { // Create the inc collection and make sure we have index on "0" key. // Intentionally not replicating the inc collection to secondaries. - Client::WriteContext incCtx( _config.incLong ); + Client::WriteContext incCtx(_txn, _config.incLong); Collection* incColl = incCtx.ctx().db()->getCollection( _txn, _config.incLong ); if ( !incColl ) { CollectionOptions options; @@ -364,7 +364,7 @@ namespace mongo { { // copy indexes into temporary storage - Client::WriteContext finalCtx( _config.outputOptions.finalNamespace ); + Client::WriteContext finalCtx(_txn, _config.outputOptions.finalNamespace); Collection* finalColl = finalCtx.ctx().db()->getCollection( _config.outputOptions.finalNamespace ); if ( finalColl ) { @@ -392,7 +392,7 @@ namespace mongo { { // create temp collection and insert the indexes from temporary storage - Client::WriteContext tempCtx( _config.tempNamespace ); + Client::WriteContext tempCtx(_txn, _config.tempNamespace); Collection* tempColl = tempCtx.ctx().db()->getCollection( _txn, _config.tempNamespace ); if ( !tempColl ) { CollectionOptions options; @@ -559,7 +559,7 @@ namespace mongo { _safeCount(_db, _config.tempNamespace, BSONObj())); auto_ptr<DBClientCursor> cursor = _db.query( _config.tempNamespace , BSONObj() ); while ( cursor->more() ) { - Lock::DBWrite lock( _config.outputOptions.finalNamespace ); + Lock::DBWrite lock(_txn->lockState(), _config.outputOptions.finalNamespace); BSONObj o = cursor->nextSafe(); Helpers::upsert( _txn, _config.outputOptions.finalNamespace , o ); _txn->recoveryUnit()->commitIfNeeded(); @@ -619,7 +619,7 @@ namespace mongo { void State::insert( const string& ns , const BSONObj& o ) { verify( _onDisk ); - Client::WriteContext ctx( ns ); + Client::WriteContext ctx(_txn, ns ); Collection* coll = ctx.ctx().db()->getCollection( ns ); if ( !coll ) uasserted(13630, str::stream() << "attempted to insert into nonexistent" << @@ -645,7 +645,7 @@ namespace mongo { void State::_insertToInc( BSONObj& o ) { verify( _onDisk ); - Client::WriteContext ctx( _config.incLong ); + Client::WriteContext ctx(_txn, _config.incLong ); Collection* coll = ctx.ctx().db()->getCollection( _config.incLong ); if ( !coll ) uasserted(13631, str::stream() << "attempted to insert into nonexistent" @@ -921,7 +921,7 @@ namespace mongo { BSONObj sortKey = BSON( "0" << 1 ); { - Client::WriteContext incCtx( _config.incLong ); + Client::WriteContext incCtx(_txn, _config.incLong ); Collection* incColl = incCtx.ctx().db()->getCollection( _config.incLong ); bool foundIndex = false; @@ -940,7 +940,7 @@ namespace mongo { verify( foundIndex ); } - scoped_ptr<Client::ReadContext> ctx(new Client::ReadContext(_config.incLong)); + scoped_ptr<Client::ReadContext> ctx(new Client::ReadContext(_txn, _config.incLong)); BSONObj prev; BSONList all; @@ -989,7 +989,7 @@ namespace mongo { // reduce a finalize array finalReduce( all ); - ctx.reset(new Client::ReadContext(_config.incLong)); + ctx.reset(new Client::ReadContext(_txn, _config.incLong)); all.clear(); prev = o; @@ -1005,7 +1005,7 @@ namespace mongo { ctx.reset(); // reduce and finalize last array finalReduce( all ); - ctx.reset(new Client::ReadContext(_config.incLong)); + ctx.reset(new Client::ReadContext(_txn, _config.incLong)); pm.finished(); } @@ -1060,7 +1060,7 @@ namespace mongo { if ( ! _onDisk ) return; - Lock::DBWrite kl(_config.incLong); + Lock::DBWrite kl(_txn->lockState(), _config.incLong); for ( InMemory::iterator i=_temp->begin(); i!=_temp->end(); i++ ) { BSONList& all = i->second; @@ -1216,7 +1216,7 @@ namespace mongo { // Prevent sharding state from changing during the MR. auto_ptr<RangePreserver> rangePreserver; { - Client::ReadContext ctx(config.ns); + Client::ReadContext ctx(txn, config.ns); Collection* collection = ctx.ctx().db()->getCollection( config.ns ); if ( collection ) rangePreserver.reset(new RangePreserver(collection)); @@ -1278,7 +1278,7 @@ namespace mongo { // We've got a cursor preventing migrations off, now re-establish our useful cursor // Need lock and context to use it - scoped_ptr<Lock::DBRead> lock(new Lock::DBRead(config.ns)); + scoped_ptr<Lock::DBRead> lock(new Lock::DBRead(txn->lockState(), config.ns)); // This context does no version check, safe b/c we checked earlier and have an // open cursor @@ -1340,7 +1340,7 @@ namespace mongo { ctx.reset(); lock.reset(); state.reduceAndSpillInMemoryStateIfNeeded(); - lock.reset(new Lock::DBRead(config.ns)); + lock.reset(new Lock::DBRead(txn->lockState(), config.ns)); ctx.reset(new Client::Context(config.ns, storageGlobalParams.dbpath, false)); reduceTime += t.micros(); diff --git a/src/mongo/db/commands/parallel_collection_scan.cpp b/src/mongo/db/commands/parallel_collection_scan.cpp index 061175638cd..593912cf0d4 100644 --- a/src/mongo/db/commands/parallel_collection_scan.cpp +++ b/src/mongo/db/commands/parallel_collection_scan.cpp @@ -165,7 +165,7 @@ namespace mongo { NamespaceString ns( dbname, cmdObj[name].String() ); - Client::ReadContext ctx(ns.ns()); + Client::ReadContext ctx(txn, ns.ns()); Database* db = ctx.ctx().db(); Collection* collection = db->getCollection( ns ); diff --git a/src/mongo/db/commands/parameters.cpp b/src/mongo/db/commands/parameters.cpp index 981e04c26a5..a600be68787 100644 --- a/src/mongo/db/commands/parameters.cpp +++ b/src/mongo/db/commands/parameters.cpp @@ -96,7 +96,7 @@ namespace mongo { const ServerParameter::Map& m = ServerParameterSet::getGlobal()->getMap(); for ( ServerParameter::Map::const_iterator i = m.begin(); i != m.end(); ++i ) { if ( all || cmdObj.hasElement( i->first.c_str() ) ) { - i->second->append( result, i->second->name() ); + i->second->append(txn, result, i->second->name() ); } } @@ -177,7 +177,7 @@ namespace mongo { } if ( s == 0 ) - j->second->append( result, "was" ); + j->second->append(txn, result, "was" ); Status status = j->second->set( e ); if ( status.isOK() ) { @@ -203,7 +203,7 @@ namespace mongo { public: LogLevelSetting() : ServerParameter(ServerParameterSet::getGlobal(), "logLevel") {} - virtual void append(BSONObjBuilder& b, const std::string& name) { + virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) { b << name << logger::globalLogDomain()->getMinimumLogSeverity().toInt(); } @@ -257,7 +257,8 @@ namespace mongo { } } - virtual void append(BSONObjBuilder& b, const std::string& name) { + virtual void append( + OperationContext* txn, BSONObjBuilder& b, const std::string& name) { b << name << sslModeStr(); } @@ -324,7 +325,8 @@ namespace mongo { } } - virtual void append(BSONObjBuilder& b, const std::string& name) { + virtual void append( + OperationContext* txn, BSONObjBuilder& b, const std::string& name) { b << name << clusterAuthModeStr(); } diff --git a/src/mongo/db/commands/pipeline_command.cpp b/src/mongo/db/commands/pipeline_command.cpp index ea373a92d1c..a43d77eeda0 100644 --- a/src/mongo/db/commands/pipeline_command.cpp +++ b/src/mongo/db/commands/pipeline_command.cpp @@ -317,7 +317,7 @@ namespace { // sharding version that we synchronize on here. This is also why we always need to // create a ClientCursor even when we aren't outputting to a cursor. See the comment // on ShardFilterStage for more details. - Client::ReadContext ctx(ns); + Client::ReadContext ctx(txn, ns); Collection* collection = ctx.ctx().db()->getCollection(ns); diff --git a/src/mongo/db/commands/plan_cache_commands.cpp b/src/mongo/db/commands/plan_cache_commands.cpp index f7e97c68072..a8d32641646 100644 --- a/src/mongo/db/commands/plan_cache_commands.cpp +++ b/src/mongo/db/commands/plan_cache_commands.cpp @@ -118,7 +118,7 @@ namespace mongo { string& errmsg, BSONObjBuilder& result, bool fromRepl) { string ns = parseNs(dbname, cmdObj); - Status status = runPlanCacheCommand(ns, cmdObj, &result); + Status status = runPlanCacheCommand(txn, ns, cmdObj, &result); if (!status.isOK()) { addStatus(status, result); @@ -138,7 +138,8 @@ namespace mongo { ss << helpText; } - Status PlanCacheCommand::checkAuthForCommand(ClientBasic* client, const std::string& dbname, + Status PlanCacheCommand::checkAuthForCommand(ClientBasic* client, + const std::string& dbname, const BSONObj& cmdObj) { AuthorizationSession* authzSession = client->getAuthorizationSession(); ResourcePattern pattern = parseResourcePattern(dbname, cmdObj); @@ -206,10 +207,12 @@ namespace mongo { "Displays all query shapes in a collection.", ActionType::planCacheRead) { } - Status PlanCacheListQueryShapes::runPlanCacheCommand(const string& ns, BSONObj& cmdObj, + Status PlanCacheListQueryShapes::runPlanCacheCommand(OperationContext* txn, + const string& ns, + BSONObj& cmdObj, BSONObjBuilder* bob) { // This is a read lock. The query cache is owned by the collection. - Client::ReadContext readCtx(ns); + Client::ReadContext readCtx(txn, ns); Client::Context& ctx = readCtx.ctx(); PlanCache* planCache; Status status = getPlanCache(ctx.db(), ns, &planCache); @@ -252,10 +255,12 @@ namespace mongo { "Drops one or all cached queries in a collection.", ActionType::planCacheWrite) { } - Status PlanCacheClear::runPlanCacheCommand(const string& ns, BSONObj& cmdObj, + Status PlanCacheClear::runPlanCacheCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, BSONObjBuilder* bob) { // This is a read lock. The query cache is owned by the collection. - Client::ReadContext readCtx(ns); + Client::ReadContext readCtx(txn, ns); Client::Context& ctx = readCtx.ctx(); PlanCache* planCache; Status status = getPlanCache(ctx.db(), ns, &planCache); @@ -322,9 +327,11 @@ namespace mongo { "Displays the cached plans for a query shape.", ActionType::planCacheRead) { } - Status PlanCacheListPlans::runPlanCacheCommand(const string& ns, BSONObj& cmdObj, + Status PlanCacheListPlans::runPlanCacheCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, BSONObjBuilder* bob) { - Client::ReadContext readCtx(ns); + Client::ReadContext readCtx(txn, ns); Client::Context& ctx = readCtx.ctx(); PlanCache* planCache; Status status = getPlanCache(ctx.db(), ns, &planCache); diff --git a/src/mongo/db/commands/plan_cache_commands.h b/src/mongo/db/commands/plan_cache_commands.h index 8e7eb9667a4..507d4fe4927 100644 --- a/src/mongo/db/commands/plan_cache_commands.h +++ b/src/mongo/db/commands/plan_cache_commands.h @@ -72,7 +72,8 @@ namespace mongo { * - planCacheRead * - planCacheWrite */ - virtual Status checkAuthForCommand(ClientBasic* client, const std::string& dbname, + virtual Status checkAuthForCommand(ClientBasic* client, + const std::string& dbname, const BSONObj& cmdObj); /** * Subset of command arguments used by plan cache commands @@ -80,7 +81,9 @@ namespace mongo { * Should contain just enough logic to invoke run*Command() function * in plan_cache.h */ - virtual Status runPlanCacheCommand(const std::string& ns, BSONObj& cmdObj, + virtual Status runPlanCacheCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, BSONObjBuilder* bob) = 0; /** @@ -103,7 +106,10 @@ namespace mongo { class PlanCacheListQueryShapes : public PlanCacheCommand { public: PlanCacheListQueryShapes(); - virtual Status runPlanCacheCommand(const std::string& ns, BSONObj& cmdObj, BSONObjBuilder* bob); + virtual Status runPlanCacheCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob); /** * Looks up cache keys for collection's plan cache. @@ -126,7 +132,10 @@ namespace mongo { class PlanCacheClear : public PlanCacheCommand { public: PlanCacheClear(); - virtual Status runPlanCacheCommand(const std::string& ns, BSONObj& cmdObj, BSONObjBuilder* bob); + virtual Status runPlanCacheCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, + BSONObjBuilder* bob); /** * Clears collection's plan cache. @@ -149,7 +158,9 @@ namespace mongo { class PlanCacheListPlans : public PlanCacheCommand { public: PlanCacheListPlans(); - virtual Status runPlanCacheCommand(const std::string& ns, BSONObj& cmdObj, + virtual Status runPlanCacheCommand(OperationContext* txn, + const std::string& ns, + BSONObj& cmdObj, BSONObjBuilder* bob); /** diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp index 006a86d3677..7265270beef 100644 --- a/src/mongo/db/commands/test_commands.cpp +++ b/src/mongo/db/commands/test_commands.cpp @@ -62,7 +62,7 @@ namespace mongo { string ns = dbname + "." + coll; BSONObj obj = cmdObj[ "obj" ].embeddedObjectUserCheck(); - Lock::DBWrite lk(ns); + Lock::DBWrite lk(txn->lockState(), ns); Client::Context ctx( ns ); Database* db = ctx.db(); Collection* collection = db->getCollection( ns ); @@ -140,7 +140,7 @@ namespace mongo { int n = cmdObj.getIntField( "n" ); bool inc = cmdObj.getBoolField( "inc" ); // inclusive range? - Client::WriteContext ctx( nss.ns() ); + Client::WriteContext ctx(txn, nss.ns() ); Collection* collection = ctx.ctx().db()->getCollection( nss.ns() ); massert( 13417, "captrunc collection not found or empty", collection); @@ -185,7 +185,7 @@ namespace mongo { uassert( 13428, "emptycapped must specify a collection", !coll.empty() ); NamespaceString nss( dbname, coll ); - Client::WriteContext ctx( nss.ns() ); + Client::WriteContext ctx(txn, nss.ns() ); Database* db = ctx.ctx().db(); Collection* collection = db->getCollection( nss.ns() ); massert( 13429, "emptycapped no such collection", collection ); diff --git a/src/mongo/db/commands/touch.cpp b/src/mongo/db/commands/touch.cpp index 841a738abf2..ec2fc972659 100644 --- a/src/mongo/db/commands/touch.cpp +++ b/src/mongo/db/commands/touch.cpp @@ -104,7 +104,7 @@ namespace mongo { return false; } - Client::ReadContext context( nss.ns() ); + Client::ReadContext context(txn, nss.ns()); Database* db = context.ctx().db(); Collection* collection = db->getCollection( nss.ns() ); diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp index 40999d0cbe5..4682f9a055b 100644 --- a/src/mongo/db/commands/user_management_commands.cpp +++ b/src/mongo/db/commands/user_management_commands.cpp @@ -118,12 +118,13 @@ namespace mongo { return Status::OK(); } - static Status getCurrentUserRoles(AuthorizationManager* authzManager, + static Status getCurrentUserRoles(OperationContext* txn, + AuthorizationManager* authzManager, const UserName& userName, unordered_set<RoleName>* roles) { User* user; authzManager->invalidateUserByName(userName); // Need to make sure cache entry is up to date - Status status = authzManager->acquireUser(userName, &user); + Status status = authzManager->acquireUser(txn, userName, &user); if (!status.isOK()) { return status; } @@ -265,9 +266,10 @@ namespace mongo { return Status::OK(); } - static Status requireAuthSchemaVersion26Final(AuthorizationManager* authzManager) { + static Status requireAuthSchemaVersion26Final(OperationContext* txn, + AuthorizationManager* authzManager) { int foundSchemaVersion; - Status status = authzManager->getAuthorizationVersion(&foundSchemaVersion); + Status status = authzManager->getAuthorizationVersion(txn, &foundSchemaVersion); if (!status.isOK()) { return status; } @@ -282,9 +284,10 @@ namespace mongo { return authzManager->writeAuthSchemaVersionIfNeeded(); } - static Status requireAuthSchemaVersion26UpgradeOrFinal(AuthorizationManager* authzManager) { + static Status requireAuthSchemaVersion26UpgradeOrFinal(OperationContext* txn, + AuthorizationManager* authzManager) { int foundSchemaVersion; - Status status = authzManager->getAuthorizationVersion(&foundSchemaVersion); + Status status = authzManager->getAuthorizationVersion(txn, &foundSchemaVersion); if (!status.isOK()) { return status; } @@ -434,7 +437,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -579,7 +582,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -668,7 +671,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -754,7 +757,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -836,7 +839,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -856,7 +859,7 @@ namespace mongo { UserName userName(userNameString, dbname); unordered_set<RoleName> userRoles; - status = getCurrentUserRoles(authzManager, userName, &userRoles); + status = getCurrentUserRoles(txn, authzManager, userName, &userRoles); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -934,7 +937,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -954,7 +957,7 @@ namespace mongo { UserName userName(userNameString, dbname); unordered_set<RoleName> userRoles; - status = getCurrentUserRoles(authzManager, userName, &userRoles); + status = getCurrentUserRoles(txn, authzManager, userName, &userRoles); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1049,7 +1052,8 @@ namespace mongo { return appendCommandStatus(result, status); } - status = requireAuthSchemaVersion26UpgradeOrFinal(getGlobalAuthorizationManager()); + status = requireAuthSchemaVersion26UpgradeOrFinal(txn, + getGlobalAuthorizationManager()); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1068,7 +1072,7 @@ namespace mongo { for (size_t i = 0; i < args.userNames.size(); ++i) { BSONObj userDetails; status = getGlobalAuthorizationManager()->getUserDescription( - args.userNames[i], &userDetails); + txn, args.userNames[i], &userDetails); if (status.code() == ErrorCodes::UserNotFound) { continue; } @@ -1107,7 +1111,7 @@ namespace mongo { AuthorizationManager* authzManager = getGlobalAuthorizationManager(); int authzVersion; - Status status = authzManager->getAuthorizationVersion(&authzVersion); + Status status = authzManager->getAuthorizationVersion(txn, &authzVersion); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1252,7 +1256,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1369,7 +1373,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1459,7 +1463,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1595,7 +1599,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1755,7 +1759,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1851,7 +1855,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -1970,7 +1974,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - Status status = requireAuthSchemaVersion26Final(authzManager); + Status status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -2146,7 +2150,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -2292,7 +2296,8 @@ namespace mongo { return appendCommandStatus(result, status); } - status = requireAuthSchemaVersion26UpgradeOrFinal(getGlobalAuthorizationManager()); + status = requireAuthSchemaVersion26UpgradeOrFinal(txn, + getGlobalAuthorizationManager()); if (!status.isOK()) { return appendCommandStatus(result, status); } @@ -2840,7 +2845,7 @@ namespace mongo { Status(ErrorCodes::LockBusy, "Could not lock auth data update lock.")); } - status = requireAuthSchemaVersion26Final(authzManager); + status = requireAuthSchemaVersion26Final(txn, authzManager); if (!status.isOK()) { return appendCommandStatus(result, status); } diff --git a/src/mongo/db/commands/validate.cpp b/src/mongo/db/commands/validate.cpp index 28d06c9ae05..9b539a8b954 100644 --- a/src/mongo/db/commands/validate.cpp +++ b/src/mongo/db/commands/validate.cpp @@ -75,7 +75,7 @@ namespace mongo { MONGO_TLOG(0) << "CMD: validate " << ns << endl; } - Client::ReadContext ctx(ns_string.ns()); + Client::ReadContext ctx(txn, ns_string.ns()); Database* db = ctx.ctx().db(); if ( !db ) { diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp index a6332a50288..b147446a93d 100644 --- a/src/mongo/db/commands/write_commands/batch_executor.cpp +++ b/src/mongo/db/commands/write_commands/batch_executor.cpp @@ -902,7 +902,7 @@ namespace mongo { } invariant(!_context.get()); - _writeLock.reset(new Lock::DBWrite(request->getNS())); + _writeLock.reset(new Lock::DBWrite(txn->lockState(), request->getNS())); if (!checkIsMasterForCollection(request->getNS(), result)) { return false; } @@ -1087,7 +1087,7 @@ namespace mongo { } /////////////////////////////////////////// - Lock::DBWrite writeLock( nsString.ns() ); + Lock::DBWrite writeLock(txn->lockState(), nsString.ns()); /////////////////////////////////////////// if ( !checkShardVersion( &shardingState, *updateItem.getRequest(), result ) ) @@ -1144,7 +1144,7 @@ namespace mongo { } /////////////////////////////////////////// - Lock::DBWrite writeLock( nss.ns() ); + Lock::DBWrite writeLock(txn->lockState(), nss.ns()); /////////////////////////////////////////// // Check version once we're locked |