summaryrefslogtreecommitdiff
path: root/src/mongo/s/commands
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2017-06-01 14:18:45 -0400
committerMathias Stearn <mathias@10gen.com>2017-06-13 17:15:28 -0400
commit24c66e9e8f9a2415436adf1a09317eaae8ee56e5 (patch)
tree2ff9fcd9450190882d20c9cefac9faccbbe8c783 /src/mongo/s/commands
parent7317ccaf069b5c2ac6d725aaf5fd3eb82bbdd45d (diff)
downloadmongo-24c66e9e8f9a2415436adf1a09317eaae8ee56e5.tar.gz
SERVER-29525 filter mongos command requests only where needed
Diffstat (limited to 'src/mongo/s/commands')
-rw-r--r--src/mongo/s/commands/cluster_aggregate.cpp1
-rw-r--r--src/mongo/s/commands/cluster_current_op.cpp7
-rw-r--r--src/mongo/s/commands/cluster_db_stats_cmd.cpp7
-rw-r--r--src/mongo/s/commands/cluster_explain.cpp5
-rw-r--r--src/mongo/s/commands/cluster_find_and_modify_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_find_cmd.cpp9
-rw-r--r--src/mongo/s/commands/cluster_get_last_error_cmd.cpp3
-rw-r--r--src/mongo/s/commands/cluster_index_filter_cmd.cpp9
-rw-r--r--src/mongo/s/commands/cluster_list_databases_cmd.cpp11
-rw-r--r--src/mongo/s/commands/cluster_map_reduce_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_plan_cache_cmd.cpp9
-rw-r--r--src/mongo/s/commands/cluster_reset_error_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_user_management_commands.cpp36
-rw-r--r--src/mongo/s/commands/commands_public.cpp39
-rw-r--r--src/mongo/s/commands/strategy.cpp37
15 files changed, 87 insertions, 93 deletions
diff --git a/src/mongo/s/commands/cluster_aggregate.cpp b/src/mongo/s/commands/cluster_aggregate.cpp
index a491ed5e553..5ab0184dfbd 100644
--- a/src/mongo/s/commands/cluster_aggregate.cpp
+++ b/src/mongo/s/commands/cluster_aggregate.cpp
@@ -450,6 +450,7 @@ Status ClusterAggregate::aggPassthrough(OperationContext* opCtx,
cmdObj = explainCmdObj.toBson();
}
+ cmdObj = Command::filterCommandRequestForPassthrough(cmdObj);
auto cmdResponse = uassertStatusOK(shard->runCommandWithFixedRetryAttempts(
opCtx,
ReadPreferenceSetting::get(opCtx),
diff --git a/src/mongo/s/commands/cluster_current_op.cpp b/src/mongo/s/commands/cluster_current_op.cpp
index ffc2a3fa067..df4c0b15132 100644
--- a/src/mongo/s/commands/cluster_current_op.cpp
+++ b/src/mongo/s/commands/cluster_current_op.cpp
@@ -85,8 +85,11 @@ public:
const BSONObj& cmdObj,
std::string& errmsg,
BSONObjBuilder& output) override {
- auto shardResponses = uassertStatusOK(
- scatterGather(opCtx, dbName, cmdObj, ReadPreferenceSetting::get(opCtx)));
+ auto shardResponses =
+ uassertStatusOK(scatterGather(opCtx,
+ dbName,
+ filterCommandRequestForPassthrough(cmdObj),
+ ReadPreferenceSetting::get(opCtx)));
if (!appendRawResponses(opCtx, &errmsg, &output, shardResponses)) {
return false;
}
diff --git a/src/mongo/s/commands/cluster_db_stats_cmd.cpp b/src/mongo/s/commands/cluster_db_stats_cmd.cpp
index 297638e424d..b1dcb07e491 100644
--- a/src/mongo/s/commands/cluster_db_stats_cmd.cpp
+++ b/src/mongo/s/commands/cluster_db_stats_cmd.cpp
@@ -68,8 +68,11 @@ public:
const BSONObj& cmdObj,
std::string& errmsg,
BSONObjBuilder& output) override {
- auto shardResponses = uassertStatusOK(
- scatterGather(opCtx, dbName, cmdObj, ReadPreferenceSetting::get(opCtx)));
+ auto shardResponses =
+ uassertStatusOK(scatterGather(opCtx,
+ dbName,
+ filterCommandRequestForPassthrough(cmdObj),
+ ReadPreferenceSetting::get(opCtx)));
if (!appendRawResponses(opCtx, &errmsg, &output, shardResponses)) {
return false;
}
diff --git a/src/mongo/s/commands/cluster_explain.cpp b/src/mongo/s/commands/cluster_explain.cpp
index 59f4ca83cc5..9970138748e 100644
--- a/src/mongo/s/commands/cluster_explain.cpp
+++ b/src/mongo/s/commands/cluster_explain.cpp
@@ -130,13 +130,14 @@ std::vector<Strategy::CommandResult> ClusterExplain::downconvert(
// static
BSONObj ClusterExplain::wrapAsExplain(const BSONObj& cmdObj, ExplainOptions::Verbosity verbosity) {
+ auto filtered = Command::filterCommandRequestForPassthrough(cmdObj);
BSONObjBuilder out;
- out.append("explain", cmdObj);
+ out.append("explain", filtered);
out.append("verbosity", ExplainOptions::verbosityString(verbosity));
// Propagate all generic arguments out of the inner command since the shards will only process
// them at the top level.
- for (auto elem : cmdObj) {
+ for (auto elem : filtered) {
if (Command::isGenericArgument(elem.fieldNameStringData())) {
out.append(elem);
}
diff --git a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
index 6594ba534bf..33f10c478f5 100644
--- a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
+++ b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
@@ -232,7 +232,8 @@ private:
uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, shardId));
ShardConnection conn(shard->getConnString(), nss.ns(), chunkManager);
- bool ok = conn->runCommand(nss.db().toString(), cmdObj, res);
+ bool ok =
+ conn->runCommand(nss.db().toString(), filterCommandRequestForPassthrough(cmdObj), res);
conn.done();
// ErrorCodes::RecvStaleConfig is the code for RecvStaleConfigException.
diff --git a/src/mongo/s/commands/cluster_find_cmd.cpp b/src/mongo/s/commands/cluster_find_cmd.cpp
index 16c84ab5c27..4bf8b053008 100644
--- a/src/mongo/s/commands/cluster_find_cmd.cpp
+++ b/src/mongo/s/commands/cluster_find_cmd.cpp
@@ -171,19 +171,12 @@ public:
return appendCommandStatus(result, cq.getStatus());
}
- // Extract read preference. If no read preference is specified in the query, will we pass
- // down a "primaryOnly" or "secondary" read pref, depending on the slaveOk setting.
- auto readPref = ClusterFind::extractUnwrappedReadPref(cmdObj);
- if (!readPref.isOK()) {
- return appendCommandStatus(result, readPref.getStatus());
- }
-
// Do the work to generate the first batch of results. This blocks waiting to get responses
// from the shard(s).
std::vector<BSONObj> batch;
BSONObj viewDefinition;
auto cursorId = ClusterFind::runQuery(
- opCtx, *cq.getValue(), readPref.getValue(), &batch, &viewDefinition);
+ opCtx, *cq.getValue(), ReadPreferenceSetting::get(opCtx), &batch, &viewDefinition);
if (!cursorId.isOK()) {
if (cursorId.getStatus() == ErrorCodes::CommandOnShardedViewNotSupportedOnMongod) {
auto aggCmdOnView = cq.getValue()->getQueryRequest().asAggregationCommand();
diff --git a/src/mongo/s/commands/cluster_get_last_error_cmd.cpp b/src/mongo/s/commands/cluster_get_last_error_cmd.cpp
index 4d366c1a1de..57e036562eb 100644
--- a/src/mongo/s/commands/cluster_get_last_error_cmd.cpp
+++ b/src/mongo/s/commands/cluster_get_last_error_cmd.cpp
@@ -243,7 +243,8 @@ public:
const HostOpTimeMap hostOpTimes(ClusterLastErrorInfo::get(cc())->getPrevHostOpTimes());
std::vector<LegacyWCResponse> wcResponses;
- auto status = enforceLegacyWriteConcern(opCtx, dbname, cmdObj, hostOpTimes, &wcResponses);
+ auto status = enforceLegacyWriteConcern(
+ opCtx, dbname, filterCommandRequestForPassthrough(cmdObj), hostOpTimes, &wcResponses);
// Don't forget about our last hosts, reset the client info
ClusterLastErrorInfo::get(cc())->disableForCommand();
diff --git a/src/mongo/s/commands/cluster_index_filter_cmd.cpp b/src/mongo/s/commands/cluster_index_filter_cmd.cpp
index 23328fa3f18..7b7ef05ef22 100644
--- a/src/mongo/s/commands/cluster_index_filter_cmd.cpp
+++ b/src/mongo/s/commands/cluster_index_filter_cmd.cpp
@@ -106,8 +106,13 @@ public:
// commands are tied to query shape (data has no effect on query shape).
vector<Strategy::CommandResult> results;
const BSONObj query;
- Strategy::commandOp(
- opCtx, dbname, cmdObj, nss.ns(), query, CollationSpec::kSimpleSpec, &results);
+ Strategy::commandOp(opCtx,
+ dbname,
+ filterCommandRequestForPassthrough(cmdObj),
+ nss.ns(),
+ query,
+ CollationSpec::kSimpleSpec,
+ &results);
// Set value of first shard result's "ok" field.
bool clusterCmdResult = true;
diff --git a/src/mongo/s/commands/cluster_list_databases_cmd.cpp b/src/mongo/s/commands/cluster_list_databases_cmd.cpp
index 68c9cd55581..bc81d7f5b8d 100644
--- a/src/mongo/s/commands/cluster_list_databases_cmd.cpp
+++ b/src/mongo/s/commands/cluster_list_databases_cmd.cpp
@@ -39,6 +39,7 @@
#include "mongo/s/catalog/sharding_catalog_client.h"
#include "mongo/s/client/shard.h"
#include "mongo/s/client/shard_registry.h"
+#include "mongo/s/commands/strategy.h"
#include "mongo/s/grid.h"
namespace mongo {
@@ -107,7 +108,7 @@ public:
opCtx,
ReadPreferenceSetting{ReadPreference::PrimaryPreferred},
"admin",
- cmdObj,
+ filterCommandRequestForPassthrough(cmdObj),
Shard::RetryPolicy::kIdempotent));
uassertStatusOK(response.commandStatus);
BSONObj x = std::move(response.response);
@@ -166,14 +167,14 @@ public:
// Get information for config and admin dbs from the config servers.
auto catalogClient = grid.catalogClient(opCtx);
- auto appendStatus =
- catalogClient->appendInfoForConfigServerDatabases(opCtx, cmdObj, &dbListBuilder);
+ auto appendStatus = catalogClient->appendInfoForConfigServerDatabases(
+ opCtx, filterCommandRequestForPassthrough(cmdObj), &dbListBuilder);
+ dbListBuilder.doneFast();
if (!appendStatus.isOK()) {
+ result.resetToEmpty();
return Command::appendCommandStatus(result, appendStatus);
}
- dbListBuilder.done();
-
if (nameOnly)
return true;
diff --git a/src/mongo/s/commands/cluster_map_reduce_cmd.cpp b/src/mongo/s/commands/cluster_map_reduce_cmd.cpp
index 3e9cd98da85..858f5c09dfa 100644
--- a/src/mongo/s/commands/cluster_map_reduce_cmd.cpp
+++ b/src/mongo/s/commands/cluster_map_reduce_cmd.cpp
@@ -282,7 +282,7 @@ public:
ShardConnection conn(inputRoutingInfo.primary()->getConnString(), "");
BSONObj res;
- bool ok = conn->runCommand(dbname, cmdObj, res);
+ bool ok = conn->runCommand(dbname, filterCommandRequestForPassthrough(cmdObj), res);
conn.done();
if (auto wcErrorElem = res["writeConcernError"]) {
diff --git a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp
index 3ca3798a929..775dd7b3aec 100644
--- a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp
+++ b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp
@@ -121,8 +121,13 @@ bool ClusterPlanCacheCmd::run(OperationContext* opCtx,
// commands are tied to query shape (data has no effect on query shape).
vector<Strategy::CommandResult> results;
const BSONObj query;
- Strategy::commandOp(
- opCtx, dbName, cmdObj, nss.ns(), query, CollationSpec::kSimpleSpec, &results);
+ Strategy::commandOp(opCtx,
+ dbName,
+ filterCommandRequestForPassthrough(cmdObj),
+ nss.ns(),
+ query,
+ CollationSpec::kSimpleSpec,
+ &results);
// Set value of first shard result's "ok" field.
bool clusterCmdResult = true;
diff --git a/src/mongo/s/commands/cluster_reset_error_cmd.cpp b/src/mongo/s/commands/cluster_reset_error_cmd.cpp
index 7844ac44a27..8757e8944a6 100644
--- a/src/mongo/s/commands/cluster_reset_error_cmd.cpp
+++ b/src/mongo/s/commands/cluster_reset_error_cmd.cpp
@@ -76,7 +76,7 @@ public:
BSONObj res;
// Don't care about result from shards.
- conn->runCommand(dbname, cmdObj, res);
+ conn->runCommand(dbname, filterCommandRequestForPassthrough(cmdObj), res);
conn.done();
}
diff --git a/src/mongo/s/commands/cluster_user_management_commands.cpp b/src/mongo/s/commands/cluster_user_management_commands.cpp
index dfa2233c57f..72c4d04868c 100644
--- a/src/mongo/s/commands/cluster_user_management_commands.cpp
+++ b/src/mongo/s/commands/cluster_user_management_commands.cpp
@@ -92,7 +92,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
return Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
}
virtual void redactForLogging(mutablebson::Document* cmdObj) {
@@ -135,7 +135,7 @@ public:
return appendCommandStatus(result, status);
}
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -184,7 +184,7 @@ public:
return appendCommandStatus(result, status);
}
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -224,7 +224,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -271,7 +271,7 @@ public:
return appendCommandStatus(result, status);
}
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -318,7 +318,7 @@ public:
return appendCommandStatus(result, status);
}
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -362,7 +362,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
return Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementReadCommand(
- opCtx, dbname, cmdObj, &result);
+ opCtx, dbname, filterCommandRequestForPassthrough(cmdObj), &result);
}
} cmdUsersInfo;
@@ -396,7 +396,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
return Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
}
} cmdCreateRole;
@@ -430,7 +430,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -470,7 +470,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -510,7 +510,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -550,7 +550,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -590,7 +590,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -633,7 +633,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -677,7 +677,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
const bool ok = Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
invariant(authzManager);
@@ -721,7 +721,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
return Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementReadCommand(
- opCtx, dbname, cmdObj, &result);
+ opCtx, dbname, filterCommandRequestForPassthrough(cmdObj), &result);
}
} cmdRolesInfo;
@@ -809,7 +809,7 @@ public:
string& errmsg,
BSONObjBuilder& result) {
return Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result);
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result);
}
} cmdMergeAuthzCollections;
@@ -899,7 +899,7 @@ public:
BSONObjBuilder& result) {
// Run the authSchemaUpgrade command on the config servers
if (!Grid::get(opCtx)->catalogClient(opCtx)->runUserManagementWriteCommand(
- opCtx, getName(), dbname, cmdObj, &result)) {
+ opCtx, getName(), dbname, filterCommandRequestForPassthrough(cmdObj), &result)) {
return false;
}
diff --git a/src/mongo/s/commands/commands_public.cpp b/src/mongo/s/commands/commands_public.cpp
index 16560f6b0b6..f5493186bac 100644
--- a/src/mongo/s/commands/commands_public.cpp
+++ b/src/mongo/s/commands/commands_public.cpp
@@ -95,7 +95,9 @@ bool cursorCommandPassthrough(OperationContext* opCtx,
}
const auto shard = shardStatus.getValue();
ScopedDbConnection conn(shard->getConnString());
- auto cursor = conn->query(str::stream() << dbName << ".$cmd", cmdObj, /* nToReturn=*/-1);
+ auto cursor = conn->query(str::stream() << dbName << ".$cmd",
+ Command::filterCommandRequestForPassthrough(cmdObj),
+ /* nToReturn=*/-1);
if (!cursor || !cursor->more()) {
return Command::appendCommandStatus(
*out, {ErrorCodes::OperationFailed, "failed to read command response from shard"});
@@ -176,7 +178,7 @@ protected:
ShardConnection conn(shard->getConnString(), "");
BSONObj res;
- bool ok = conn->runCommand(db, cmdObj, res);
+ bool ok = conn->runCommand(db, filterCommandRequestForPassthrough(cmdObj), res);
conn.done();
// First append the properly constructed writeConcernError. It will then be skipped
@@ -225,7 +227,7 @@ protected:
auto shardResponses =
uassertStatusOK(scatterGatherForNamespace(opCtx,
nss,
- cmdObj,
+ filterCommandRequestForPassthrough(cmdObj),
ReadPreferenceSetting::get(opCtx),
boost::none, // filter
boost::none, // collation
@@ -368,8 +370,13 @@ public:
vector<Strategy::CommandResult> results;
const BSONObj query;
- Strategy::commandOp(
- opCtx, dbName, cmdObj, cm->getns(), query, CollationSpec::kSimpleSpec, &results);
+ Strategy::commandOp(opCtx,
+ dbName,
+ filterCommandRequestForPassthrough(cmdObj),
+ cm->getns(),
+ query,
+ CollationSpec::kSimpleSpec,
+ &results);
BSONObjBuilder rawResBuilder(output.subobjStart("raw"));
bool isValid = true;
@@ -552,7 +559,7 @@ public:
!fromDbInfo.shardingEnabled());
BSONObjBuilder b;
- BSONForEach(e, cmdObj) {
+ BSONForEach(e, filterCommandRequestForPassthrough(cmdObj)) {
if (strcmp(e.fieldName(), "fromhost") != 0) {
b.append(e);
}
@@ -626,7 +633,7 @@ public:
BSONObj res;
{
ScopedDbConnection conn(shard->getConnString());
- if (!conn->runCommand(dbName, cmdObj, res)) {
+ if (!conn->runCommand(dbName, filterCommandRequestForPassthrough(cmdObj), res)) {
if (!res["code"].eoo()) {
result.append(res["code"]);
}
@@ -814,7 +821,7 @@ public:
ScopedDbConnection conn(shardStatus.getValue()->getConnString());
BSONObj res;
- bool ok = conn->runCommand(dbName, cmdObj, res);
+ bool ok = conn->runCommand(dbName, filterCommandRequestForPassthrough(cmdObj), res);
conn.done();
if (!ok) {
@@ -1085,7 +1092,8 @@ public:
ShardConnection conn(shardStatus.getValue()->getConnString(), nss.ns());
BSONObj res;
- bool ok = conn->runCommand(nss.db().toString(), cmdObj, res);
+ bool ok = conn->runCommand(
+ nss.db().toString(), filterCommandRequestForPassthrough(cmdObj), res);
conn.done();
if (!ok) {
@@ -1259,8 +1267,13 @@ public:
BSONObj finder = BSON("files_id" << cmdObj.firstElement());
vector<Strategy::CommandResult> results;
- Strategy::commandOp(
- opCtx, dbName, cmdObj, nss.ns(), finder, CollationSpec::kSimpleSpec, &results);
+ Strategy::commandOp(opCtx,
+ dbName,
+ filterCommandRequestForPassthrough(cmdObj),
+ nss.ns(),
+ finder,
+ CollationSpec::kSimpleSpec,
+ &results);
verify(results.size() == 1); // querying on shard key so should only talk to one shard
BSONObj res = results.begin()->result;
@@ -1281,7 +1294,7 @@ public:
// look for chunk n and it doesn't exist. This means that the file's last
// chunk is n-1, so we return the computed md5 results.
BSONObjBuilder bb;
- bb.appendElements(cmdObj);
+ bb.appendElements(filterCommandRequestForPassthrough(cmdObj));
bb.appendBool("partialOk", true);
bb.append("startAt", n);
if (!lastResult.isEmpty()) {
@@ -1415,7 +1428,7 @@ public:
vector<AsyncRequestsSender::Request> requests;
BSONArrayBuilder shardArray;
for (const ShardId& shardId : shardIds) {
- requests.emplace_back(shardId, cmdObj);
+ requests.emplace_back(shardId, filterCommandRequestForPassthrough(cmdObj));
shardArray.append(shardId.toString());
}
diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp
index c1ca83c0234..27d621d495b 100644
--- a/src/mongo/s/commands/strategy.cpp
+++ b/src/mongo/s/commands/strategy.cpp
@@ -143,38 +143,6 @@ void appendRequiredFieldsToResponse(OperationContext* opCtx, BSONObjBuilder* res
}
}
-/**
- * Rewrites cmdObj into the format expected by mongos Command::run() implementations.
- *
- * This performs 2 transformations:
- * 1) $readPreference fields are moved into a subobject called $queryOptions. This matches the
- * "wrapped" format historically used internally by mongos. Moving off of that format will be
- * done as SERVER-29091.
- *
- * 2) Filter out generic arguments that shouldn't be blindly passed to the shards. This is
- * necessary because many mongos implementations of Command::run() just pass cmdObj through
- * directly to the shards. However, some of the generic arguments fields are automatically
- * appended in the egress layer. Removing them here ensures that they don't get duplicated.
- *
- * Ideally this function can be deleted once mongos run() implementations are more careful about
- * what they send to the shards.
- */
-BSONObj filterCommandRequestForPassthrough(const BSONObj& cmdObj) {
- BSONObjBuilder bob;
- for (auto elem : cmdObj) {
- const auto name = elem.fieldNameStringData();
- if (name == "$readPreference") {
- BSONObjBuilder(bob.subobjStart("$queryOptions")).append(elem);
- } else if (!Command::isGenericArgument(name) || name == "maxTimeMS" ||
- name == "readConcern" || name == "writeConcern") {
- // This is the whitelist of generic arguments that commands can be trusted to blindly
- // forward to the shards.
- bob.append(elem);
- }
- }
- return bob.obj();
-}
-
void execCommandClient(OperationContext* opCtx,
Command* c,
StringData dbname,
@@ -249,19 +217,18 @@ void execCommandClient(OperationContext* opCtx,
return;
}
- auto filteredCmdObj = filterCommandRequestForPassthrough(cmdObj);
std::string errmsg;
bool ok = false;
try {
if (!supportsWriteConcern) {
- ok = c->run(opCtx, dbname.toString(), filteredCmdObj, errmsg, result);
+ ok = c->run(opCtx, dbname.toString(), cmdObj, errmsg, result);
} else {
// Change the write concern while running the command.
const auto oldWC = opCtx->getWriteConcern();
ON_BLOCK_EXIT([&] { opCtx->setWriteConcern(oldWC); });
opCtx->setWriteConcern(wcResult.getValue());
- ok = c->run(opCtx, dbname.toString(), filteredCmdObj, errmsg, result);
+ ok = c->run(opCtx, dbname.toString(), cmdObj, errmsg, result);
}
} catch (const DBException& e) {
result.resetToEmpty();