From eadabb492ee5e8ad8a37bb3aedd7d198c772da62 Mon Sep 17 00:00:00 2001 From: Kaloian Manassiev Date: Wed, 20 May 2015 17:07:22 -0400 Subject: SERVER-18567 Replace usages of the legacy ConnectionString::parse This is all the non-sharding code, which is using it. --- src/mongo/base/error_codes.err | 1 + src/mongo/client/connpool.cpp | 5 +- src/mongo/db/catalog/database_holder.cpp | 2 +- src/mongo/db/cloner.cpp | 61 ++++++++++------------ src/mongo/db/cloner.h | 16 +++--- src/mongo/db/commands/clone.cpp | 29 ++++------ src/mongo/db/commands/copydb.cpp | 35 +++++-------- src/mongo/db/commands/copydb_start_commands.cpp | 30 +++-------- src/mongo/db/repl/master_slave.cpp | 29 +++++----- src/mongo/db/repl/rs_initialsync.cpp | 7 ++- src/mongo/s/catalog/catalog_manager.h | 4 +- .../s/catalog/legacy/catalog_manager_legacy.cpp | 2 +- src/mongo/scripting/v8-3.25_db.cpp | 10 ++-- src/mongo/scripting/v8_db.cpp | 10 ++-- src/mongo/shell/bench.cpp | 5 +- src/mongo/shell/shell_utils.cpp | 12 +++-- src/mongo/util/assert_util.h | 1 - 17 files changed, 110 insertions(+), 149 deletions(-) (limited to 'src/mongo') diff --git a/src/mongo/base/error_codes.err b/src/mongo/base/error_codes.err index 07c2f56f2b2..f7431039681 100644 --- a/src/mongo/base/error_codes.err +++ b/src/mongo/base/error_codes.err @@ -140,6 +140,7 @@ error_code("NotMasterOrSecondaryCode", 13436); error_code("NotMasterNoSlaveOkCode", 13435); error_code("ShardKeyTooBig", 13334); error_code("SendStaleConfig", 13388); +error_code("DatabaseDifferCase", 13297); error_class("NetworkError", ["HostUnreachable", "HostNotFound", "NetworkTimeout"]) error_class("Interruption", ["Interrupted", "InterruptedAtShutdown", "ExceededTimeLimit"]) diff --git a/src/mongo/client/connpool.cpp b/src/mongo/client/connpool.cpp index 4b3002e1322..2357f930742 100644 --- a/src/mongo/client/connpool.cpp +++ b/src/mongo/client/connpool.cpp @@ -249,10 +249,9 @@ namespace mongo { return c; } - string errmsg; - ConnectionString cs = ConnectionString::parse( host , errmsg ); - uassert( 13071 , (string)"invalid hostname [" + host + "]" + errmsg , cs.isValid() ); + const ConnectionString cs(uassertStatusOK(ConnectionString::parse(host))); + string errmsg; c = cs.connect( errmsg, socketTimeout ); if ( ! c ) throw SocketException( SocketException::CONNECT_ERROR , host , 11002 , str::stream() << _name << " error: " << errmsg ); diff --git a/src/mongo/db/catalog/database_holder.cpp b/src/mongo/db/catalog/database_holder.cpp index 61110aa2b5e..7ff6ea6d81b 100644 --- a/src/mongo/db/catalog/database_holder.cpp +++ b/src/mongo/db/catalog/database_holder.cpp @@ -118,7 +118,7 @@ namespace { << "] trying to create [" << dbname.toString() << "]"; - uasserted(DatabaseDifferCaseCode, ss.str()); + uasserted(ErrorCodes::DatabaseDifferCase, ss.str()); } StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine(); diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp index 5b92cadc8a7..aaa53cccceb 100644 --- a/src/mongo/db/cloner.cpp +++ b/src/mongo/db/cloner.cpp @@ -424,28 +424,23 @@ namespace mongo { return true; } - bool Cloner::go(OperationContext* txn, - const std::string& toDBName, - const string& masterHost, - const CloneOptions& opts, - set* clonedColls, - string& errmsg, - int* errCode) { - - if ( errCode ) { - *errCode = 0; - } + Status Cloner::copyDb(OperationContext* txn, + const std::string& toDBName, + const string& masterHost, + const CloneOptions& opts, + set* clonedColls) { + massert(10289, "useReplAuth is not written to replication log", !opts.useReplAuth || !txn->writesAreReplicated()); - const ConnectionString cs = ConnectionString::parse(masterHost, errmsg); - if (!cs.isValid()) { - if (errCode) - *errCode = ErrorCodes::FailedToParse; - return false; + auto statusWithMasterHost = ConnectionString::parse(masterHost); + if (!statusWithMasterHost.isOK()) { + return statusWithMasterHost.getStatus(); } + const ConnectionString cs(statusWithMasterHost.getValue()); + bool masterSameProcess = false; std::vector csServers = cs.getServers(); for (std::vector::const_iterator iter = csServers.begin(); @@ -460,10 +455,8 @@ namespace mongo { if (masterSameProcess) { if (opts.fromDB == toDBName) { - // guard against an "infinite" loop - /* if you are replicating, the local.sources config may be wrong if you get this */ - errmsg = "can't clone from self (localhost)."; - return false; + // Guard against re-entrance + return Status(ErrorCodes::IllegalOperation, "can't clone from self (localhost)"); } } @@ -473,13 +466,17 @@ namespace mongo { // nothing to do } else if ( !masterSameProcess ) { + std::string errmsg; auto_ptr con( cs.connect( errmsg )); - if ( !con.get() ) - return false; + if (!con.get()) { + return Status(ErrorCodes::HostUnreachable, errmsg); + } + if (getGlobalAuthorizationManager()->isAuthEnabled() && - !authenticateInternalUser(con.get())) { + !authenticateInternalUser(con.get())) { - return false; + return Status(ErrorCodes::AuthenticationFailed, + "Unable to authenticate as internal user"); } _conn = con; @@ -509,10 +506,8 @@ namespace mongo { BSONElement collectionOptions = collection["options"]; if ( collectionOptions.isABSONObj() ) { Status parseOptionsStatus = CollectionOptions().parse(collectionOptions.Obj()); - if ( !parseOptionsStatus.isOK() ) { - errmsg = str::stream() << "invalid collection options: " << collection - << ", reason: " << parseOptionsStatus.reason(); - return false; + if (!parseOptionsStatus.isOK()) { + return parseOptionsStatus; } } @@ -580,12 +575,10 @@ namespace mongo { // we defer building id index for performance - building it in batch is much // faster Status createStatus = userCreateNS(txn, db, to_name.ns(), options, false); - if ( !createStatus.isOK() ) { - errmsg = str::stream() << "failed to create collection \"" - << to_name.ns() << "\": " - << createStatus.reason(); - return false; + if (!createStatus.isOK()) { + return createStatus; } + wunit.commit(); } MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "createUser", to_name.ns()); } @@ -680,7 +673,7 @@ namespace mongo { } } - return true; + return Status::OK(); } } // namespace mongo diff --git a/src/mongo/db/cloner.h b/src/mongo/db/cloner.h index e9218d8ab67..d537932dc83 100644 --- a/src/mongo/db/cloner.h +++ b/src/mongo/db/cloner.h @@ -50,14 +50,14 @@ namespace mongo { _conn.reset(c); } - /** copy the entire database */ - bool go(OperationContext* txn, - const std::string& toDBName, - const std::string& masterHost, - const CloneOptions& opts, - std::set* clonedColls, - std::string& errmsg, - int *errCode = 0); + /** + * Copies an entire database from the specified host. + */ + Status copyDb(OperationContext* txn, + const std::string& toDBName, + const std::string& masterHost, + const CloneOptions& opts, + std::set* clonedColls); bool copyCollection(OperationContext* txn, const std::string& ns, diff --git a/src/mongo/db/commands/clone.cpp b/src/mongo/db/commands/clone.cpp index 565d214ff44..f2fd0d8928f 100644 --- a/src/mongo/db/commands/clone.cpp +++ b/src/mongo/db/commands/clone.cpp @@ -28,28 +28,18 @@ #include "mongo/platform/basic.h" -#include "mongo/base/init.h" #include "mongo/base/status.h" -#include "mongo/bson/util/builder.h" -#include "mongo/client/dbclientinterface.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/resource_pattern.h" #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/cloner.h" #include "mongo/db/commands.h" -#include "mongo/db/commands/copydb.h" -#include "mongo/db/commands/rename_collection.h" -#include "mongo/db/dbhelpers.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/operation_context_impl.h" -#include "mongo/db/storage_options.h" -namespace mongo { +namespace { + + using namespace mongo; using std::set; using std::string; @@ -100,8 +90,9 @@ namespace mongo { BSONObjBuilder& result) { boost::optional maybeDisableValidation; - if (shouldBypassDocumentValidationForCommand(cmdObj)) + if (shouldBypassDocumentValidationForCommand(cmdObj)) { maybeDisableValidation.emplace(txn); + } string from = cmdObj.getStringField("clone"); if ( from.empty() ) @@ -129,16 +120,16 @@ namespace mongo { Lock::DBLock dbXLock(txn->lockState(), dbname, MODE_X); Cloner cloner; - bool rval = cloner.go(txn, dbname, from, opts, &clonedColls, errmsg); + Status status = cloner.copyDb(txn, dbname, from, opts, &clonedColls); BSONArrayBuilder barr; barr.append( clonedColls ); - result.append( "clonedColls", barr.arr() ); - - return rval; + result.append("clonedColls", barr.arr()); + return appendCommandStatus(result, status); } + } cmdClone; -} // namespace mongo +} // namespace diff --git a/src/mongo/db/commands/copydb.cpp b/src/mongo/db/commands/copydb.cpp index 09e1fc28089..25b5c00f5d7 100644 --- a/src/mongo/db/commands/copydb.cpp +++ b/src/mongo/db/commands/copydb.cpp @@ -28,32 +28,22 @@ #include "mongo/platform/basic.h" -#include "mongo/base/init.h" #include "mongo/base/status.h" -#include "mongo/bson/util/bson_extract.h" -#include "mongo/bson/util/builder.h" -#include "mongo/client/dbclientinterface.h" #include "mongo/client/sasl_client_authenticate.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/resource_pattern.h" #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/cloner.h" #include "mongo/db/commands.h" #include "mongo/db/commands/copydb.h" #include "mongo/db/commands/copydb_start_commands.h" -#include "mongo/db/commands/rename_collection.h" -#include "mongo/db/db.h" -#include "mongo/db/dbhelpers.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/operation_context_impl.h" -#include "mongo/db/storage_options.h" -namespace mongo { +namespace { + + using namespace mongo; using std::string; using std::stringstream; @@ -205,11 +195,7 @@ namespace mongo { } else if (!fromSelf) { // If fromSelf leave the cloner's conn empty, it will use a DBDirectClient instead. - - ConnectionString cs = ConnectionString::parse(fromhost, errmsg); - if (!cs.isValid()) { - return false; - } + const ConnectionString cs(uassertStatusOK(ConnectionString::parse(fromhost))); DBClientBase* conn = cs.connect(errmsg); if (!conn) { @@ -222,14 +208,17 @@ namespace mongo { // SERVER-4328 todo lock just the two db's not everything for the fromself case ScopedTransaction transaction(txn, MODE_X); Lock::GlobalWrite lk(txn->lockState()); - return cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg); + uassertStatusOK(cloner.copyDb(txn, todb, fromhost, cloneOptions, NULL)); + } + else { + ScopedTransaction transaction(txn, MODE_IX); + Lock::DBLock lk(txn->lockState(), todb, MODE_X); + uassertStatusOK(cloner.copyDb(txn, todb, fromhost, cloneOptions, NULL)); } - ScopedTransaction transaction(txn, MODE_IX); - Lock::DBLock lk (txn->lockState(), todb, MODE_X); - return cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg); + return true; } } cmdCopyDB; -} // namespace mongo +} // namespace diff --git a/src/mongo/db/commands/copydb_start_commands.cpp b/src/mongo/db/commands/copydb_start_commands.cpp index 99c79e9345a..56107e9c2bc 100644 --- a/src/mongo/db/commands/copydb_start_commands.cpp +++ b/src/mongo/db/commands/copydb_start_commands.cpp @@ -30,28 +30,17 @@ #include "mongo/platform/basic.h" -#include "mongo/base/init.h" #include "mongo/base/status.h" #include "mongo/bson/util/bson_extract.h" -#include "mongo/bson/util/builder.h" #include "mongo/client/dbclientinterface.h" #include "mongo/client/sasl_client_authenticate.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/resource_pattern.h" #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/catalog/collection.h" #include "mongo/db/cloner.h" #include "mongo/db/commands.h" #include "mongo/db/commands/copydb.h" -#include "mongo/db/commands/rename_collection.h" -#include "mongo/db/db.h" -#include "mongo/db/dbhelpers.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/operation_context_impl.h" -#include "mongo/db/storage_options.h" #include "mongo/util/log.h" namespace mongo { @@ -110,18 +99,15 @@ namespace mongo { fromhost = ss.str(); } - BSONObj ret; - - ConnectionString cs = ConnectionString::parse(fromhost, errmsg); - if (!cs.isValid()) { - return false; - } + const ConnectionString cs(uassertStatusOK(ConnectionString::parse(fromhost))); authConn_.reset(cs.connect(errmsg)); if (!authConn_.get()) { return false; } + BSONObj ret; + if( !authConn_->runCommand( "admin", BSON( "getnonce" << 1 ), ret ) ) { errmsg = "couldn't get nonce " + ret.toString(); return false; @@ -175,7 +161,8 @@ namespace mongo { string& errmsg, BSONObjBuilder& result) { - string fromDb = cmdObj.getStringField("fromdb"); + const string fromDb = cmdObj.getStringField("fromdb"); + string fromHost = cmdObj.getStringField("fromhost"); if ( fromHost.empty() ) { /* copy from self */ @@ -184,11 +171,7 @@ namespace mongo { fromHost = ss.str(); } - ConnectionString cs = ConnectionString::parse(fromHost, errmsg); - if (!cs.isValid()) { - appendCommandStatus(result, false, errmsg); - return false; - } + const ConnectionString cs(uassertStatusOK(ConnectionString::parse(fromHost))); BSONElement mechanismElement; Status status = bsonExtractField(cmdObj, @@ -226,4 +209,5 @@ namespace mongo { } } cmdCopyDBSaslStart; + } // namespace mongo diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp index 3a827858924..dc975fe7b90 100644 --- a/src/mongo/db/repl/master_slave.cpp +++ b/src/mongo/db/repl/master_slave.cpp @@ -473,8 +473,7 @@ namespace repl { { log() << "resync: cloning database " << db << " to get an initial copy" << endl; ReplInfo r("resync: cloning a database"); - string errmsg; - int errCode = 0; + CloneOptions cloneOptions; cloneOptions.fromDB = db; cloneOptions.slaveOk = true; @@ -484,30 +483,28 @@ namespace repl { cloneOptions.mayBeInterrupted = false; Cloner cloner; - bool ok = cloner.go(txn, - db, - hostName.c_str(), - cloneOptions, - NULL, - errmsg, - &errCode); - - if ( !ok ) { - if ( errCode == DatabaseDifferCaseCode ) { + Status status = cloner.copyDb(txn, + db, + hostName.c_str(), + cloneOptions, + NULL); + + if (!status.isOK()) { + if (status.code() == ErrorCodes::DatabaseDifferCase) { resyncDrop( txn, db ); - log() << "resync: database " << db << " not valid on the master due to a name conflict, dropping." << endl; + log() << "resync: database " << db + << " not valid on the master due to a name conflict, dropping."; return; } else { - log() << "resync of " << db << " from " << hostName << " failed " << errmsg << endl; + log() << "resync of " << db << " from " << hostName + << " failed due to: " << status.toString(); throw SyncException(); } } } log() << "resync: done with initial clone for db: " << db << endl; - - return; } static DatabaseIgnorer ___databaseIgnorer; diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp index bc68dbdad59..d8ceabaa98a 100644 --- a/src/mongo/db/repl/rs_initialsync.cpp +++ b/src/mongo/db/repl/rs_initialsync.cpp @@ -179,8 +179,6 @@ namespace { else log() << "initial sync cloning indexes for : " << db; - string err; - int errCode; CloneOptions options; options.fromDB = db; options.slaveOk = true; @@ -195,10 +193,11 @@ namespace { ScopedTransaction transaction(txn, MODE_IX); Lock::DBLock dbWrite(txn->lockState(), db, MODE_X); - if (!cloner.go(txn, db, host, options, NULL, err, &errCode)) { + Status status = cloner.copyDb(txn, db, host, options, NULL); + if (!status.isOK()) { log() << "initial sync: error while " << (dataPass ? "cloning " : "indexing ") << db - << ". " << (err.empty() ? "" : err + ". "); + << ". " << status.toString(); return false; } diff --git a/src/mongo/s/catalog/catalog_manager.h b/src/mongo/s/catalog/catalog_manager.h index 38dcdbee937..fd935d3bd96 100644 --- a/src/mongo/s/catalog/catalog_manager.h +++ b/src/mongo/s/catalog/catalog_manager.h @@ -91,7 +91,7 @@ namespace mongo { * * Returns Status::OK on success or any error code indicating the failure. These are some * of the known failures: - * - DatabaseDifferCaseCode - database already exists, but with a different case + * - DatabaseDifferCase - database already exists, but with a different case * - ShardNotFound - could not find a shard to place the DB on */ virtual Status enableSharding(const std::string& dbName) = 0; @@ -152,7 +152,7 @@ namespace mongo { * Returns Status::OK on success or any error code indicating the failure. These are some * of the known failures: * - NamespaceExists - database already exists - * - DatabaseDifferCaseCode - database already exists, but with a different case + * - DatabaseDifferCase - database already exists, but with a different case * - ShardNotFound - could not find a shard to place the DB on */ virtual Status createDatabase(const std::string& dbName) = 0; diff --git a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp index e5dce3c4064..7ac156b68a4 100644 --- a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp +++ b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp @@ -1495,7 +1495,7 @@ namespace { } if (!dbObj.isEmpty()) { - return Status(static_cast(DatabaseDifferCaseCode), + return Status(ErrorCodes::DatabaseDifferCase, str::stream() << "can't have 2 databases that just differ on case " << " have: " << dbObj[DatabaseType::name()].String() << " want to add: " << dbName); diff --git a/src/mongo/scripting/v8-3.25_db.cpp b/src/mongo/scripting/v8-3.25_db.cpp index 0c9054314bd..69066dfb2f3 100644 --- a/src/mongo/scripting/v8-3.25_db.cpp +++ b/src/mongo/scripting/v8-3.25_db.cpp @@ -139,12 +139,14 @@ namespace mongo { args.IsConstructCall()); verify(scope->MongoFT()->HasInstance(args.This())); - string errmsg; - ConnectionString cs = ConnectionString::parse(host, errmsg); - if (!cs.isValid()) { - return v8AssertionException(errmsg); + auto statusWithHost = ConnectionString::parse(host); + if (!status.isOK()) { + return v8AssertionException(statusWithHost.getStatus().reason()); } + const ConnectionString cs(statusWithHost.getValue()); + + string errmsg; DBClientBase* conn; conn = cs.connect(errmsg); if (!conn) { diff --git a/src/mongo/scripting/v8_db.cpp b/src/mongo/scripting/v8_db.cpp index c4b45d29ad9..2f9ae8c604e 100644 --- a/src/mongo/scripting/v8_db.cpp +++ b/src/mongo/scripting/v8_db.cpp @@ -145,12 +145,14 @@ namespace mongo { args.IsConstructCall()); verify(scope->MongoFT()->HasInstance(args.This())); - string errmsg; - ConnectionString cs = ConnectionString::parse(host, errmsg); - if (!cs.isValid()) { - return v8AssertionException(errmsg); + auto statusWithHost = ConnectionString::parse(host); + if (!statusWithHost.isOK()) { + return v8AssertionException(statusWithHost.getStatus().reason()); } + const ConnectionString cs(statusWithHost.getValue()); + + string errmsg; DBClientBase* conn; conn = cs.connect(errmsg); if (!conn) { diff --git a/src/mongo/shell/bench.cpp b/src/mongo/shell/bench.cpp index 62ee26be6a9..ae4fe3e0e59 100644 --- a/src/mongo/shell/bench.cpp +++ b/src/mongo/shell/bench.cpp @@ -220,11 +220,12 @@ namespace mongo { } DBClientBase *BenchRunConfig::createConnection() const { + const ConnectionString connectionString = uassertStatusOK(ConnectionString::parse(host)); + std::string errorMessage; - ConnectionString connectionString = ConnectionString::parse( host, errorMessage ); - uassert( 16157, errorMessage, connectionString.isValid() ); DBClientBase *connection = connectionString.connect(errorMessage); uassert( 16158, errorMessage, connection != NULL ); + return connection; } diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp index 0b8b1cb7c6c..1aa1792c4d0 100644 --- a/src/mongo/shell/shell_utils.cpp +++ b/src/mongo/shell/shell_utils.cpp @@ -305,11 +305,15 @@ namespace mongo { boost::lock_guard lk( _mutex ); for( map >::const_iterator i = _connectionUris.begin(); i != _connectionUris.end(); ++i ) { - string errmsg; - ConnectionString cs = ConnectionString::parse( i->first, errmsg ); - if ( !cs.isValid() ) { - continue; + + auto status = ConnectionString::parse(i->first); + if (!status.isOK()) { + continue; } + + const ConnectionString cs(status.getValue()); + + string errmsg; boost::scoped_ptr conn( cs.connect( errmsg ) ); if ( !conn ) { continue; diff --git a/src/mongo/util/assert_util.h b/src/mongo/util/assert_util.h index 7fe9a8271e7..5fd4d56aa2e 100644 --- a/src/mongo/util/assert_util.h +++ b/src/mongo/util/assert_util.h @@ -44,7 +44,6 @@ namespace mongo { enum CommonErrorCodes { OkCode = 0, - DatabaseDifferCaseCode = 13297 , // uassert( 13297 ) SendStaleConfigCode = 13388 , // uassert( 13388 ) RecvStaleConfigCode = 9996, // uassert( 9996 ) PrepareConfigsFailedCode = 13104, // uassert( 13104 ) -- cgit v1.2.1