summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-11-08 12:06:12 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-11-11 14:21:42 -0500
commit07562c2fb080a3856fe06a2ff412d06060a6abb7 (patch)
tree9b9fd9c65973abdec2e331f25c0b229bc0a96a69 /src/mongo/db
parentcbb4e60d3e2756f5861372121228a6fe82a3cedb (diff)
downloadmongo-07562c2fb080a3856fe06a2ff412d06060a6abb7.tar.gz
SERVER-26955 Ensure setFeatureCompatibilityVersion commands support maxTimeMS
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/commands/SConscript1
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.cpp28
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.h2
-rw-r--r--src/mongo/db/commands/feature_compatibility_version_command_parser.cpp96
-rw-r--r--src/mongo/db/commands/feature_compatibility_version_command_parser.h57
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp44
-rw-r--r--src/mongo/db/s/config/configsvr_control_balancer_command.cpp18
-rw-r--r--src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp50
8 files changed, 189 insertions, 107 deletions
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index 868484de229..cc535fc4fe5 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -31,6 +31,7 @@ env.Library(
"connection_status.cpp",
"copydb_common.cpp",
"fail_point_cmd.cpp",
+ "feature_compatibility_version_command_parser.cpp",
"find_and_modify_common.cpp",
"hashcmd.cpp",
"isself.cpp",
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp
index dcf4ae4c652..2e38906b685 100644
--- a/src/mongo/db/commands/feature_compatibility_version.cpp
+++ b/src/mongo/db/commands/feature_compatibility_version.cpp
@@ -34,6 +34,7 @@
#include "mongo/base/status.h"
#include "mongo/db/catalog/collection_options.h"
+#include "mongo/db/commands/feature_compatibility_version_command_parser.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
@@ -58,8 +59,6 @@ constexpr StringData FeatureCompatibilityVersion::kCollection;
constexpr StringData FeatureCompatibilityVersion::kCommandName;
constexpr StringData FeatureCompatibilityVersion::kParameterName;
constexpr StringData FeatureCompatibilityVersion::kVersionField;
-constexpr StringData FeatureCompatibilityVersion::kVersion34;
-constexpr StringData FeatureCompatibilityVersion::kVersion32;
namespace {
const BSONObj k32IncompatibleIndexSpec =
@@ -104,9 +103,9 @@ StringData getFeatureCompatibilityVersionString(
ServerGlobalParams::FeatureCompatibility::Version version) {
switch (version) {
case ServerGlobalParams::FeatureCompatibility::Version::k34:
- return FeatureCompatibilityVersion::kVersion34;
+ return FeatureCompatibilityVersionCommandParser::kVersion34;
case ServerGlobalParams::FeatureCompatibility::Version::k32:
- return FeatureCompatibilityVersion::kVersion32;
+ return FeatureCompatibilityVersionCommandParser::kVersion32;
default:
MONGO_UNREACHABLE;
}
@@ -139,9 +138,9 @@ StatusWith<ServerGlobalParams::FeatureCompatibility::Version> FeatureCompatibili
<< featureCompatibilityVersionDoc
<< ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.");
}
- if (elem.String() == FeatureCompatibilityVersion::kVersion34) {
+ if (elem.String() == FeatureCompatibilityVersionCommandParser::kVersion34) {
version = ServerGlobalParams::FeatureCompatibility::Version::k34;
- } else if (elem.String() == FeatureCompatibilityVersion::kVersion32) {
+ } else if (elem.String() == FeatureCompatibilityVersionCommandParser::kVersion32) {
version = ServerGlobalParams::FeatureCompatibility::Version::k32;
} else {
return Status(
@@ -152,9 +151,9 @@ StatusWith<ServerGlobalParams::FeatureCompatibility::Version> FeatureCompatibili
<< ", found "
<< elem.String()
<< ", expected '"
- << FeatureCompatibilityVersion::kVersion34
+ << FeatureCompatibilityVersionCommandParser::kVersion34
<< "' or '"
- << FeatureCompatibilityVersion::kVersion32
+ << FeatureCompatibilityVersionCommandParser::kVersion32
<< "'. Contents of "
<< FeatureCompatibilityVersion::kParameterName
<< " document in "
@@ -197,13 +196,13 @@ void FeatureCompatibilityVersion::set(OperationContext* txn, StringData version)
uassert(40284,
"featureCompatibilityVersion must be '3.4' or '3.2'. See "
"http://dochub.mongodb.org/core/3.4-feature-compatibility.",
- version == FeatureCompatibilityVersion::kVersion34 ||
- version == FeatureCompatibilityVersion::kVersion32);
+ version == FeatureCompatibilityVersionCommandParser::kVersion34 ||
+ version == FeatureCompatibilityVersionCommandParser::kVersion32);
DBDirectClient client(txn);
NamespaceString nss(FeatureCompatibilityVersion::kCollection);
- if (version == FeatureCompatibilityVersion::kVersion34) {
+ if (version == FeatureCompatibilityVersionCommandParser::kVersion34) {
// We build a v=2 index on the "admin.system.version" collection as part of setting the
// featureCompatibilityVersion to 3.4. This is a new index version that isn't supported by
// versions of MongoDB earlier than 3.4 that will cause 3.2 secondaries to crash when it is
@@ -248,7 +247,7 @@ void FeatureCompatibilityVersion::set(OperationContext* txn, StringData version)
// We then update the value of the featureCompatibilityVersion server parameter.
serverGlobalParams.featureCompatibility.version.store(
ServerGlobalParams::FeatureCompatibility::Version::k34);
- } else if (version == FeatureCompatibilityVersion::kVersion32) {
+ } else if (version == FeatureCompatibilityVersionCommandParser::kVersion32) {
// We update the featureCompatibilityVersion document stored in the "admin.system.version"
// collection. We do this before dropping the v=2 index in order to maintain the invariant
// that if the featureCompatibilityVersion is 3.4, then 'k32IncompatibleIndexSpec' index
@@ -321,7 +320,7 @@ void FeatureCompatibilityVersion::setIfCleanStartup(OperationContext* txn,
nss,
BSON("_id" << FeatureCompatibilityVersion::kParameterName
<< FeatureCompatibilityVersion::kVersionField
- << FeatureCompatibilityVersion::kVersion34)));
+ << FeatureCompatibilityVersionCommandParser::kVersion34)));
// We then update the value of the featureCompatibilityVersion server parameter.
serverGlobalParams.featureCompatibility.version.store(
@@ -347,7 +346,8 @@ void FeatureCompatibilityVersion::onDelete(const BSONObj& doc) {
idElement.String() != FeatureCompatibilityVersion::kParameterName) {
return;
}
- log() << "setting featureCompatibilityVersion to " << FeatureCompatibilityVersion::kVersion32;
+ log() << "setting featureCompatibilityVersion to "
+ << FeatureCompatibilityVersionCommandParser::kVersion32;
serverGlobalParams.featureCompatibility.version.store(
ServerGlobalParams::FeatureCompatibility::Version::k32);
}
diff --git a/src/mongo/db/commands/feature_compatibility_version.h b/src/mongo/db/commands/feature_compatibility_version.h
index 2560d08953e..46fa8390bb3 100644
--- a/src/mongo/db/commands/feature_compatibility_version.h
+++ b/src/mongo/db/commands/feature_compatibility_version.h
@@ -52,8 +52,6 @@ public:
static constexpr StringData kCommandName = "setFeatureCompatibilityVersion"_sd;
static constexpr StringData kParameterName = "featureCompatibilityVersion"_sd;
static constexpr StringData kVersionField = "version"_sd;
- static constexpr StringData kVersion34 = "3.4"_sd;
- static constexpr StringData kVersion32 = "3.2"_sd;
/**
* Parses the featureCompatibilityVersion document from admin.system.version, and returns the
diff --git a/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp b/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp
new file mode 100644
index 00000000000..e8536e88db2
--- /dev/null
+++ b/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2016 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.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/commands/feature_compatibility_version_command_parser.h"
+
+#include "mongo/base/status_with.h"
+#include "mongo/bson/bsonobj.h"
+#include "mongo/db/query/query_request.h"
+#include "mongo/util/version.h"
+
+namespace mongo {
+
+constexpr StringData FeatureCompatibilityVersionCommandParser::kVersion34;
+constexpr StringData FeatureCompatibilityVersionCommandParser::kVersion32;
+
+StatusWith<std::string> FeatureCompatibilityVersionCommandParser::extractVersionFromCommand(
+ StringData commandName, const BSONObj& cmdObj) {
+ if (cmdObj.firstElementFieldName() != commandName) {
+ return {ErrorCodes::InternalError,
+ str::stream() << "Expected to find a " << commandName << " command, but found "
+ << cmdObj};
+ }
+
+ const auto versionElem = cmdObj.firstElement();
+
+ if (versionElem.type() != BSONType::String) {
+ return {ErrorCodes::TypeMismatch,
+ str::stream() << "Command argument must be of type "
+ "String, but was of type "
+ << typeName(versionElem.type())
+ << " in: "
+ << cmdObj
+ << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."};
+ }
+
+ // Ensure that the command does not contain any unrecognized parameters
+ for (const auto& cmdElem : cmdObj) {
+ if (cmdElem.fieldNameStringData() == commandName ||
+ cmdElem.fieldNameStringData() == QueryRequest::cmdOptionMaxTimeMS) {
+ continue;
+ }
+
+ uasserted(
+ ErrorCodes::InvalidOptions,
+ str::stream() << "Unrecognized field found " << cmdElem.fieldNameStringData() << " in "
+ << cmdObj
+ << ". See http ://dochub.mongodb.org/core/3.4-feature-compatibility.");
+ }
+
+ const std::string version = versionElem.String();
+
+ if (version != FeatureCompatibilityVersionCommandParser::kVersion34 &&
+ version != FeatureCompatibilityVersionCommandParser::kVersion32) {
+ return {ErrorCodes::BadValue,
+ str::stream() << "Invalid command argument. Expected '"
+ << FeatureCompatibilityVersionCommandParser::kVersion34
+ << "' or '"
+ << FeatureCompatibilityVersionCommandParser::kVersion32
+ << "', found "
+ << version
+ << " in: "
+ << cmdObj
+ << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."};
+ }
+
+ return version;
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/commands/feature_compatibility_version_command_parser.h b/src/mongo/db/commands/feature_compatibility_version_command_parser.h
new file mode 100644
index 00000000000..4e17aa94cdc
--- /dev/null
+++ b/src/mongo/db/commands/feature_compatibility_version_command_parser.h
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "mongo/base/string_data.h"
+
+namespace mongo {
+
+class BSONObj;
+template <typename T>
+class StatusWith;
+
+class FeatureCompatibilityVersionCommandParser {
+public:
+ /**
+ * Known server release versions.
+ */
+ static constexpr StringData kVersion34 = "3.4"_sd;
+ static constexpr StringData kVersion32 = "3.2"_sd;
+
+ /**
+ * Interprets the specified BSON as a command and extracts the desired compatibility version
+ * from it.
+ */
+ static StatusWith<std::string> extractVersionFromCommand(StringData commandName,
+ const BSONObj& cmdObj);
+};
+
+} // namespace mongo
diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
index adc00bd7ae5..4d6c7f9867d 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/feature_compatibility_version.h"
+#include "mongo/db/commands/feature_compatibility_version_command_parser.h"
namespace mongo {
@@ -86,51 +87,14 @@ public:
int options,
std::string& errmsg,
BSONObjBuilder& result) {
+ const auto version = uassertStatusOK(
+ FeatureCompatibilityVersionCommandParser::extractVersionFromCommand(getName(), cmdObj));
- // Validate command.
- std::string version;
- for (auto&& elem : cmdObj) {
- if (elem.fieldNameStringData() == FeatureCompatibilityVersion::kCommandName) {
- uassert(ErrorCodes::TypeMismatch,
- str::stream()
- << FeatureCompatibilityVersion::kCommandName
- << " must be of type String, but was of type "
- << typeName(elem.type())
- << " in: "
- << cmdObj
- << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.",
- elem.type() == BSONType::String);
- version = elem.String();
- } else {
- uasserted(ErrorCodes::FailedToParse,
- str::stream()
- << "unrecognized field '"
- << elem.fieldName()
- << "' in: "
- << cmdObj
- << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.");
- }
- }
-
- uassert(ErrorCodes::BadValue,
- str::stream() << "invalid value for " << FeatureCompatibilityVersion::kCommandName
- << ", expected '"
- << FeatureCompatibilityVersion::kVersion34
- << "' or '"
- << FeatureCompatibilityVersion::kVersion32
- << "', found "
- << version
- << " in: "
- << cmdObj
- << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.",
- version == FeatureCompatibilityVersion::kVersion34 ||
- version == FeatureCompatibilityVersion::kVersion32);
-
- // Set featureCompatibilityVersion.
FeatureCompatibilityVersion::set(txn, version);
return true;
}
+
} setFeatureCompatibilityVersionCommand;
} // namespace
diff --git a/src/mongo/db/s/config/configsvr_control_balancer_command.cpp b/src/mongo/db/s/config/configsvr_control_balancer_command.cpp
index 7c269919384..88deff30a9e 100644
--- a/src/mongo/db/s/config/configsvr_control_balancer_command.cpp
+++ b/src/mongo/db/s/config/configsvr_control_balancer_command.cpp
@@ -78,16 +78,14 @@ public:
int options,
std::string& errmsg,
BSONObjBuilder& result) final {
- if (cmdObj.firstElementFieldName() != getName()) {
- uasserted(ErrorCodes::InternalError,
- str::stream() << "Expected to find a " << getName() << " command, but found "
- << cmdObj);
- }
-
- if (serverGlobalParams.clusterRole != ClusterRole::ConfigServer) {
- uasserted(ErrorCodes::IllegalOperation,
- str::stream() << getName() << " can only be run on config servers");
- }
+ uassert(ErrorCodes::InternalError,
+ str::stream() << "Expected to find a " << getName() << " command, but found "
+ << cmdObj,
+ cmdObj.firstElementFieldName() == getName());
+
+ uassert(ErrorCodes::IllegalOperation,
+ str::stream() << getName() << " can only be run on config servers",
+ serverGlobalParams.clusterRole == ClusterRole::ConfigServer);
_run(txn, &result);
diff --git a/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp b/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp
index d42e9313c54..694cec5f96c 100644
--- a/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/feature_compatibility_version.h"
+#include "mongo/db/commands/feature_compatibility_version_command_parser.h"
#include "mongo/s/catalog/sharding_catalog_manager.h"
#include "mongo/s/grid.h"
@@ -86,58 +87,25 @@ public:
int options,
std::string& errmsg,
BSONObjBuilder& result) override {
+ const auto version = uassertStatusOK(
+ FeatureCompatibilityVersionCommandParser::extractVersionFromCommand(getName(), cmdObj));
+
uassert(ErrorCodes::IllegalOperation,
- "_configsvrSetFeatureCompatibilityVersion can only be run on config servers. See "
- "http://dochub.mongodb.org/core/3.4-feature-compatibility.",
+ str::stream() << getName()
+ << " can only be run on config servers. See "
+ "http://dochub.mongodb.org/core/3.4-feature-compatibility.",
serverGlobalParams.clusterRole == ClusterRole::ConfigServer);
- // Validate command.
- std::string version;
- for (auto&& elem : cmdObj) {
- if (elem.fieldNameStringData() == "_configsvrSetFeatureCompatibilityVersion") {
- uassert(ErrorCodes::TypeMismatch,
- str::stream()
- << "_configsvrSetFeatureCompatibilityVersion must be of type "
- "String, but was of type "
- << typeName(elem.type())
- << " in: "
- << cmdObj
- << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.",
- elem.type() == BSONType::String);
- version = elem.String();
- } else {
- uasserted(ErrorCodes::FailedToParse,
- str::stream()
- << "unrecognized field '"
- << elem.fieldName()
- << "' in: "
- << cmdObj
- << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.");
- }
- }
-
- uassert(ErrorCodes::BadValue,
- str::stream()
- << "invalid value for _configsvrSetFeatureCompatibilityVersion, expected '"
- << FeatureCompatibilityVersion::kVersion34
- << "' or '"
- << FeatureCompatibilityVersion::kVersion32
- << "', found "
- << version
- << " in: "
- << cmdObj
- << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.",
- version == FeatureCompatibilityVersion::kVersion34 ||
- version == FeatureCompatibilityVersion::kVersion32);
-
// Forward to all shards.
uassertStatusOK(
Grid::get(txn)->catalogManager()->setFeatureCompatibilityVersionOnShards(txn, version));
// On success, set featureCompatibilityVersion on self.
FeatureCompatibilityVersion::set(txn, version);
+
return true;
}
+
} configsvrSetFeatureCompatibilityVersionCmd;
} // namespace