Status ShardingNetworkConnectionHook::validateHostImpl( const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) { auto shard = grid.shardRegistry()->getShardNoReload(remoteHost.toString()); if (!shard) { return {ErrorCodes::ShardNotFound, str::stream() << "No shard found for host: " << remoteHost.toString()}; } long long configServerModeNumber; auto status = bsonExtractIntegerField(isMasterReply.data, "configsvr", &configServerModeNumber); switch (status.code()) { case ErrorCodes::OK: { // The ismaster response indicates remoteHost is a config server. if (!shard->isConfig()) { return {ErrorCodes::InvalidOptions, str::stream() << "Surprised to discover that " << remoteHost.toString() << " believes it is a config server"}; } using ConfigServerMode = CatalogManager::ConfigServerMode; const BSONElement setName = isMasterReply.data["setName"]; return grid.forwardingCatalogManager()->scheduleReplaceCatalogManagerIfNeeded( (configServerModeNumber == 0 ? ConfigServerMode::SCCC : ConfigServerMode::CSRS), (setName.type() == String ? setName.valueStringData() : StringData()), remoteHost); } case ErrorCodes::NoSuchKey: { // The ismaster response indicates that remoteHost is not a config server, or that // the config server is running a version prior to the 3.1 development series. if (!shard->isConfig()) { return Status::OK(); } long long remoteMaxWireVersion; status = bsonExtractIntegerFieldWithDefault(isMasterReply.data, "maxWireVersion", RELEASE_2_4_AND_BEFORE, &remoteMaxWireVersion); if (!status.isOK()) { return status; } if (remoteMaxWireVersion < FIND_COMMAND) { // Prior to the introduction of the find command and the 3.1 release series, it was // not possible to distinguish a config server from a shard server from its ismaster // response. As such, we must assume that the system is properly configured. return Status::OK(); } return {ErrorCodes::InvalidOptions, str::stream() << "Surprised to discover that " << remoteHost.toString() << " does not believe it is a config server"}; } default: // The ismaster response was malformed. return status; } }
Status ShardingNetworkConnectionHook::validateHostImpl( const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) { auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost); if (!shard) { return {ErrorCodes::ShardNotFound, str::stream() << "No shard found for host: " << remoteHost.toString()}; } long long configServerModeNumber; auto status = bsonExtractIntegerField(isMasterReply.data, "configsvr", &configServerModeNumber); // TODO SERVER-22320 fix should collapse the switch to only NoSuchKey handling switch (status.code()) { case ErrorCodes::OK: { // The ismaster response indicates remoteHost is a config server. if (!shard->isConfig()) { return {ErrorCodes::InvalidOptions, str::stream() << "Surprised to discover that " << remoteHost.toString() << " believes it is a config server"}; } return Status::OK(); } case ErrorCodes::NoSuchKey: { // The ismaster response indicates that remoteHost is not a config server, or that // the config server is running a version prior to the 3.1 development series. if (!shard->isConfig()) { return Status::OK(); } long long remoteMaxWireVersion; status = bsonExtractIntegerFieldWithDefault(isMasterReply.data, "maxWireVersion", RELEASE_2_4_AND_BEFORE, &remoteMaxWireVersion); if (!status.isOK()) { return status; } if (remoteMaxWireVersion < FIND_COMMAND) { // Prior to the introduction of the find command and the 3.1 release series, it was // not possible to distinguish a config server from a shard server from its ismaster // response. As such, we must assume that the system is properly configured. return Status::OK(); } return {ErrorCodes::InvalidOptions, str::stream() << "Surprised to discover that " << remoteHost.toString() << " does not believe it is a config server"}; } default: // The ismaster response was malformed. return status; } }
StatusWith<boost::optional<executor::RemoteCommandRequest>> ShardingNetworkConnectionHook::makeRequest(const HostAndPort& remoteHost) { if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) { // TODO: SERVER-23973 Temporary crutch until we decide where to get the config server // connection string. return {boost::none}; } auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost); if (!shard) { return {ErrorCodes::ShardNotFound, str::stream() << "No shard found for host: " << remoteHost.toString()}; } if (shard->isConfig()) { // No need to initialize sharding metadata if talking to a config server return {boost::none}; } SetShardVersionRequest ssv = SetShardVersionRequest::makeForInitNoPersist( grid.shardRegistry()->getConfigServerConnectionString(), shard->getId(), shard->getConnString()); executor::RemoteCommandRequest request; request.dbname = "admin"; request.target = remoteHost; request.timeout = stdx::chrono::seconds{30}; request.cmdObj = ssv.toBSON(); return {request}; }
Status ShardingNetworkConnectionHook::validateHostImpl( const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) { auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost); if (!shard) { return {ErrorCodes::ShardNotFound, str::stream() << "No shard found for host: " << remoteHost.toString()}; } long long configServerModeNumber; auto status = bsonExtractIntegerField(isMasterReply.data, "configsvr", &configServerModeNumber); // TODO SERVER-22320 fix should collapse the switch to only NoSuchKey handling switch (status.code()) { case ErrorCodes::OK: { // The ismaster response indicates remoteHost is a config server. if (!shard->isConfig()) { return {ErrorCodes::InvalidOptions, str::stream() << "Surprised to discover that " << remoteHost.toString() << " believes it is a config server"}; } return Status::OK(); } case ErrorCodes::NoSuchKey: { // The ismaster response indicates that remoteHost is not a config server, or that // the config server is running a version prior to the 3.1 development series. if (!shard->isConfig()) { return Status::OK(); } return {ErrorCodes::InvalidOptions, str::stream() << "Surprised to discover that " << remoteHost.toString() << " does not believe it is a config server"}; } default: // The ismaster response was malformed. return status; } }
StatusWith<boost::optional<executor::RemoteCommandRequest>> ShardingNetworkConnectionHook::makeRequest(const HostAndPort& remoteHost) { auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost); if (!shard) { return {ErrorCodes::ShardNotFound, str::stream() << "No shard found for host: " << remoteHost.toString()}; } if (shard->isConfig()) { // No need to initialize sharding metadata if talking to a config server return {boost::none}; } SetShardVersionRequest ssv = SetShardVersionRequest::makeForInitNoPersist( grid.shardRegistry()->getConfigServerConnectionString(), shard->getId(), shard->getConnString()); executor::RemoteCommandRequest request; request.dbname = "admin"; request.target = remoteHost; request.timeout = Seconds{30}; request.cmdObj = ssv.toBSON(); return {request}; }