Skip to content

Commit

Permalink
SERVER-19545 Prohibit config server replica sets from being added as …
Browse files Browse the repository at this point in the history
…shards
  • Loading branch information
stbrody committed Aug 3, 2015
1 parent e8b4e57 commit 998705d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
13 changes: 13 additions & 0 deletions jstests/sharding/addshard2.js
Expand Up @@ -25,6 +25,15 @@ var rs4 = new ReplSetTest({ 'name': 'admin', nodes: 3, startPort: 31209 });
rs4.startSet();
rs4.initiate();

// replica set with configServer: true should *not* be allowed to be added as a shard
var rs5 = new ReplSetTest({ 'name': 'csrs', nodes: 3, startPort: 31212 });
rs5.startSet();
var conf = rs5.getReplSetConfig();
conf.configServer = true;
conf.settings = {protocolVersion: 1};
rs5.initiate(conf);


// step 1. name given
assert(s.admin.runCommand({"addshard" : getHostName()+":" + conn1.port, "name" : "bar"}).ok,
"failed to add shard in step 1");
Expand Down Expand Up @@ -82,8 +91,12 @@ var wRes = s.getDB('test').foo.insert({ x: 1 });
assert(!wRes.hasWriteError() && wRes.nInserted === 1,
'failed to insert document into "test.foo" unsharded collection');

// SERVER-19545 Should not be able to add config server replsets as shards.
assert.commandFailed(s.admin.runCommand({addshard: rs5.getURL()}));

s.stop();
rs1.stopSet();
rs2.stopSet();
rs3.stopSet();
rs4.stopSet();
rs5.stopSet();
4 changes: 4 additions & 0 deletions src/mongo/db/repl/topology_coordinator_impl.cpp
Expand Up @@ -1503,6 +1503,10 @@ void TopologyCoordinatorImpl::prepareStatusResponse(const ReplicationExecutor::C
response->append("syncingTo", _syncSource.toString());
}

if (_rsConfig.isConfigServer()) {
response->append("configServer", true);
}

response->append("members", membersOut);
*result = Status::OK();
}
Expand Down
35 changes: 25 additions & 10 deletions src/mongo/s/catalog/catalog_manager.cpp
Expand Up @@ -36,6 +36,7 @@

#include "mongo/base/status.h"
#include "mongo/base/status_with.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/client/read_preference.h"
#include "mongo/client/remote_command_targeter.h"
#include "mongo/client/replica_set_monitor.h"
Expand Down Expand Up @@ -182,20 +183,34 @@ StatusWith<ShardType> validateHostAsShard(ShardRegistry* shardRegistry,
}

// Is it a mongos config server?
if (foundSetName.empty()) {
cmdStatus = shardRegistry->runCommand(shardHost, "admin", BSON("replSetGetStatus" << 1));
if (!cmdStatus.isOK()) {
return cmdStatus.getStatus();
}
cmdStatus = shardRegistry->runCommand(shardHost, "admin", BSON("replSetGetStatus" << 1));
if (!cmdStatus.isOK()) {
return cmdStatus.getStatus();
}

BSONObj res = cmdStatus.getValue();
BSONObj res = cmdStatus.getValue();

if (!getStatusFromCommandResult(res).isOK() && (res["info"].type() == String) &&
(res["info"].String() == "configsvr")) {
if (getStatusFromCommandResult(res).isOK()) {
bool isConfigServer;
Status status =
bsonExtractBooleanFieldWithDefault(res, "configServer", false, &isConfigServer);
if (!status.isOK()) {
return Status(status.code(),
str::stream() << "replSetGetStatus returned invalid \"configServer\" "
<< "field when attempting to add "
<< connectionString.toString()
<< " as a shard: " << status.reason());
}

if (isConfigServer) {
return {ErrorCodes::BadValue,
"the specified mongod is a legacy-style config "
"server and cannot be used as a shard server"};
str::stream() << "Cannot add " << connectionString.toString()
<< " as a shard since it is part of a config server replica set"};
}
} else if ((res["info"].type() == String) && (res["info"].String() == "configsvr")) {
return {ErrorCodes::BadValue,
"the specified mongod is a legacy-style config "
"server and cannot be used as a shard server"};
}

// If the shard is part of a replica set, make sure all the hosts mentioned in the connection
Expand Down

0 comments on commit 998705d

Please sign in to comment.