summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorGreg Studer <greg@10gen.com>2012-06-11 09:56:07 -0400
committerGreg Studer <greg@10gen.com>2012-06-11 12:10:05 -0400
commit936c03f4adab997257057458a9cb730753712d8a (patch)
tree71b3ea127c952a6887c0b510e67d58ee638798a2 /src/mongo
parentfd5eb17c32cbbf4a639ed930a658609f3b8a2211 (diff)
downloadmongo-936c03f4adab997257057458a9cb730753712d8a.tar.gz
SERVER-5920 protect reload of database config, ensure we don't get partial dbconfig objs
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/s/grid.cpp125
1 files changed, 74 insertions, 51 deletions
diff --git a/src/mongo/s/grid.cpp b/src/mongo/s/grid.cpp
index 05f3e8d519f..01d744296b0 100644
--- a/src/mongo/s/grid.cpp
+++ b/src/mongo/s/grid.cpp
@@ -41,73 +41,96 @@ namespace mongo {
if ( database == "config" )
return configServerPtr;
- uassert( 15918 , str::stream() << "invalid database name: " << database , NamespaceString::validDBName( database ) );
+ uassert( 15918,
+ str::stream() << "invalid database name: " << database,
+ NamespaceString::validDBName( database ) );
scoped_lock l( _lock );
- DBConfigPtr& cc = _databases[database];
- if ( !cc ) {
- cc.reset(new DBConfig( database ));
- if ( ! cc->load() ) {
- if ( create ) {
- // note here that cc->primary == 0.
- log() << "couldn't find database [" << database << "] in config db" << endl;
-
- {
- // lets check case
- scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getScopedDbConnection(
- configServer.modelServer() ));
- BSONObjBuilder b;
- b.appendRegex( "_id" , (string)"^" +
- pcrecpp::RE::QuoteMeta( database ) + "$" , "i" );
- BSONObj d = conn->get()->findOne( ShardNS::database , b.obj() );
- conn->done();
-
- if ( ! d.isEmpty() ) {
- cc.reset();
- stringstream ss;
- ss << "can't have 2 databases that just differ on case "
- << " have: " << d["_id"].String()
- << " want to add: " << database;
-
- uasserted( DatabaseDifferCaseCode ,ss.str() );
+ DBConfigPtr& dbConfig = _databases[database];
+ if( ! dbConfig ){
+
+ dbConfig.reset(new DBConfig( database ));
+
+ // Protect initial load from connectivity errors
+ bool loaded = false;
+ try {
+ loaded = dbConfig->load();
+ }
+ catch( DBException& e ){
+ e.addContext( "error loading initial database config information" );
+ warning() << e.what() << endl;
+ dbConfig.reset();
+ throw;
+ }
+
+ if( ! loaded ){
+
+ if( create ){
+
+ // Protect creation of initial db doc from connectivity errors
+ try{
+
+ // note here that cc->primary == 0.
+ log() << "couldn't find database [" << database << "] in config db" << endl;
+
+ {
+ // lets check case
+ scoped_ptr<ScopedDbConnection> conn(
+ ScopedDbConnection::getScopedDbConnection( configServer.modelServer() ));
+
+ BSONObjBuilder b;
+ b.appendRegex( "_id" , (string)"^" +
+ pcrecpp::RE::QuoteMeta( database ) + "$" , "i" );
+ BSONObj d = conn->get()->findOne( ShardNS::database , b.obj() );
+ conn->done();
+
+ if ( ! d.isEmpty() ) {
+ uasserted( DatabaseDifferCaseCode, str::stream()
+ << "can't have 2 databases that just differ on case "
+ << " have: " << d["_id"].String()
+ << " want to add: " << database );
+ }
}
- }
- Shard primary;
- if ( database == "admin" ) {
- primary = configServer.getPrimary();
+ Shard primary;
+ if ( database == "admin" ) {
+ primary = configServer.getPrimary();
- }
- else if ( shardNameHint.empty() ) {
- primary = Shard::pick();
+ }
+ else if ( shardNameHint.empty() ) {
+ primary = Shard::pick();
- }
- else {
- // use the shard name if provided
- Shard shard;
- shard.reset( shardNameHint );
- primary = shard;
- }
+ }
+ else {
+ // use the shard name if provided
+ Shard shard;
+ shard.reset( shardNameHint );
+ primary = shard;
+ }
- if ( primary.ok() ) {
- cc->setPrimary( primary.getName() ); // saves 'cc' to configDB
- log() << "\t put [" << database << "] on: " << primary << endl;
+ if ( primary.ok() ) {
+ dbConfig->setPrimary( primary.getName() ); // saves 'cc' to configDB
+ log() << "\t put [" << database << "] on: " << primary << endl;
+ }
+ else {
+ uasserted( 10185 , "can't find a shard to put new db on" );
+ }
}
- else {
- cc.reset();
- log() << "\t can't find a shard to put new db on" << endl;
- uasserted( 10185 , "can't find a shard to put new db on" );
+ catch( DBException& e ){
+ e.addContext( "error creating initial database config information" );
+ warning() << e.what() << endl;
+ dbConfig.reset();
+ throw;
}
}
else {
- cc.reset();
+ dbConfig.reset();
}
}
-
}
- return cc;
+ return dbConfig;
}
void Grid::removeDB( string database ) {