summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2016-12-10 22:01:46 -0500
committerAndrew Morrow <acm@mongodb.com>2016-12-14 09:22:24 -0500
commita20ff1fe0d639d703314b36031d829c8713c2a91 (patch)
tree6f03762fc5daaf812400513b8bfddfb9a4222aee
parent64f1ca4537d17ea65ceeb05885b48732a314cc02 (diff)
downloadmongo-a20ff1fe0d639d703314b36031d829c8713c2a91.tar.gz
SERVER-23103 Move assembleResposne to its own library
-rw-r--r--src/mongo/db/SConscript22
-rw-r--r--src/mongo/db/assemble_response.cpp655
-rw-r--r--src/mongo/db/assemble_response.h48
-rw-r--r--src/mongo/db/auth/authz_session_external_state_d.cpp1
-rw-r--r--src/mongo/db/catalog/database.cpp1
-rw-r--r--src/mongo/db/commands/clone_collection.cpp1
-rw-r--r--src/mongo/db/commands/dbcommands.cpp1
-rw-r--r--src/mongo/db/commands/distinct.cpp1
-rw-r--r--src/mongo/db/commands/generic.cpp1
-rw-r--r--src/mongo/db/commands/mr.cpp1
-rw-r--r--src/mongo/db/dbdirectclient.cpp9
-rw-r--r--src/mongo/db/dbdirectclient.h2
-rw-r--r--src/mongo/db/dbwebserver.cpp1
-rw-r--r--src/mongo/db/index_rebuilder.cpp1
-rw-r--r--src/mongo/db/instance.cpp653
-rw-r--r--src/mongo/db/instance.h11
-rw-r--r--src/mongo/db/mongod_options.cpp1
-rw-r--r--src/mongo/db/pipeline/accumulator_test.cpp1
-rw-r--r--src/mongo/db/pipeline/document_source_cursor.cpp1
-rw-r--r--src/mongo/db/pipeline/document_value_test.cpp2
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp2
-rw-r--r--src/mongo/db/service_entry_point_mongod.cpp2
-rw-r--r--src/mongo/db/storage/mmap_v1/btree/btree_logic_test.cpp1
-rw-r--r--src/mongo/db/storage/mmap_v1/data_file_sync.cpp1
-rw-r--r--src/mongo/dbtests/basictests.cpp1
-rw-r--r--src/mongo/dbtests/dbtests.cpp1
-rw-r--r--src/mongo/dbtests/dbtests.h2
-rw-r--r--src/mongo/dbtests/jsobjtests.cpp1
-rw-r--r--src/mongo/dbtests/mmaptests.cpp1
-rw-r--r--src/mongo/dbtests/query_stage_ixscan.cpp1
-rw-r--r--src/mongo/dbtests/query_stage_limit_skip.cpp1
-rw-r--r--src/mongo/dbtests/socktests.cpp2
-rw-r--r--src/mongo/s/server.cpp1
33 files changed, 744 insertions, 687 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 8370d39a01d..1b6d57eddef 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -606,7 +606,7 @@ env.Library(
'lasterror',
],
LIBDEPS_TAGS=[
- # Depends on assembleResponse, defined in instance.cpp below.
+ # Circularity with assembleResponse, defined in assemble_response, below.
'incomplete',
],
)
@@ -803,6 +803,25 @@ env.Library(
],
)
+env.Library(
+ target="assemble_response",
+ source=[
+ "assemble_response.cpp",
+ ],
+ LIBDEPS=[
+ "commands/dcommands",
+ "curop",
+ "curop_metrics",
+ "diag_log",
+ "introspect",
+ "lasterror",
+ "ops/write_ops",
+ "ops/write_ops_parsers",
+ "run_commands",
+ "storage/storage_options",
+ ],
+)
+
# mongod files - also files used in tools. present in dbtests, but not in mongos and not in client
# libs.
serverOnlyFiles = [
@@ -826,6 +845,7 @@ serveronlyLibdeps = [
"$BUILD_DIR/mongo/db/storage/mmap_v1/file_allocator",
"$BUILD_DIR/third_party/shim_snappy",
'$BUILD_DIR/mongo/db/ttl_collection_cache',
+ "assemble_response",
"auth/authmongod",
"background",
"catalog/catalog",
diff --git a/src/mongo/db/assemble_response.cpp b/src/mongo/db/assemble_response.cpp
new file mode 100644
index 00000000000..c2da985db30
--- /dev/null
+++ b/src/mongo/db/assemble_response.cpp
@@ -0,0 +1,655 @@
+/**
+ * Copyright (C) 2008-2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/assemble_response.h"
+
+#include "mongo/db/audit.h"
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/catalog/cursor_manager.h"
+#include "mongo/db/commands/fsync.h"
+#include "mongo/db/curop.h"
+#include "mongo/db/curop_metrics.h"
+#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/diag_log.h"
+#include "mongo/db/introspect.h"
+#include "mongo/db/jsobj.h"
+#include "mongo/db/lasterror.h"
+#include "mongo/db/ops/write_ops_exec.h"
+#include "mongo/db/ops/write_ops_parsers.h"
+#include "mongo/db/query/find.h"
+#include "mongo/db/run_commands.h"
+#include "mongo/db/s/sharded_connection_info.h"
+#include "mongo/db/s/sharding_state.h"
+#include "mongo/db/stats/counters.h"
+#include "mongo/db/stats/top.h"
+#include "mongo/rpc/command_reply_builder.h"
+#include "mongo/rpc/command_request.h"
+#include "mongo/rpc/legacy_reply_builder.h"
+#include "mongo/rpc/legacy_request.h"
+#include "mongo/s/stale_exception.h"
+#include "mongo/util/fail_point_service.h"
+#include "mongo/util/log.h"
+#include "mongo/util/net/message.h"
+
+namespace mongo {
+
+const HostAndPort kHostAndPortForDirectClient("0.0.0.0", 0);
+
+MONGO_FP_DECLARE(rsStopGetMore);
+
+namespace {
+using logger::LogComponent;
+
+inline void opread(Message& m) {
+ if (_diaglog.getLevel() & 2) {
+ _diaglog.readop(m.singleData().view2ptr(), m.header().getLen());
+ }
+}
+
+inline void opwrite(Message& m) {
+ if (_diaglog.getLevel() & 1) {
+ _diaglog.writeop(m.singleData().view2ptr(), m.header().getLen());
+ }
+}
+
+void generateLegacyQueryErrorResponse(const AssertionException* exception,
+ const QueryMessage& queryMessage,
+ CurOp* curop,
+ Message* response) {
+ curop->debug().exceptionInfo = exception->getInfo();
+
+ log(LogComponent::kQuery) << "assertion " << exception->toString() << " ns:" << queryMessage.ns
+ << " query:" << (queryMessage.query.valid(BSONVersion::kLatest)
+ ? queryMessage.query.toString()
+ : "query object is corrupt");
+ if (queryMessage.ntoskip || queryMessage.ntoreturn) {
+ log(LogComponent::kQuery) << " ntoskip:" << queryMessage.ntoskip
+ << " ntoreturn:" << queryMessage.ntoreturn;
+ }
+
+ const SendStaleConfigException* scex = (exception->getCode() == ErrorCodes::SendStaleConfig)
+ ? static_cast<const SendStaleConfigException*>(exception)
+ : NULL;
+
+ BSONObjBuilder err;
+ exception->getInfo().append(err);
+ if (scex) {
+ err.append("ok", 0.0);
+ err.append("ns", scex->getns());
+ scex->getVersionReceived().addToBSON(err, "vReceived");
+ scex->getVersionWanted().addToBSON(err, "vWanted");
+ }
+ BSONObj errObj = err.done();
+
+ if (scex) {
+ log(LogComponent::kQuery) << "stale version detected during query over " << queryMessage.ns
+ << " : " << errObj;
+ }
+
+ BufBuilder bb;
+ bb.skip(sizeof(QueryResult::Value));
+ bb.appendBuf((void*)errObj.objdata(), errObj.objsize());
+
+ // TODO: call replyToQuery() from here instead of this!!! see dbmessage.h
+ QueryResult::View msgdata = bb.buf();
+ QueryResult::View qr = msgdata;
+ qr.setResultFlags(ResultFlag_ErrSet);
+ if (scex)
+ qr.setResultFlags(qr.getResultFlags() | ResultFlag_ShardConfigStale);
+ qr.msgdata().setLen(bb.len());
+ qr.msgdata().setOperation(opReply);
+ qr.setCursorId(0);
+ qr.setStartingFrom(0);
+ qr.setNReturned(1);
+ response->setData(bb.release());
+}
+
+/**
+ * Fills out CurOp / OpDebug with basic command info.
+ */
+void beginCommandOp(OperationContext* txn, const NamespaceString& nss, const BSONObj& queryObj) {
+ auto curop = CurOp::get(txn);
+ stdx::lock_guard<Client> lk(*txn->getClient());
+ curop->setQuery_inlock(queryObj);
+ curop->setNS_inlock(nss.ns());
+}
+
+void receivedCommand(OperationContext* txn,
+ const NamespaceString& nss,
+ Client& client,
+ DbResponse& dbResponse,
+ Message& message) {
+ invariant(nss.isCommand());
+
+ const int32_t responseToMsgId = message.header().getId();
+
+ DbMessage dbMessage(message);
+ QueryMessage queryMessage(dbMessage);
+
+ CurOp* op = CurOp::get(txn);
+
+ rpc::LegacyReplyBuilder builder{};
+
+ try {
+ // This will throw if the request is on an invalid namespace.
+ rpc::LegacyRequest request{&message};
+ // Auth checking for Commands happens later.
+ int nToReturn = queryMessage.ntoreturn;
+
+ beginCommandOp(txn, nss, request.getCommandArgs());
+
+ {
+ stdx::lock_guard<Client> lk(*txn->getClient());
+ op->markCommand_inlock();
+ }
+
+ uassert(16979,
+ str::stream() << "bad numberToReturn (" << nToReturn
+ << ") for $cmd type ns - can only be 1 or -1",
+ nToReturn == 1 || nToReturn == -1);
+
+ runCommands(txn, request, &builder);
+
+ op->debug().iscommand = true;
+ } catch (const DBException& exception) {
+ Command::generateErrorResponse(txn, &builder, exception);
+ }
+
+ auto response = builder.done();
+
+ op->debug().responseLength = response.header().dataLen();
+
+ dbResponse.response = std::move(response);
+ dbResponse.responseToMsgId = responseToMsgId;
+}
+
+void receivedRpc(OperationContext* txn, Client& client, DbResponse& dbResponse, Message& message) {
+ invariant(message.operation() == dbCommand);
+
+ const int32_t responseToMsgId = message.header().getId();
+
+ rpc::CommandReplyBuilder replyBuilder{};
+
+ auto curOp = CurOp::get(txn);
+
+ try {
+ // database is validated here
+ rpc::CommandRequest request{&message};
+
+ // We construct a legacy $cmd namespace so we can fill in curOp using
+ // the existing logic that existed for OP_QUERY commands
+ NamespaceString nss(request.getDatabase(), "$cmd");
+ beginCommandOp(txn, nss, request.getCommandArgs());
+ {
+ stdx::lock_guard<Client> lk(*txn->getClient());
+ curOp->markCommand_inlock();
+ }
+
+ runCommands(txn, request, &replyBuilder);
+
+ curOp->debug().iscommand = true;
+
+ } catch (const DBException& exception) {
+ Command::generateErrorResponse(txn, &replyBuilder, exception);
+ }
+
+ auto response = replyBuilder.done();
+
+ curOp->debug().responseLength = response.header().dataLen();
+
+ dbResponse.response = std::move(response);
+ dbResponse.responseToMsgId = responseToMsgId;
+}
+
+// In SERVER-7775 we reimplemented the pseudo-commands fsyncUnlock, inProg, and killOp
+// as ordinary commands. To support old clients for another release, this helper serves
+// to execute the real command from the legacy pseudo-command codepath.
+// TODO: remove after MongoDB 3.2 is released
+void receivedPseudoCommand(OperationContext* txn,
+ Client& client,
+ DbResponse& dbResponse,
+ Message& message,
+ StringData realCommandName) {
+ DbMessage originalDbm(message);
+
+ auto originalNToSkip = originalDbm.pullInt();
+
+ uassert(ErrorCodes::InvalidOptions,
+ str::stream() << "invalid nToSkip - expected 0, but got " << originalNToSkip,
+ originalNToSkip == 0);
+
+ auto originalNToReturn = originalDbm.pullInt();
+
+ uassert(ErrorCodes::InvalidOptions,
+ str::stream() << "invalid nToReturn - expected -1 or 1, but got " << originalNToSkip,
+ originalNToReturn == -1 || originalNToReturn == 1);
+
+ auto cmdParams = originalDbm.nextJsObj();
+
+ Message interposed;
+ // HACK:
+ // legacy pseudo-commands could run on any database. The command replacements
+ // can only run on 'admin'. To avoid breaking old shells and a multitude
+ // of third-party tools, we rewrite the namespace. As auth is checked
+ // later in Command::_checkAuthorizationImpl, we will still properly
+ // reject the request if the client is not authorized.
+ NamespaceString interposedNss("admin", "$cmd");
+
+ BSONObjBuilder cmdBob;
+ cmdBob.append(realCommandName, 1);
+ cmdBob.appendElements(cmdParams);
+ auto cmd = cmdBob.done();
+
+ // TODO: use OP_COMMAND here instead of constructing
+ // a legacy OP_QUERY style command
+ BufBuilder cmdMsgBuf;
+
+ int32_t flags = DataView(message.header().data()).read<LittleEndian<int32_t>>();
+ cmdMsgBuf.appendNum(flags);
+
+ cmdMsgBuf.appendStr(interposedNss.db(), false); // not including null byte
+ cmdMsgBuf.appendStr(".$cmd");
+ cmdMsgBuf.appendNum(0); // ntoskip
+ cmdMsgBuf.appendNum(1); // ntoreturn
+ cmdMsgBuf.appendBuf(cmd.objdata(), cmd.objsize());
+
+ interposed.setData(dbQuery, cmdMsgBuf.buf(), cmdMsgBuf.len());
+ interposed.header().setId(message.header().getId());
+
+ receivedCommand(txn, interposedNss, client, dbResponse, interposed);
+}
+
+void receivedQuery(OperationContext* txn,
+ const NamespaceString& nss,
+ Client& c,
+ DbResponse& dbResponse,
+ Message& m) {
+ invariant(!nss.isCommand());
+ globalOpCounters.gotQuery();
+
+ int32_t responseToMsgId = m.header().getId();
+
+ DbMessage d(m);
+ QueryMessage q(d);
+
+ CurOp& op = *CurOp::get(txn);
+
+ try {
+ Client* client = txn->getClient();
+ Status status = AuthorizationSession::get(client)->checkAuthForFind(nss, false);
+ audit::logQueryAuthzCheck(client, nss, q.query, status.code());
+ uassertStatusOK(status);
+
+ dbResponse.exhaustNS = runQuery(txn, q, nss, dbResponse.response);
+ } catch (const AssertionException& e) {
+ // If we got a stale config, wait in case the operation is stuck in a critical section
+ if (e.getCode() == ErrorCodes::SendStaleConfig) {
+ auto& sce = static_cast<const StaleConfigException&>(e);
+ ShardingState::get(txn)->onStaleShardVersion(
+ txn, NamespaceString(sce.getns()), sce.getVersionReceived());
+ }
+
+ dbResponse.response.reset();
+ generateLegacyQueryErrorResponse(&e, q, &op, &dbResponse.response);
+ }
+
+ op.debug().responseLength = dbResponse.response.header().dataLen();
+ dbResponse.responseToMsgId = responseToMsgId;
+}
+
+void receivedKillCursors(OperationContext* txn, Message& m) {
+ LastError::get(txn->getClient()).disable();
+ DbMessage dbmessage(m);
+ int n = dbmessage.pullInt();
+
+ uassert(13659, "sent 0 cursors to kill", n != 0);
+ massert(13658,
+ str::stream() << "bad kill cursors size: " << m.dataSize(),
+ m.dataSize() == 8 + (8 * n));
+ uassert(13004, str::stream() << "sent negative cursors to kill: " << n, n >= 1);
+
+ if (n > 2000) {
+ (n < 30000 ? warning() : error()) << "receivedKillCursors, n=" << n;
+ verify(n < 30000);
+ }
+
+ const char* cursorArray = dbmessage.getArray(n);
+
+ int found = CursorManager::eraseCursorGlobalIfAuthorized(txn, n, cursorArray);
+
+ if (shouldLog(logger::LogSeverity::Debug(1)) || found != n) {
+ LOG(found == n ? 1 : 0) << "killcursors: found " << found << " of " << n;
+ }
+}
+
+void receivedInsert(OperationContext* txn, const NamespaceString& nsString, Message& m) {
+ auto insertOp = parseLegacyInsert(m);
+ invariant(insertOp.ns == nsString);
+ for (const auto& obj : insertOp.documents) {
+ Status status =
+ AuthorizationSession::get(txn->getClient())->checkAuthForInsert(txn, nsString, obj);
+ audit::logInsertAuthzCheck(txn->getClient(), nsString, obj, status.code());
+ uassertStatusOK(status);
+ }
+ performInserts(txn, insertOp);
+}
+
+void receivedUpdate(OperationContext* txn, const NamespaceString& nsString, Message& m) {
+ auto updateOp = parseLegacyUpdate(m);
+ auto& singleUpdate = updateOp.updates[0];
+ invariant(updateOp.ns == nsString);
+
+ Status status =
+ AuthorizationSession::get(txn->getClient())
+ ->checkAuthForUpdate(
+ txn, nsString, singleUpdate.query, singleUpdate.update, singleUpdate.upsert);
+ audit::logUpdateAuthzCheck(txn->getClient(),
+ nsString,
+ singleUpdate.query,
+ singleUpdate.update,
+ singleUpdate.upsert,
+ singleUpdate.multi,
+ status.code());
+ uassertStatusOK(status);
+
+ performUpdates(txn, updateOp);
+}
+
+void receivedDelete(OperationContext* txn, const NamespaceString& nsString, Message& m) {
+ auto deleteOp = parseLegacyDelete(m);
+ auto& singleDelete = deleteOp.deletes[0];
+ invariant(deleteOp.ns == nsString);
+
+ Status status = AuthorizationSession::get(txn->getClient())
+ ->checkAuthForDelete(txn, nsString, singleDelete.query);
+ audit::logDeleteAuthzCheck(txn->getClient(), nsString, singleDelete.query, status.code());
+ uassertStatusOK(status);
+
+ performDeletes(txn, deleteOp);
+}
+
+bool receivedGetMore(OperationContext* txn, DbResponse& dbresponse, Message& m, CurOp& curop) {
+ globalOpCounters.gotGetMore();
+ DbMessage d(m);
+
+ const char* ns = d.getns();
+ int ntoreturn = d.pullInt();
+ uassert(
+ 34419, str::stream() << "Invalid ntoreturn for OP_GET_MORE: " << ntoreturn, ntoreturn >= 0);
+ long long cursorid = d.pullInt64();
+
+ curop.debug().ntoreturn = ntoreturn;
+ curop.debug().cursorid = cursorid;
+
+ {
+ stdx::lock_guard<Client>(*txn->getClient());
+ CurOp::get(txn)->setNS_inlock(ns);
+ }
+
+ bool exhaust = false;
+ bool isCursorAuthorized = false;
+
+ try {
+ const NamespaceString nsString(ns);
+ uassert(ErrorCodes::InvalidNamespace,
+ str::stream() << "Invalid ns [" << ns << "]",
+ nsString.isValid());
+
+ Status status = AuthorizationSession::get(txn->getClient())
+ ->checkAuthForGetMore(nsString, cursorid, false);
+ audit::logGetMoreAuthzCheck(txn->getClient(), nsString, cursorid, status.code());
+ uassertStatusOK(status);
+
+ while (MONGO_FAIL_POINT(rsStopGetMore)) {
+ sleepmillis(0);
+ }
+
+ dbresponse.response = getMore(txn, ns, ntoreturn, cursorid, &exhaust, &isCursorAuthorized);
+ } catch (AssertionException& e) {
+ if (isCursorAuthorized) {
+ // If a cursor with id 'cursorid' was authorized, it may have been advanced
+ // before an exception terminated processGetMore. Erase the ClientCursor
+ // because it may now be out of sync with the client's iteration state.
+ // SERVER-7952
+ // TODO Temporary code, see SERVER-4563 for a cleanup overview.
+ CursorManager::eraseCursorGlobal(txn, cursorid);
+ }
+
+ BSONObjBuilder err;
+ e.getInfo().append(err);
+ BSONObj errObj = err.done();
+
+ curop.debug().exceptionInfo = e.getInfo();
+
+ replyToQuery(ResultFlag_ErrSet, m, dbresponse, errObj);
+ curop.debug().responseLength = dbresponse.response.header().dataLen();
+ curop.debug().nreturned = 1;
+ return false;
+ }
+
+ curop.debug().responseLength = dbresponse.response.header().dataLen();
+ auto queryResult = QueryResult::ConstView(dbresponse.response.buf());
+ curop.debug().nreturned = queryResult.getNReturned();
+
+ dbresponse.responseToMsgId = m.header().getId();
+
+ if (exhaust) {
+ curop.debug().exhaust = true;
+ dbresponse.exhaustNS = ns;
+ }
+
+ return true;
+}
+
+} // namespace
+
+// Returns false when request includes 'end'
+void assembleResponse(OperationContext* txn,
+ Message& m,
+ DbResponse& dbresponse,
+ const HostAndPort& remote) {
+ // before we lock...
+ NetworkOp op = m.operation();
+ bool isCommand = false;
+
+ DbMessage dbmsg(m);
+
+ Client& c = *txn->getClient();
+ if (c.isInDirectClient()) {
+ invariant(!txn->lockState()->inAWriteUnitOfWork());
+ } else {
+ LastError::get(c).startRequest();
+ AuthorizationSession::get(c)->startRequest(txn);
+
+ // We should not be holding any locks at this point
+ invariant(!txn->lockState()->isLocked());
+ }
+
+ const char* ns = dbmsg.messageShouldHaveNs() ? dbmsg.getns() : NULL;
+ const NamespaceString nsString = ns ? NamespaceString(ns) : NamespaceString();
+
+ if (op == dbQuery) {
+ if (nsString.isCommand()) {
+ isCommand = true;
+ opwrite(m);
+ }
+ // TODO: remove this entire code path after 3.2. Refs SERVER-7775
+ else if (nsString.isSpecialCommand()) {
+ opwrite(m);
+
+ if (nsString.coll() == "$cmd.sys.inprog") {
+ receivedPseudoCommand(txn, c, dbresponse, m, "currentOp");
+ return;
+ }
+ if (nsString.coll() == "$cmd.sys.killop") {
+ receivedPseudoCommand(txn, c, dbresponse, m, "killOp");
+ return;
+ }
+ if (nsString.coll() == "$cmd.sys.unlock") {
+ receivedPseudoCommand(txn, c, dbresponse, m, "fsyncUnlock");
+ return;
+ }
+ } else {
+ opread(m);
+ }
+ } else if (op == dbGetMore) {
+ opread(m);
+ } else if (op == dbCommand) {
+ isCommand = true;
+ opwrite(m);
+ } else {
+ opwrite(m);
+ }
+
+ CurOp& currentOp = *CurOp::get(txn);
+ {
+ stdx::lock_guard<Client> lk(*txn->getClient());
+ // Commands handling code will reset this if the operation is a command
+ // which is logically a basic CRUD operation like query, insert, etc.
+ currentOp.setNetworkOp_inlock(op);
+ currentOp.setLogicalOp_inlock(networkOpToLogicalOp(op));
+ }
+
+ OpDebug& debug = currentOp.debug();
+
+ long long logThresholdMs = serverGlobalParams.slowMS;
+ bool shouldLogOpDebug = shouldLog(logger::LogSeverity::Debug(1));
+
+ if (op == dbQuery) {
+ if (isCommand) {
+ receivedCommand(txn, nsString, c, dbresponse, m);
+ } else {
+ receivedQuery(txn, nsString, c, dbresponse, m);
+ }
+ } else if (op == dbCommand) {
+ receivedRpc(txn, c, dbresponse, m);
+ } else if (op == dbGetMore) {
+ if (!receivedGetMore(txn, dbresponse, m, currentOp))
+ shouldLogOpDebug = true;
+ } else if (op == dbMsg) {
+ // deprecated - replaced by commands
+ const char* p = dbmsg.getns();
+
+ int len = strlen(p);
+ if (len > 400)
+ log() << curTimeMillis64() % 10000 << " long msg received, len:" << len;
+
+ if (strcmp("end", p) == 0)
+ dbresponse.response.setData(opReply, "dbMsg end no longer supported");
+ else
+ dbresponse.response.setData(opReply, "i am fine - dbMsg deprecated");
+
+ dbresponse.responseToMsgId = m.header().getId();
+ } else {
+ // The remaining operations do not return any response. They are fire-and-forget.
+ try {
+ if (op == dbKillCursors) {
+ currentOp.ensureStarted();
+ logThresholdMs = 10;
+ receivedKillCursors(txn, m);
+ } else if (op != dbInsert && op != dbUpdate && op != dbDelete) {
+ log() << " operation isn't supported: " << static_cast<int>(op);
+ currentOp.done();
+ shouldLogOpDebug = true;
+ } else {
+ if (remote != kHostAndPortForDirectClient) {
+ const ShardedConnectionInfo* connInfo = ShardedConnectionInfo::get(&c, false);
+ uassert(18663,
+ str::stream() << "legacy writeOps not longer supported for "
+ << "versioned connections, ns: "
+ << nsString.ns()
+ << ", op: "
+ << networkOpToString(op)
+ << ", remote: "
+ << remote.toString(),
+ connInfo == NULL);
+ }
+
+ if (!nsString.isValid()) {
+ uassert(16257, str::stream() << "Invalid ns [" << ns << "]", false);
+ } else if (op == dbInsert) {
+ receivedInsert(txn, nsString, m);
+ } else if (op == dbUpdate) {
+ receivedUpdate(txn, nsString, m);
+ } else if (op == dbDelete) {
+ receivedDelete(txn, nsString, m);
+ } else {
+ invariant(false);
+ }
+ }
+ } catch (const UserException& ue) {
+ LastError::get(c).setLastError(ue.getCode(), ue.getInfo().msg);
+ LOG(3) << " Caught Assertion in " << networkOpToString(op) << ", continuing "
+ << redact(ue);
+ debug.exceptionInfo = ue.getInfo();
+ } catch (const AssertionException& e) {
+ LastError::get(c).setLastError(e.getCode(), e.getInfo().msg);
+ LOG(3) << " Caught Assertion in " << networkOpToString(op) << ", continuing "
+ << redact(e);
+ debug.exceptionInfo = e.getInfo();
+ shouldLogOpDebug = true;
+ }
+ }
+ currentOp.ensureStarted();
+ currentOp.done();
+ debug.executionTimeMicros = currentOp.totalTimeMicros();
+
+ logThresholdMs += currentOp.getExpectedLatencyMs();
+ Top::get(txn->getServiceContext())
+ .incrementGlobalLatencyStats(
+ txn, currentOp.totalTimeMicros(), currentOp.getReadWriteType());
+
+ if (shouldLogOpDebug || debug.executionTimeMicros > logThresholdMs * 1000LL) {
+ Locker::LockerInfo lockerInfo;
+ txn->lockState()->getLockerInfo(&lockerInfo);
+ log() << debug.report(&c, currentOp, lockerInfo.stats);
+ }
+
+ if (currentOp.shouldDBProfile()) {
+ // Performance profiling is on
+ if (txn->lockState()->isReadLocked()) {
+ LOG(1) << "note: not profiling because recursive read lock";
+ } else if (lockedForWriting()) {
+ // TODO SERVER-26825: Fix race condition where fsyncLock is acquired post
+ // lockedForWriting() call but prior to profile collection lock acquisition.
+ LOG(1) << "note: not profiling because doing fsync+lock";
+ } else if (storageGlobalParams.readOnly) {
+ LOG(1) << "note: not profiling because server is read-only";
+ } else {
+ profile(txn, op);
+ }
+ }
+
+ recordCurOpMetrics(txn);
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/assemble_response.h b/src/mongo/db/assemble_response.h
new file mode 100644
index 00000000000..c8c71fd9aad
--- /dev/null
+++ b/src/mongo/db/assemble_response.h
@@ -0,0 +1,48 @@
+/**
+* Copyright (C) 2008 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects for
+* all of the code used other than as permitted herein. If you modify file(s)
+* with this exception, you may extend this exception to your version of the
+* file(s), but you are not obligated to do so. If you do not wish to do so,
+* delete this exception statement from your version. If you delete this
+* exception statement from all source files in the program, then also delete
+* it in the license file.
+*/
+
+#pragma once
+
+#include "mongo/util/net/hostandport.h"
+
+namespace mongo {
+
+struct DbResponse;
+class Message;
+class OperationContext;
+
+// Pass this as the 'client' argument to assembleResponse
+// to indicate that the call is on behalf of a DBDirectClient.
+extern const HostAndPort kHostAndPortForDirectClient;
+
+void assembleResponse(OperationContext* txn,
+ Message& m,
+ DbResponse& dbresponse,
+ const HostAndPort& client);
+
+} // namespace mongo
diff --git a/src/mongo/db/auth/authz_session_external_state_d.cpp b/src/mongo/db/auth/authz_session_external_state_d.cpp
index dee99046240..25298b2823b 100644
--- a/src/mongo/db/auth/authz_session_external_state_d.cpp
+++ b/src/mongo/db/auth/authz_session_external_state_d.cpp
@@ -33,7 +33,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/client.h"
#include "mongo/db/dbhelpers.h"
-#include "mongo/db/instance.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/replication_coordinator_global.h"
diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp
index 7361e1f4f4c..5d4ff27c56e 100644
--- a/src/mongo/db/catalog/database.cpp
+++ b/src/mongo/db/catalog/database.cpp
@@ -50,7 +50,6 @@
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/index/index_access_method.h"
-#include "mongo/db/instance.h"
#include "mongo/db/introspect.h"
#include "mongo/db/op_observer.h"
#include "mongo/db/query/collation/collator_factory_interface.h"
diff --git a/src/mongo/db/commands/clone_collection.cpp b/src/mongo/db/commands/clone_collection.cpp
index a7cf1e04017..512c9d7b737 100644
--- a/src/mongo/db/commands/clone_collection.cpp
+++ b/src/mongo/db/commands/clone_collection.cpp
@@ -45,7 +45,6 @@
#include "mongo/db/commands/rename_collection.h"
#include "mongo/db/db.h"
#include "mongo/db/index_builder.h"
-#include "mongo/db/instance.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/ops/insert.h"
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index 9aeaa83a3e9..a7bfbc9d351 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -69,7 +69,6 @@
#include "mongo/db/index/index_access_method.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/index_builder.h"
-#include "mongo/db/instance.h"
#include "mongo/db/introspect.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp
index 2543e4879bc..1b129780fa7 100644
--- a/src/mongo/db/commands/distinct.cpp
+++ b/src/mongo/db/commands/distinct.cpp
@@ -47,7 +47,6 @@
#include "mongo/db/commands.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/working_set_common.h"
-#include "mongo/db/instance.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/matcher/extensions_callback_real.h"
#include "mongo/db/query/cursor_response.h"
diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp
index ae173c44942..57e96ac75c7 100644
--- a/src/mongo/db/commands/generic.cpp
+++ b/src/mongo/db/commands/generic.cpp
@@ -42,7 +42,6 @@
#include "mongo/db/commands.h"
#include "mongo/db/commands/shutdown.h"
#include "mongo/db/db.h"
-#include "mongo/db/instance.h"
#include "mongo/db/introspect.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 093ffefa1db..fd45c5dd115 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -51,7 +51,6 @@
#include "mongo/db/dbhelpers.h"
#include "mongo/db/exec/working_set_common.h"
#include "mongo/db/index/index_descriptor.h"
-#include "mongo/db/instance.h"
#include "mongo/db/matcher/extensions_callback_real.h"
#include "mongo/db/matcher/matcher.h"
#include "mongo/db/namespace_string.h"
diff --git a/src/mongo/db/dbdirectclient.cpp b/src/mongo/db/dbdirectclient.cpp
index f4bf62ed644..40fcdb79dc2 100644
--- a/src/mongo/db/dbdirectclient.cpp
+++ b/src/mongo/db/dbdirectclient.cpp
@@ -32,9 +32,10 @@
#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/assemble_response.h"
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
-#include "mongo/db/instance.h"
+#include "mongo/db/curop.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/wire_version.h"
@@ -124,7 +125,7 @@ bool DBDirectClient::call(Message& toSend, Message& response, bool assertOk, str
DbResponse dbResponse;
CurOp curOp(_txn);
- assembleResponse(_txn, toSend, dbResponse, dummyHost);
+ assembleResponse(_txn, toSend, dbResponse, kHostAndPortForDirectClient);
verify(!dbResponse.response.empty());
response = std::move(dbResponse.response);
@@ -137,7 +138,7 @@ void DBDirectClient::say(Message& toSend, bool isRetry, string* actualServer) {
DbResponse dbResponse;
CurOp curOp(_txn);
- assembleResponse(_txn, toSend, dbResponse, dummyHost);
+ assembleResponse(_txn, toSend, dbResponse, kHostAndPortForDirectClient);
}
unique_ptr<DBClientCursor> DBDirectClient::query(const string& ns,
@@ -151,8 +152,6 @@ unique_ptr<DBClientCursor> DBDirectClient::query(const string& ns,
ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions, batchSize);
}
-const HostAndPort DBDirectClient::dummyHost("0.0.0.0", 0);
-
unsigned long long DBDirectClient::count(
const string& ns, const BSONObj& query, int options, int limit, int skip) {
BSONObj cmdObj = _countCmd(ns, query, options, limit, skip);
diff --git a/src/mongo/db/dbdirectclient.h b/src/mongo/db/dbdirectclient.h
index d4d187ff91c..1bd4c407f8a 100644
--- a/src/mongo/db/dbdirectclient.h
+++ b/src/mongo/db/dbdirectclient.h
@@ -49,8 +49,6 @@ class OperationContext;
*/
class DBDirectClient : public DBClientBase {
public:
- static const HostAndPort dummyHost;
-
DBDirectClient(OperationContext* txn);
using DBClientBase::query;
diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp
index b202e0500b9..41b097c5718 100644
--- a/src/mongo/db/dbwebserver.cpp
+++ b/src/mongo/db/dbwebserver.cpp
@@ -47,7 +47,6 @@
#include "mongo/db/background.h"
#include "mongo/db/commands.h"
#include "mongo/db/db.h"
-#include "mongo/db/instance.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
#include "mongo/db/stats/snapshots.h"
diff --git a/src/mongo/db/index_rebuilder.cpp b/src/mongo/db/index_rebuilder.cpp
index 2d4c40f5747..c42cbc1dcee 100644
--- a/src/mongo/db/index_rebuilder.cpp
+++ b/src/mongo/db/index_rebuilder.cpp
@@ -43,7 +43,6 @@
#include "mongo/db/catalog/index_create.h"
#include "mongo/db/client.h"
#include "mongo/db/db_raii.h"
-#include "mongo/db/instance.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/util/log.h"
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 367709954f0..10283a3d972 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -30,103 +30,23 @@
#include "mongo/platform/basic.h"
-#include <fstream>
+#include "mongo/db/instance.h"
+
#include <memory>
#include "mongo/base/init.h"
-#include "mongo/base/status.h"
-#include "mongo/db/audit.h"
-#include "mongo/db/auth/action_type.h"
-#include "mongo/db/auth/authorization_manager.h"
-#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/authz_manager_external_state_d.h"
-#include "mongo/db/catalog/cursor_manager.h"
-#include "mongo/db/client.h"
-#include "mongo/db/commands.h"
-#include "mongo/db/commands/fsync.h"
-#include "mongo/db/concurrency/d_concurrency.h"
-#include "mongo/db/concurrency/lock_state.h"
-#include "mongo/db/concurrency/write_conflict_exception.h"
-#include "mongo/db/curop_metrics.h"
-#include "mongo/db/db.h"
-#include "mongo/db/db_raii.h"
-#include "mongo/db/dbdirectclient.h"
-#include "mongo/db/dbmessage.h"
-#include "mongo/db/diag_log.h"
-#include "mongo/db/ftdc/ftdc_mongod.h"
-#include "mongo/db/global_timestamp.h"
-#include "mongo/db/instance.h"
-#include "mongo/db/introspect.h"
-#include "mongo/db/json.h"
-#include "mongo/db/lasterror.h"
-#include "mongo/db/matcher/matcher.h"
-#include "mongo/db/mongod_options.h"
-#include "mongo/db/namespace_string.h"
-#include "mongo/db/op_observer.h"
-#include "mongo/db/ops/write_ops_exec.h"
-#include "mongo/db/ops/write_ops_parsers.h"
-#include "mongo/db/query/find.h"
-#include "mongo/db/query/get_executor.h"
-#include "mongo/db/run_commands.h"
-#include "mongo/db/s/sharded_connection_info.h"
-#include "mongo/db/s/sharding_state.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/stats/counters.h"
-#include "mongo/db/stats/top.h"
-#include "mongo/db/storage/storage_engine.h"
-#include "mongo/db/storage/storage_options.h"
-#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/process_id.h"
-#include "mongo/rpc/command_reply_builder.h"
-#include "mongo/rpc/command_request.h"
-#include "mongo/rpc/legacy_reply.h"
-#include "mongo/rpc/legacy_reply_builder.h"
-#include "mongo/rpc/legacy_request.h"
-#include "mongo/rpc/legacy_request_builder.h"
-#include "mongo/rpc/metadata.h"
-#include "mongo/rpc/request_interface.h"
-#include "mongo/s/stale_exception.h" // for SendStaleConfigException
-#include "mongo/scripting/engine.h"
#include "mongo/stdx/memory.h"
-#include "mongo/stdx/thread.h"
-#include "mongo/util/exit.h"
-#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
-#include "mongo/util/mongoutils/str.h"
-#include "mongo/util/quick_exit.h"
-#include "mongo/util/scopeguard.h"
-#include "mongo/util/time_support.h"
namespace mongo {
-using logger::LogComponent;
-using std::endl;
-using std::hex;
-using std::ios;
-using std::ofstream;
using std::string;
-using std::stringstream;
using std::unique_ptr;
-using std::vector;
string dbExecCommand;
-MONGO_FP_DECLARE(rsStopGetMore);
-
namespace {
-// for diaglog
-inline void opread(Message& m) {
- if (_diaglog.getLevel() & 2) {
- _diaglog.readop(m.singleData().view2ptr(), m.header().getLen());
- }
-}
-
-inline void opwrite(Message& m) {
- if (_diaglog.getLevel() & 1) {
- _diaglog.writeop(m.singleData().view2ptr(), m.header().getLen());
- }
-}
-
unique_ptr<AuthzManagerExternalState> createAuthzManagerExternalStateMongod() {
return stdx::make_unique<AuthzManagerExternalStateMongod>();
}
@@ -136,395 +56,6 @@ MONGO_INITIALIZER(CreateAuthorizationExternalStateFactory)(InitializerContext* c
return Status::OK();
}
-void generateLegacyQueryErrorResponse(const AssertionException* exception,
- const QueryMessage& queryMessage,
- CurOp* curop,
- Message* response) {
- curop->debug().exceptionInfo = exception->getInfo();
-
- log(LogComponent::kQuery) << "assertion " << exception->toString() << " ns:" << queryMessage.ns
- << " query:" << (queryMessage.query.valid(BSONVersion::kLatest)
- ? queryMessage.query.toString()
- : "query object is corrupt");
- if (queryMessage.ntoskip || queryMessage.ntoreturn) {
- log(LogComponent::kQuery) << " ntoskip:" << queryMessage.ntoskip
- << " ntoreturn:" << queryMessage.ntoreturn;
- }
-
- const SendStaleConfigException* scex = (exception->getCode() == ErrorCodes::SendStaleConfig)
- ? static_cast<const SendStaleConfigException*>(exception)
- : NULL;
-
- BSONObjBuilder err;
- exception->getInfo().append(err);
- if (scex) {
- err.append("ok", 0.0);
- err.append("ns", scex->getns());
- scex->getVersionReceived().addToBSON(err, "vReceived");
- scex->getVersionWanted().addToBSON(err, "vWanted");
- }
- BSONObj errObj = err.done();
-
- if (scex) {
- log(LogComponent::kQuery) << "stale version detected during query over " << queryMessage.ns
- << " : " << errObj;
- }
-
- BufBuilder bb;
- bb.skip(sizeof(QueryResult::Value));
- bb.appendBuf((void*)errObj.objdata(), errObj.objsize());
-
- // TODO: call replyToQuery() from here instead of this!!! see dbmessage.h
- QueryResult::View msgdata = bb.buf();
- QueryResult::View qr = msgdata;
- qr.setResultFlags(ResultFlag_ErrSet);
- if (scex)
- qr.setResultFlags(qr.getResultFlags() | ResultFlag_ShardConfigStale);
- qr.msgdata().setLen(bb.len());
- qr.msgdata().setOperation(opReply);
- qr.setCursorId(0);
- qr.setStartingFrom(0);
- qr.setNReturned(1);
- response->setData(bb.release());
-}
-
-/**
- * Fills out CurOp / OpDebug with basic command info.
- */
-void beginCommandOp(OperationContext* txn, const NamespaceString& nss, const BSONObj& queryObj) {
- auto curop = CurOp::get(txn);
- stdx::lock_guard<Client> lk(*txn->getClient());
- curop->setQuery_inlock(queryObj);
- curop->setNS_inlock(nss.ns());
-}
-
-void receivedCommand(OperationContext* txn,
- const NamespaceString& nss,
- Client& client,
- DbResponse& dbResponse,
- Message& message) {
- invariant(nss.isCommand());
-
- const int32_t responseToMsgId = message.header().getId();
-
- DbMessage dbMessage(message);
- QueryMessage queryMessage(dbMessage);
-
- CurOp* op = CurOp::get(txn);
-
- rpc::LegacyReplyBuilder builder{};
-
- try {
- // This will throw if the request is on an invalid namespace.
- rpc::LegacyRequest request{&message};
- // Auth checking for Commands happens later.
- int nToReturn = queryMessage.ntoreturn;
-
- beginCommandOp(txn, nss, request.getCommandArgs());
-
- {
- stdx::lock_guard<Client> lk(*txn->getClient());
- op->markCommand_inlock();
- }
-
- uassert(16979,
- str::stream() << "bad numberToReturn (" << nToReturn
- << ") for $cmd type ns - can only be 1 or -1",
- nToReturn == 1 || nToReturn == -1);
-
- runCommands(txn, request, &builder);
-
- op->debug().iscommand = true;
- } catch (const DBException& exception) {
- Command::generateErrorResponse(txn, &builder, exception);
- }
-
- auto response = builder.done();
-
- op->debug().responseLength = response.header().dataLen();
-
- dbResponse.response = std::move(response);
- dbResponse.responseToMsgId = responseToMsgId;
-}
-
-void receivedRpc(OperationContext* txn, Client& client, DbResponse& dbResponse, Message& message) {
- invariant(message.operation() == dbCommand);
-
- const int32_t responseToMsgId = message.header().getId();
-
- rpc::CommandReplyBuilder replyBuilder{};
-
- auto curOp = CurOp::get(txn);
-
- try {
- // database is validated here
- rpc::CommandRequest request{&message};
-
- // We construct a legacy $cmd namespace so we can fill in curOp using
- // the existing logic that existed for OP_QUERY commands
- NamespaceString nss(request.getDatabase(), "$cmd");
- beginCommandOp(txn, nss, request.getCommandArgs());
- {
- stdx::lock_guard<Client> lk(*txn->getClient());
- curOp->markCommand_inlock();
- }
-
- runCommands(txn, request, &replyBuilder);
-
- curOp->debug().iscommand = true;
-
- } catch (const DBException& exception) {
- Command::generateErrorResponse(txn, &replyBuilder, exception);
- }
-
- auto response = replyBuilder.done();
-
- curOp->debug().responseLength = response.header().dataLen();
-
- dbResponse.response = std::move(response);
- dbResponse.responseToMsgId = responseToMsgId;
-}
-
-// In SERVER-7775 we reimplemented the pseudo-commands fsyncUnlock, inProg, and killOp
-// as ordinary commands. To support old clients for another release, this helper serves
-// to execute the real command from the legacy pseudo-command codepath.
-// TODO: remove after MongoDB 3.2 is released
-void receivedPseudoCommand(OperationContext* txn,
- Client& client,
- DbResponse& dbResponse,
- Message& message,
- StringData realCommandName) {
- DbMessage originalDbm(message);
-
- auto originalNToSkip = originalDbm.pullInt();
-
- uassert(ErrorCodes::InvalidOptions,
- str::stream() << "invalid nToSkip - expected 0, but got " << originalNToSkip,
- originalNToSkip == 0);
-
- auto originalNToReturn = originalDbm.pullInt();
-
- uassert(ErrorCodes::InvalidOptions,
- str::stream() << "invalid nToReturn - expected -1 or 1, but got " << originalNToSkip,
- originalNToReturn == -1 || originalNToReturn == 1);
-
- auto cmdParams = originalDbm.nextJsObj();
-
- Message interposed;
- // HACK:
- // legacy pseudo-commands could run on any database. The command replacements
- // can only run on 'admin'. To avoid breaking old shells and a multitude
- // of third-party tools, we rewrite the namespace. As auth is checked
- // later in Command::_checkAuthorizationImpl, we will still properly
- // reject the request if the client is not authorized.
- NamespaceString interposedNss("admin", "$cmd");
-
- BSONObjBuilder cmdBob;
- cmdBob.append(realCommandName, 1);
- cmdBob.appendElements(cmdParams);
- auto cmd = cmdBob.done();
-
- // TODO: use OP_COMMAND here instead of constructing
- // a legacy OP_QUERY style command
- BufBuilder cmdMsgBuf;
-
- int32_t flags = DataView(message.header().data()).read<LittleEndian<int32_t>>();
- cmdMsgBuf.appendNum(flags);
-
- cmdMsgBuf.appendStr(interposedNss.db(), false); // not including null byte
- cmdMsgBuf.appendStr(".$cmd");
- cmdMsgBuf.appendNum(0); // ntoskip
- cmdMsgBuf.appendNum(1); // ntoreturn
- cmdMsgBuf.appendBuf(cmd.objdata(), cmd.objsize());
-
- interposed.setData(dbQuery, cmdMsgBuf.buf(), cmdMsgBuf.len());
- interposed.header().setId(message.header().getId());
-
- receivedCommand(txn, interposedNss, client, dbResponse, interposed);
-}
-
-void receivedQuery(OperationContext* txn,
- const NamespaceString& nss,
- Client& c,
- DbResponse& dbResponse,
- Message& m) {
- invariant(!nss.isCommand());
- globalOpCounters.gotQuery();
-
- int32_t responseToMsgId = m.header().getId();
-
- DbMessage d(m);
- QueryMessage q(d);
-
- CurOp& op = *CurOp::get(txn);
-
- try {
- Client* client = txn->getClient();
- Status status = AuthorizationSession::get(client)->checkAuthForFind(nss, false);
- audit::logQueryAuthzCheck(client, nss, q.query, status.code());
- uassertStatusOK(status);
-
- dbResponse.exhaustNS = runQuery(txn, q, nss, dbResponse.response);
- } catch (const AssertionException& e) {
- // If we got a stale config, wait in case the operation is stuck in a critical section
- if (e.getCode() == ErrorCodes::SendStaleConfig) {
- auto& sce = static_cast<const StaleConfigException&>(e);
- ShardingState::get(txn)->onStaleShardVersion(
- txn, NamespaceString(sce.getns()), sce.getVersionReceived());
- }
-
- dbResponse.response.reset();
- generateLegacyQueryErrorResponse(&e, q, &op, &dbResponse.response);
- }
-
- op.debug().responseLength = dbResponse.response.header().dataLen();
- dbResponse.responseToMsgId = responseToMsgId;
-}
-
-void receivedKillCursors(OperationContext* txn, Message& m) {
- LastError::get(txn->getClient()).disable();
- DbMessage dbmessage(m);
- int n = dbmessage.pullInt();
-
- uassert(13659, "sent 0 cursors to kill", n != 0);
- massert(13658,
- str::stream() << "bad kill cursors size: " << m.dataSize(),
- m.dataSize() == 8 + (8 * n));
- uassert(13004, str::stream() << "sent negative cursors to kill: " << n, n >= 1);
-
- if (n > 2000) {
- (n < 30000 ? warning() : error()) << "receivedKillCursors, n=" << n;
- verify(n < 30000);
- }
-
- const char* cursorArray = dbmessage.getArray(n);
-
- int found = CursorManager::eraseCursorGlobalIfAuthorized(txn, n, cursorArray);
-
- if (shouldLog(logger::LogSeverity::Debug(1)) || found != n) {
- LOG(found == n ? 1 : 0) << "killcursors: found " << found << " of " << n;
- }
-}
-
-void receivedInsert(OperationContext* txn, const NamespaceString& nsString, Message& m) {
- auto insertOp = parseLegacyInsert(m);
- invariant(insertOp.ns == nsString);
- for (const auto& obj : insertOp.documents) {
- Status status =
- AuthorizationSession::get(txn->getClient())->checkAuthForInsert(txn, nsString, obj);
- audit::logInsertAuthzCheck(txn->getClient(), nsString, obj, status.code());
- uassertStatusOK(status);
- }
- performInserts(txn, insertOp);
-}
-
-void receivedUpdate(OperationContext* txn, const NamespaceString& nsString, Message& m) {
- auto updateOp = parseLegacyUpdate(m);
- auto& singleUpdate = updateOp.updates[0];
- invariant(updateOp.ns == nsString);
-
- Status status =
- AuthorizationSession::get(txn->getClient())
- ->checkAuthForUpdate(
- txn, nsString, singleUpdate.query, singleUpdate.update, singleUpdate.upsert);
- audit::logUpdateAuthzCheck(txn->getClient(),
- nsString,
- singleUpdate.query,
- singleUpdate.update,
- singleUpdate.upsert,
- singleUpdate.multi,
- status.code());
- uassertStatusOK(status);
-
- performUpdates(txn, updateOp);
-}
-
-void receivedDelete(OperationContext* txn, const NamespaceString& nsString, Message& m) {
- auto deleteOp = parseLegacyDelete(m);
- auto& singleDelete = deleteOp.deletes[0];
- invariant(deleteOp.ns == nsString);
-
- Status status = AuthorizationSession::get(txn->getClient())
- ->checkAuthForDelete(txn, nsString, singleDelete.query);
- audit::logDeleteAuthzCheck(txn->getClient(), nsString, singleDelete.query, status.code());
- uassertStatusOK(status);
-
- performDeletes(txn, deleteOp);
-}
-
-bool receivedGetMore(OperationContext* txn, DbResponse& dbresponse, Message& m, CurOp& curop) {
- globalOpCounters.gotGetMore();
- DbMessage d(m);
-
- const char* ns = d.getns();
- int ntoreturn = d.pullInt();
- uassert(
- 34419, str::stream() << "Invalid ntoreturn for OP_GET_MORE: " << ntoreturn, ntoreturn >= 0);
- long long cursorid = d.pullInt64();
-
- curop.debug().ntoreturn = ntoreturn;
- curop.debug().cursorid = cursorid;
-
- {
- stdx::lock_guard<Client>(*txn->getClient());
- CurOp::get(txn)->setNS_inlock(ns);
- }
-
- bool exhaust = false;
- bool isCursorAuthorized = false;
-
- try {
- const NamespaceString nsString(ns);
- uassert(ErrorCodes::InvalidNamespace,
- str::stream() << "Invalid ns [" << ns << "]",
- nsString.isValid());
-
- Status status = AuthorizationSession::get(txn->getClient())
- ->checkAuthForGetMore(nsString, cursorid, false);
- audit::logGetMoreAuthzCheck(txn->getClient(), nsString, cursorid, status.code());
- uassertStatusOK(status);
-
- while (MONGO_FAIL_POINT(rsStopGetMore)) {
- sleepmillis(0);
- }
-
- dbresponse.response = getMore(txn, ns, ntoreturn, cursorid, &exhaust, &isCursorAuthorized);
- } catch (AssertionException& e) {
- if (isCursorAuthorized) {
- // If a cursor with id 'cursorid' was authorized, it may have been advanced
- // before an exception terminated processGetMore. Erase the ClientCursor
- // because it may now be out of sync with the client's iteration state.
- // SERVER-7952
- // TODO Temporary code, see SERVER-4563 for a cleanup overview.
- CursorManager::eraseCursorGlobal(txn, cursorid);
- }
-
- BSONObjBuilder err;
- e.getInfo().append(err);
- BSONObj errObj = err.done();
-
- curop.debug().exceptionInfo = e.getInfo();
-
- replyToQuery(ResultFlag_ErrSet, m, dbresponse, errObj);
- curop.debug().responseLength = dbresponse.response.header().dataLen();
- curop.debug().nreturned = 1;
- return false;
- }
-
- curop.debug().responseLength = dbresponse.response.header().dataLen();
- auto queryResult = QueryResult::ConstView(dbresponse.response.buf());
- curop.debug().nreturned = queryResult.getNReturned();
-
- dbresponse.responseToMsgId = m.header().getId();
-
- if (exhaust) {
- curop.debug().exhaust = true;
- dbresponse.exhaustNS = ns;
- }
-
- return true;
-}
-
} // namespace
// Mongod on win32 defines a value for this function. In all other executables it is NULL.
@@ -537,184 +68,4 @@ void mongoAbort(const char* msg) {
::abort();
}
-// Returns false when request includes 'end'
-void assembleResponse(OperationContext* txn,
- Message& m,
- DbResponse& dbresponse,
- const HostAndPort& remote) {
- // before we lock...
- NetworkOp op = m.operation();
- bool isCommand = false;
-
- DbMessage dbmsg(m);
-
- Client& c = *txn->getClient();
- if (c.isInDirectClient()) {
- invariant(!txn->lockState()->inAWriteUnitOfWork());
- } else {
- LastError::get(c).startRequest();
- AuthorizationSession::get(c)->startRequest(txn);
-
- // We should not be holding any locks at this point
- invariant(!txn->lockState()->isLocked());
- }
-
- const char* ns = dbmsg.messageShouldHaveNs() ? dbmsg.getns() : NULL;
- const NamespaceString nsString = ns ? NamespaceString(ns) : NamespaceString();
-
- if (op == dbQuery) {
- if (nsString.isCommand()) {
- isCommand = true;
- opwrite(m);
- }
- // TODO: remove this entire code path after 3.2. Refs SERVER-7775
- else if (nsString.isSpecialCommand()) {
- opwrite(m);
-
- if (nsString.coll() == "$cmd.sys.inprog") {
- receivedPseudoCommand(txn, c, dbresponse, m, "currentOp");
- return;
- }
- if (nsString.coll() == "$cmd.sys.killop") {
- receivedPseudoCommand(txn, c, dbresponse, m, "killOp");
- return;
- }
- if (nsString.coll() == "$cmd.sys.unlock") {
- receivedPseudoCommand(txn, c, dbresponse, m, "fsyncUnlock");
- return;
- }
- } else {
- opread(m);
- }
- } else if (op == dbGetMore) {
- opread(m);
- } else if (op == dbCommand) {
- isCommand = true;
- opwrite(m);
- } else {
- opwrite(m);
- }
-
- CurOp& currentOp = *CurOp::get(txn);
- {
- stdx::lock_guard<Client> lk(*txn->getClient());
- // Commands handling code will reset this if the operation is a command
- // which is logically a basic CRUD operation like query, insert, etc.
- currentOp.setNetworkOp_inlock(op);
- currentOp.setLogicalOp_inlock(networkOpToLogicalOp(op));
- }
-
- OpDebug& debug = currentOp.debug();
-
- long long logThresholdMs = serverGlobalParams.slowMS;
- bool shouldLogOpDebug = shouldLog(logger::LogSeverity::Debug(1));
-
- if (op == dbQuery) {
- if (isCommand) {
- receivedCommand(txn, nsString, c, dbresponse, m);
- } else {
- receivedQuery(txn, nsString, c, dbresponse, m);
- }
- } else if (op == dbCommand) {
- receivedRpc(txn, c, dbresponse, m);
- } else if (op == dbGetMore) {
- if (!receivedGetMore(txn, dbresponse, m, currentOp))
- shouldLogOpDebug = true;
- } else if (op == dbMsg) {
- // deprecated - replaced by commands
- const char* p = dbmsg.getns();
-
- int len = strlen(p);
- if (len > 400)
- log() << curTimeMillis64() % 10000 << " long msg received, len:" << len;
-
- if (strcmp("end", p) == 0)
- dbresponse.response.setData(opReply, "dbMsg end no longer supported");
- else
- dbresponse.response.setData(opReply, "i am fine - dbMsg deprecated");
-
- dbresponse.responseToMsgId = m.header().getId();
- } else {
- // The remaining operations do not return any response. They are fire-and-forget.
- try {
- if (op == dbKillCursors) {
- currentOp.ensureStarted();
- logThresholdMs = 10;
- receivedKillCursors(txn, m);
- } else if (op != dbInsert && op != dbUpdate && op != dbDelete) {
- log() << " operation isn't supported: " << static_cast<int>(op);
- currentOp.done();
- shouldLogOpDebug = true;
- } else {
- if (remote != DBDirectClient::dummyHost) {
- const ShardedConnectionInfo* connInfo = ShardedConnectionInfo::get(&c, false);
- uassert(18663,
- str::stream() << "legacy writeOps not longer supported for "
- << "versioned connections, ns: "
- << nsString.ns()
- << ", op: "
- << networkOpToString(op)
- << ", remote: "
- << remote.toString(),
- connInfo == NULL);
- }
-
- if (!nsString.isValid()) {
- uassert(16257, str::stream() << "Invalid ns [" << ns << "]", false);
- } else if (op == dbInsert) {
- receivedInsert(txn, nsString, m);
- } else if (op == dbUpdate) {
- receivedUpdate(txn, nsString, m);
- } else if (op == dbDelete) {
- receivedDelete(txn, nsString, m);
- } else {
- invariant(false);
- }
- }
- } catch (const UserException& ue) {
- LastError::get(c).setLastError(ue.getCode(), ue.getInfo().msg);
- LOG(3) << " Caught Assertion in " << networkOpToString(op) << ", continuing "
- << redact(ue);
- debug.exceptionInfo = ue.getInfo();
- } catch (const AssertionException& e) {
- LastError::get(c).setLastError(e.getCode(), e.getInfo().msg);
- LOG(3) << " Caught Assertion in " << networkOpToString(op) << ", continuing "
- << redact(e);
- debug.exceptionInfo = e.getInfo();
- shouldLogOpDebug = true;
- }
- }
- currentOp.ensureStarted();
- currentOp.done();
- debug.executionTimeMicros = currentOp.totalTimeMicros();
-
- logThresholdMs += currentOp.getExpectedLatencyMs();
- Top::get(txn->getServiceContext())
- .incrementGlobalLatencyStats(
- txn, currentOp.totalTimeMicros(), currentOp.getReadWriteType());
-
- if (shouldLogOpDebug || debug.executionTimeMicros > logThresholdMs * 1000LL) {
- Locker::LockerInfo lockerInfo;
- txn->lockState()->getLockerInfo(&lockerInfo);
- log() << debug.report(&c, currentOp, lockerInfo.stats);
- }
-
- if (currentOp.shouldDBProfile()) {
- // Performance profiling is on
- if (txn->lockState()->isReadLocked()) {
- LOG(1) << "note: not profiling because recursive read lock";
- } else if (lockedForWriting()) {
- // TODO SERVER-26825: Fix race condition where fsyncLock is acquired post
- // lockedForWriting() call but prior to profile collection lock acquisition.
- LOG(1) << "note: not profiling because doing fsync+lock";
- } else if (storageGlobalParams.readOnly) {
- LOG(1) << "note: not profiling because server is read-only";
- } else {
- profile(txn, op);
- }
- }
-
- recordCurOpMetrics(txn);
-}
-
} // namespace mongo
diff --git a/src/mongo/db/instance.h b/src/mongo/db/instance.h
index 2d62bdabf20..764b4605432 100644
--- a/src/mongo/db/instance.h
+++ b/src/mongo/db/instance.h
@@ -31,21 +31,12 @@
#pragma once
-#include "mongo/client/dbclientinterface.h"
-#include "mongo/db/curop.h"
-#include "mongo/db/dbmessage.h"
-#include "mongo/db/operation_context.h"
-#include "mongo/db/storage/storage_options.h"
+#include <string>
namespace mongo {
extern std::string dbExecCommand;
-void assembleResponse(OperationContext* txn,
- Message& m,
- DbResponse& dbresponse,
- const HostAndPort& client);
-
void maybeCreatePidFile();
} // namespace mongo
diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp
index d1c85db71d1..1c18fb819c5 100644
--- a/src/mongo/db/mongod_options.cpp
+++ b/src/mongo/db/mongod_options.cpp
@@ -41,7 +41,6 @@
#include "mongo/config.h"
#include "mongo/db/db.h"
#include "mongo/db/diag_log.h"
-#include "mongo/db/instance.h"
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/server_options.h"
#include "mongo/db/server_options_helpers.h"
diff --git a/src/mongo/db/pipeline/accumulator_test.cpp b/src/mongo/db/pipeline/accumulator_test.cpp
index d2ef7d7e445..c2619b3d31d 100644
--- a/src/mongo/db/pipeline/accumulator_test.cpp
+++ b/src/mongo/db/pipeline/accumulator_test.cpp
@@ -35,6 +35,7 @@
#include "mongo/db/pipeline/expression_context.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/dbtests/dbtests.h"
+#include "mongo/stdx/memory.h"
namespace AccumulatorTests {
diff --git a/src/mongo/db/pipeline/document_source_cursor.cpp b/src/mongo/db/pipeline/document_source_cursor.cpp
index 0936f6291fe..5c5be2aef1f 100644
--- a/src/mongo/db/pipeline/document_source_cursor.cpp
+++ b/src/mongo/db/pipeline/document_source_cursor.cpp
@@ -33,7 +33,6 @@
#include "mongo/db/catalog/database_holder.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/working_set_common.h"
-#include "mongo/db/instance.h"
#include "mongo/db/pipeline/document.h"
#include "mongo/db/query/explain.h"
#include "mongo/db/query/find_common.h"
diff --git a/src/mongo/db/pipeline/document_value_test.cpp b/src/mongo/db/pipeline/document_value_test.cpp
index c0182cb2fc4..8fe236cbcc2 100644
--- a/src/mongo/db/pipeline/document_value_test.cpp
+++ b/src/mongo/db/pipeline/document_value_test.cpp
@@ -30,6 +30,8 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/jsobj.h"
+#include "mongo/db/json.h"
#include "mongo/db/pipeline/document.h"
#include "mongo/db/pipeline/document_comparator.h"
#include "mongo/db/pipeline/document_value_test_util.h"
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index bebbcf9ba50..48d7c1bc521 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -30,6 +30,8 @@
#include "mongo/bson/bsonmisc.h"
#include "mongo/config.h"
+#include "mongo/db/jsobj.h"
+#include "mongo/db/json.h"
#include "mongo/db/pipeline/accumulator.h"
#include "mongo/db/pipeline/document.h"
#include "mongo/db/pipeline/document_value_test_util.h"
diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp
index ac00e12d9ac..8d040d745ad 100644
--- a/src/mongo/db/service_entry_point_mongod.cpp
+++ b/src/mongo/db/service_entry_point_mongod.cpp
@@ -34,9 +34,9 @@
#include <vector>
+#include "mongo/db/assemble_response.h"
#include "mongo/db/client.h"
#include "mongo/db/dbmessage.h"
-#include "mongo/db/instance.h"
#include "mongo/stdx/thread.h"
#include "mongo/transport/service_entry_point_utils.h"
#include "mongo/transport/session.h"
diff --git a/src/mongo/db/storage/mmap_v1/btree/btree_logic_test.cpp b/src/mongo/db/storage/mmap_v1/btree/btree_logic_test.cpp
index df9d85e9b84..5d24c5b5713 100644
--- a/src/mongo/db/storage/mmap_v1/btree/btree_logic_test.cpp
+++ b/src/mongo/db/storage/mmap_v1/btree/btree_logic_test.cpp
@@ -34,7 +34,6 @@
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage
-#include "mongo/db/instance.h"
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/storage/mmap_v1/btree/btree_test_help.h"
#include "mongo/unittest/unittest.h"
diff --git a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp
index 5fe552d0dce..51a091dd7f2 100644
--- a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp
+++ b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp
@@ -35,7 +35,6 @@
#include "mongo/db/client.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/diag_log.h"
-#include "mongo/db/instance.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/mmap_v1/dur_journal.h"
#include "mongo/db/storage/mmap_v1/mmap.h"
diff --git a/src/mongo/dbtests/basictests.cpp b/src/mongo/dbtests/basictests.cpp
index f0f68d05c97..d9a16934d8e 100644
--- a/src/mongo/dbtests/basictests.cpp
+++ b/src/mongo/dbtests/basictests.cpp
@@ -43,6 +43,7 @@
#include "mongo/util/text.h"
#include "mongo/util/thread_safe_string.h"
#include "mongo/util/time_support.h"
+#include "mongo/util/timer.h"
namespace BasicTests {
diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp
index 78ad3a66807..8bcd72ff37d 100644
--- a/src/mongo/dbtests/dbtests.cpp
+++ b/src/mongo/dbtests/dbtests.cpp
@@ -34,6 +34,7 @@
#include "mongo/dbtests/dbtests.h"
#include "mongo/base/initializer.h"
+#include "mongo/client/dbclientinterface.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_global.h"
#include "mongo/db/catalog/index_create.h"
diff --git a/src/mongo/dbtests/dbtests.h b/src/mongo/dbtests/dbtests.h
index 09dcfcfbbc7..86de296e53d 100644
--- a/src/mongo/dbtests/dbtests.h
+++ b/src/mongo/dbtests/dbtests.h
@@ -31,8 +31,6 @@
#pragma once
-
-#include "mongo/db/instance.h"
#include "mongo/unittest/unittest.h"
using namespace mongo;
diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp
index 4b5943cdc8f..917488bd1c0 100644
--- a/src/mongo/dbtests/jsobjtests.cpp
+++ b/src/mongo/dbtests/jsobjtests.cpp
@@ -49,6 +49,7 @@
#include "mongo/util/embedded_builder.h"
#include "mongo/util/log.h"
#include "mongo/util/stringutils.h"
+#include "mongo/util/timer.h"
namespace mongo {
diff --git a/src/mongo/dbtests/mmaptests.cpp b/src/mongo/dbtests/mmaptests.cpp
index 73e6fc20f83..2090e66d4b5 100644
--- a/src/mongo/dbtests/mmaptests.cpp
+++ b/src/mongo/dbtests/mmaptests.cpp
@@ -33,6 +33,7 @@
#include <boost/filesystem/operations.hpp>
#include <iostream>
+#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/concurrency/lock_state.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/mmap_v1/data_file.h"
diff --git a/src/mongo/dbtests/query_stage_ixscan.cpp b/src/mongo/dbtests/query_stage_ixscan.cpp
index 4f39d27588e..45ee7723ecf 100644
--- a/src/mongo/dbtests/query_stage_ixscan.cpp
+++ b/src/mongo/dbtests/query_stage_ixscan.cpp
@@ -28,6 +28,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/client/dbclientinterface.h"
#include "mongo/db/client.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/index_scan.h"
diff --git a/src/mongo/dbtests/query_stage_limit_skip.cpp b/src/mongo/dbtests/query_stage_limit_skip.cpp
index 0009f32ea8c..103f5932255 100644
--- a/src/mongo/dbtests/query_stage_limit_skip.cpp
+++ b/src/mongo/dbtests/query_stage_limit_skip.cpp
@@ -39,7 +39,6 @@
#include "mongo/db/exec/plan_stage.h"
#include "mongo/db/exec/queued_data_stage.h"
#include "mongo/db/exec/skip.h"
-#include "mongo/db/instance.h"
#include "mongo/db/json.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/stdx/memory.h"
diff --git a/src/mongo/dbtests/socktests.cpp b/src/mongo/dbtests/socktests.cpp
index def0cfdb176..e0a9fbb2fed 100644
--- a/src/mongo/dbtests/socktests.cpp
+++ b/src/mongo/dbtests/socktests.cpp
@@ -33,6 +33,8 @@
#include "mongo/db/repl/isself.h"
#include "mongo/dbtests/dbtests.h"
+#include "mongo/util/net/hostandport.h"
+#include "mongo/util/net/sock.h"
namespace SockTests {
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index 2bad7e6063f..52615b92aa3 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -52,7 +52,6 @@
#include "mongo/db/client.h"
#include "mongo/db/dbwebserver.h"
#include "mongo/db/initialize_server_global_state.h"
-#include "mongo/db/instance.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/log_process_details.h"
#include "mongo/db/server_options.h"