summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Lerner <alerner@10gen.com>2010-07-30 13:21:39 -0400
committerAlberto Lerner <alerner@10gen.com>2010-07-30 13:21:39 -0400
commit5a69c45341c23f654832f948febf793c6896e6b4 (patch)
treea1b989c505f6dd27e4f5534e7b6caf2c02fc4edb
parent62310262e6f4db58d175c131ed51d8e9ebd897b4 (diff)
downloadmongo-5a69c45341c23f654832f948febf793c6896e6b4.tar.gz
SERVER-1292 For now, don't add a mongod as a shard if it's not empty. Will allow that next.
-rw-r--r--jstests/sharding/addshard1.js12
-rw-r--r--s/commands_admin.cpp3
-rw-r--r--s/grid.cpp44
-rw-r--r--s/grid.h5
4 files changed, 61 insertions, 3 deletions
diff --git a/jstests/sharding/addshard1.js b/jstests/sharding/addshard1.js
new file mode 100644
index 00000000000..5e299770fff
--- /dev/null
+++ b/jstests/sharding/addshard1.js
@@ -0,0 +1,12 @@
+s = new ShardingTest( "add_shard1", 1 );
+
+assert.eq( 1, s.config.shards.count(), "initial server count wrong" );
+
+// create a shard and add a database; a non-empty mongod should not be accepted as a shard
+conn = startMongodTest( 29000 );
+db = conn.getDB( "test" );
+db.foo.save( {a:1} );
+assert( ! s.admin.runCommand( { addshard: "localhost:29000" } ).ok, "accepted non-empty shard" );
+
+stopMongod( 29000 );
+s.stop(); \ No newline at end of file
diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp
index af50422cba4..de47fd4a51b 100644
--- a/s/commands_admin.cpp
+++ b/s/commands_admin.cpp
@@ -620,6 +620,7 @@ namespace mongo {
if ( shardAddr.isLocalHost() != grid.allowLocalHost() ){
errmsg = "can't use localhost as a shard since all shards need to communicate. "
"either use all shards and configdbs in localhost or all in actual IPs " ;
+ log() << "addshard request " << cmdObj << " failed: attempt to mix localhosts and IPs" << endl;
return false;
}
@@ -639,7 +640,7 @@ namespace mongo {
}
if ( ! grid.addShard( &name , shardAddr.toString() , maxSize , &errmsg ) ){
- // addShard filled errmsg
+ log() << "addshard request " << cmdObj << " failed: " << errmsg << endl;
return false;
}
diff --git a/s/grid.cpp b/s/grid.cpp
index e1e6c4b40a5..c3d8e3ad7a0 100644
--- a/s/grid.cpp
+++ b/s/grid.cpp
@@ -21,6 +21,7 @@
#include <iomanip>
#include "../client/connpool.h"
+#include "../util/stringutils.h"
#include "grid.h"
#include "shard.h"
@@ -118,6 +119,40 @@ namespace mongo {
try {
ScopedDbConnection newShardConn( host );
newShardConn->getLastError();
+
+ // get the shard's local db's listing
+ BSONObj res;
+ bool ok = newShardConn->runCommand( "admin" , BSON( "listDatabases" << 1 ) , res );
+ if ( !ok ){
+ ostringstream ss;
+ ss << "failed listing " << host << " databases:" << res;
+ *errMsg = ss.str();
+ newShardConn.done();
+ return false;
+ }
+
+ vector<string> dbNames;
+ BSONObjIterator i( res["databases"].Obj() );
+ while ( i.more() ){
+ BSONObj dbEntry = i.next().Obj();
+ const string& dbName = dbEntry["name"].String();
+ if ( ! _isSpecialLocalDB( dbName ) ){
+ dbNames.push_back( dbName );
+ }
+ }
+
+ // TODO (within SERVER-1292) If the databases aren't duplicate, add them to the grid
+ if ( ! dbNames.empty() ){
+ string dbConcat;
+ joinStringDelim( dbNames, &dbConcat , ',' );
+ ostringstream ss;
+ ss << "cannot add shard " << host << " that has local databases: " << dbConcat;
+ *errMsg = ss.str();
+
+ newShardConn.done();
+ return false;
+ }
+
newShardConn.done();
}
catch ( DBException& e ){
@@ -134,7 +169,7 @@ namespace mongo {
return false;
}
- // build the ConfigDB shard document.
+ // build the ConfigDB shard document
BSONObjBuilder b;
b.append( "_id" , *name );
b.append( "host" , host );
@@ -146,7 +181,7 @@ namespace mongo {
{
ScopedDbConnection conn( configServer.getPrimary() );
- // check whether this host:port is already a known shard
+ // check whether this host:port is not an already a known shard
BSONObj old = conn->findOne( ShardNS::shard , BSON( "host" << host ) );
if ( ! old.isEmpty() ){
*errMsg = "host already used";
@@ -160,6 +195,7 @@ namespace mongo {
*errMsg = conn->getLastError();
if ( ! errMsg->empty() ){
log() << "error adding shard: " << shardDoc << " err: " << *errMsg << endl;
+ conn.done();
return false;
}
@@ -221,6 +257,10 @@ namespace mongo {
return result["optime"]._numberLong();
}
+ bool Grid::_isSpecialLocalDB( const string& dbName ){
+ return ( dbName == "local" ) || ( dbName == "admin" ) || ( dbName == "config" );
+ }
+
Grid grid;
}
diff --git a/s/grid.h b/s/grid.h
index c255c45bae7..ffd6d4ac2a1 100644
--- a/s/grid.h
+++ b/s/grid.h
@@ -94,6 +94,11 @@ namespace mongo {
*/
bool _getNewShardName( string* name ) const;
+ /**
+ * @return whether a give dbname is used for shard "local" databases (e.g., admin or local)
+ */
+ static bool _isSpecialLocalDB( const string& dbName );
+
};
extern Grid grid;