From 4afeb91fb45bb343583a218e23b971cf7b3c33f1 Mon Sep 17 00:00:00 2001 From: Randolph Tan Date: Tue, 24 Nov 2015 14:32:25 -0500 Subject: SERVER-21604 v3.0 mongos fails to ping config.mongos if config servers are v3.2 --- src/mongo/db/commands/find_and_modify.cpp | 2 +- src/mongo/db/commands/get_last_error.cpp | 2 +- .../db/commands/write_commands/write_commands.cpp | 2 +- src/mongo/db/write_concern.cpp | 21 +++++++++++++++++---- src/mongo/db/write_concern.h | 7 +++++-- 5 files changed, 25 insertions(+), 9 deletions(-) (limited to 'src/mongo/db') diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp index ea45097bacf..7ed7b43985f 100644 --- a/src/mongo/db/commands/find_and_modify.cpp +++ b/src/mongo/db/commands/find_and_modify.cpp @@ -344,7 +344,7 @@ public: const FindAndModifyRequest& args = parseStatus.getValue(); const NamespaceString& nsString = args.getNamespaceString(); - StatusWith wcResult = extractWriteConcern(cmdObj, dbName); + StatusWith wcResult = extractWriteConcern(txn, cmdObj, dbName); if (!wcResult.isOK()) { return appendCommandStatus(result, wcResult.getStatus()); } diff --git a/src/mongo/db/commands/get_last_error.cpp b/src/mongo/db/commands/get_last_error.cpp index b50059dfafe..dfb8a6d7097 100644 --- a/src/mongo/db/commands/get_last_error.cpp +++ b/src/mongo/db/commands/get_last_error.cpp @@ -224,7 +224,7 @@ public: if (status.isOK()) { // Ensure options are valid for this host - status = validateWriteConcern(writeConcern, dbname); + status = validateWriteConcern(txn, writeConcern, dbname); } if (!status.isOK()) { diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp index f53bc5097eb..4d5f625c948 100644 --- a/src/mongo/db/commands/write_commands/write_commands.cpp +++ b/src/mongo/db/commands/write_commands/write_commands.cpp @@ -131,7 +131,7 @@ bool WriteCmd::run(OperationContext* txn, return appendCommandStatus(result, Status(ErrorCodes::FailedToParse, errMsg)); } - StatusWith wcStatus = extractWriteConcern(cmdObj, dbName); + StatusWith wcStatus = extractWriteConcern(txn, cmdObj, dbName); if (!wcStatus.isOK()) { return appendCommandStatus(result, wcStatus.getStatus()); diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp index e5e700fa49e..6f447d8b666 100644 --- a/src/mongo/db/write_concern.cpp +++ b/src/mongo/db/write_concern.cpp @@ -42,6 +42,7 @@ #include "mongo/db/stats/timer_stats.h" #include "mongo/db/storage/storage_engine.h" #include "mongo/db/write_concern_options.h" +#include "mongo/rpc/protocol.h" namespace mongo { @@ -78,7 +79,8 @@ void addJournalSyncForWMajority(WriteConcernOptions* writeConcern) { const std::string kLocalDB = "local"; } // namespace -StatusWith extractWriteConcern(const BSONObj& cmdObj, +StatusWith extractWriteConcern(OperationContext* txn, + const BSONObj& cmdObj, const std::string& dbName) { // The default write concern if empty is w : 1 // Specifying w : 0 is/was allowed, but is interpreted identically to w : 1 @@ -111,7 +113,7 @@ StatusWith extractWriteConcern(const BSONObj& cmdObj, return wcStatus; } - wcStatus = validateWriteConcern(writeConcern, dbName); + wcStatus = validateWriteConcern(txn, writeConcern, dbName); if (!wcStatus.isOK()) { return wcStatus; } @@ -121,7 +123,9 @@ StatusWith extractWriteConcern(const BSONObj& cmdObj, return writeConcern; } -Status validateWriteConcern(const WriteConcernOptions& writeConcern, const std::string& dbName) { +Status validateWriteConcern(OperationContext* txn, + const WriteConcernOptions& writeConcern, + const std::string& dbName) { const bool isJournalEnabled = getGlobalServiceContext()->getGlobalStorageEngine()->isDurable(); if (writeConcern.syncMode == WriteConcernOptions::JOURNAL && !isJournalEnabled) { @@ -135,6 +139,15 @@ Status validateWriteConcern(const WriteConcernOptions& writeConcern, const std:: repl::getGlobalReplicationCoordinator()->getReplicationMode(); if (isConfigServer) { + auto protocol = rpc::getOperationProtocol(txn); + // This here only for v3.0 backwards compatibility. + if (serverGlobalParams.configsvrMode != CatalogManager::ConfigServerMode::CSRS && + replMode != repl::ReplicationCoordinator::modeReplSet && + protocol == rpc::Protocol::kOpQuery && writeConcern.wNumNodes == 0 && + writeConcern.wMode.empty()) { + return Status::OK(); + } + if (!writeConcern.validForConfigServers()) { return Status( ErrorCodes::BadValue, @@ -224,7 +237,7 @@ Status waitForWriteConcern(OperationContext* txn, WriteConcernResult* result) { // We assume all options have been validated earlier, if not, programming error. // Passing localDB name is a hack to avoid more rigorous check that performed for non local DB. - dassert(validateWriteConcern(writeConcern, kLocalDB).isOK()); + dassert(validateWriteConcern(txn, writeConcern, kLocalDB).isOK()); // We should never be waiting for write concern while holding any sort of lock, because this may // lead to situations where the replication heartbeats are stalled. diff --git a/src/mongo/db/write_concern.h b/src/mongo/db/write_concern.h index 146a7ec94d0..873e6114af1 100644 --- a/src/mongo/db/write_concern.h +++ b/src/mongo/db/write_concern.h @@ -54,13 +54,16 @@ void setupSynchronousCommit(OperationContext* txn); * Verifies that the writeConcern is of type Object (BSON type) and * that the resulting writeConcern is valid for this particular host. */ -StatusWith extractWriteConcern(const BSONObj& cmdObj, +StatusWith extractWriteConcern(OperationContext* txn, + const BSONObj& cmdObj, const std::string& dbName); /** * Verifies that a WriteConcern is valid for this particular host. */ -Status validateWriteConcern(const WriteConcernOptions& writeConcern, const std::string& dbName); +Status validateWriteConcern(OperationContext* txn, + const WriteConcernOptions& writeConcern, + const std::string& dbName); struct WriteConcernResult { WriteConcernResult() { -- cgit v1.2.1