// Checks that all config servers are online bool _checkConfigServersAlive(const ConnectionString& configLoc, string* errMsg) { scoped_ptr<ScopedDbConnection> connPtr; bool resultOk; BSONObj result; try { connPtr.reset(ScopedDbConnection::getInternalScopedDbConnection(configLoc, 30)); ScopedDbConnection& conn = *connPtr; if (conn->type() == ConnectionString::SYNC) { // TODO: Dynamic cast is bad, we need a better way of managing this op // via the heirarchy (or not) SyncClusterConnection* scc = dynamic_cast<SyncClusterConnection*>(conn.get()); fassert(16729, scc != NULL); return scc->prepare(*errMsg); } else { resultOk = conn->runCommand("admin", BSON( "fsync" << 1 ), result); } } catch (const DBException& e) { *errMsg = e.toString(); return false; } connPtr->done(); if (!resultOk) { *errMsg = DBClientWithCommands::getLastErrorString(result); return false; } return true; }
void ShardingConnectionHook::onCreate(DBClientBase* conn) { // Authenticate as the first thing we do // NOTE: Replica set authentication allows authentication against *any* online host if (getGlobalAuthorizationManager()->isAuthEnabled()) { LOG(2) << "calling onCreate auth for " << conn->toString(); bool result = conn->authenticateInternalUser(); uassert(15847, str::stream() << "can't authenticate to server " << conn->getServerAddress(), result); } if (_shardedConnections) { conn->setReplyMetadataReader(_shardingReplyMetadataReader); } conn->setRequestMetadataWriter( [this](BSONObjBuilder* metadataBob, StringData hostStringData) -> Status { return _shardingRequestMetadataWriter(_shardedConnections, metadataBob, hostStringData); }); // For every SCC created, add a hook that will allow fastest-config-first config reads if // the appropriate server options are set. if (conn->type() == ConnectionString::SYNC) { SyncClusterConnection* scc = dynamic_cast<SyncClusterConnection*>(conn); if (scc) { scc->attachQueryHandler(new SCCFastQueryHandler); } } else if (conn->type() == ConnectionString::MASTER) { BSONObj isMasterResponse; if (!conn->runCommand("admin", BSON("ismaster" << 1), isMasterResponse)) { uassertStatusOK(getStatusFromCommandResult(isMasterResponse)); } long long configServerModeNumber; Status status = bsonExtractIntegerField(isMasterResponse, "configsvr", &configServerModeNumber); if (status == ErrorCodes::NoSuchKey) { // This isn't a config server we're talking to. return; } uassert(28785, str::stream() << "Unrecognized configsvr version number: " << configServerModeNumber << ". Expected either 0 or 1", configServerModeNumber == 0 || configServerModeNumber == 1); BSONElement setName = isMasterResponse["setName"]; status = grid.forwardingCatalogManager()->scheduleReplaceCatalogManagerIfNeeded( configServerModeNumber == 0 ? CatalogManager::ConfigServerMode::SCCC : CatalogManager::ConfigServerMode::CSRS, setName.type() == String ? setName.valueStringData() : StringData(), static_cast<DBClientConnection*>(conn)->getServerHostAndPort()); uassertStatusOK(status); } }
void ShardingConnectionHook::onCreate(DBClientBase * conn) { // Authenticate as the first thing we do // NOTE: Replica set authentication allows authentication against *any* online host if (getGlobalAuthorizationManager()->isAuthEnabled()) { LOG(2) << "calling onCreate auth for " << conn->toString(); bool result = authenticateInternalUser(conn); uassert(15847, str::stream() << "can't authenticate to server " << conn->getServerAddress(), result); } // Initialize the wire version of single connections if (conn->type() == ConnectionString::MASTER) { LOG(2) << "checking wire version of new connection " << conn->toString(); // Initialize the wire protocol version of the connection to find out if we // can send write commands to this connection. string errMsg; if (!initWireVersion(conn, &errMsg)) { uasserted(17363, errMsg); } } if (_shardedConnections) { // For every DBClient created by mongos, add a hook that will capture the response from // commands we pass along from the client, so that we can target the correct node when // subsequent getLastError calls are made by mongos. conn->setReplyMetadataReader([](const BSONObj& metadataObj, StringData hostString) -> Status { saveGLEStats(metadataObj, hostString); return Status::OK(); }); } // For every DBClient created by mongos, add a hook that will append impersonated users // to the end of every runCommand. mongod uses this information to produce auditing // records attributed to the proper authenticated user(s). conn->setRequestMetadataWriter([](BSONObjBuilder* metadataBob) -> Status { audit::writeImpersonatedUsersToMetadata(metadataBob); return Status::OK(); }); // For every SCC created, add a hook that will allow fastest-config-first config reads if // the appropriate server options are set. if (conn->type() == ConnectionString::SYNC) { SyncClusterConnection* scc = dynamic_cast<SyncClusterConnection*>(conn); if (scc) { scc->attachQueryHandler(new SCCFastQueryHandler); } } }
void ShardingConnectionHook::onCreate(DBClientBase* conn) { // Authenticate as the first thing we do // NOTE: Replica set authentication allows authentication against *any* online host if (getGlobalAuthorizationManager()->isAuthEnabled()) { LOG(2) << "calling onCreate auth for " << conn->toString(); bool result = conn->authenticateInternalUser(); uassert(15847, str::stream() << "can't authenticate to server " << conn->getServerAddress(), result); } if (_shardedConnections) { // For every DBClient created by mongos, add a hook that will capture the response from // commands we pass along from the client, so that we can target the correct node when // subsequent getLastError calls are made by mongos. conn->setReplyMetadataReader([](const BSONObj& metadataObj, StringData hostString) -> Status { saveGLEStats(metadataObj, hostString); return Status::OK(); }); } // For every DBClient created by mongos, add a hook that will append impersonated users // to the end of every runCommand. mongod uses this information to produce auditing // records attributed to the proper authenticated user(s). conn->setRequestMetadataWriter([](BSONObjBuilder* metadataBob) -> Status { audit::writeImpersonatedUsersToMetadata(metadataBob); return Status::OK(); }); // For every SCC created, add a hook that will allow fastest-config-first config reads if // the appropriate server options are set. if (conn->type() == ConnectionString::SYNC) { SyncClusterConnection* scc = dynamic_cast<SyncClusterConnection*>(conn); if (scc) { scc->attachQueryHandler(new SCCFastQueryHandler); } } else if (conn->type() == ConnectionString::MASTER) { BSONObj isMasterResponse; if (!conn->runCommand("admin", BSON("ismaster" << 1), isMasterResponse)) { uassertStatusOK(getStatusFromCommandResult(isMasterResponse)); } long long configServerModeNumber; Status status = bsonExtractIntegerField(isMasterResponse, "configsvr", &configServerModeNumber); if (status == ErrorCodes::NoSuchKey) { // This isn't a config server we're talking to. return; } uassert(28785, str::stream() << "Unrecognized configsvr version number: " << configServerModeNumber << ". Expected either 0 or 1", configServerModeNumber == 0 || configServerModeNumber == 1); BSONElement setName = isMasterResponse["setName"]; status = grid.catalogManager()->scheduleReplaceCatalogManagerIfNeeded( configServerModeNumber == 0 ? CatalogManager::ConfigServerMode::SCCC : CatalogManager::ConfigServerMode::CSRS, setName.type() == String ? setName.valueStringData() : StringData(), static_cast<DBClientConnection*>(conn)->getServerHostAndPort()); uassertStatusOK(status); } }