diff --git a/src/mongo/s/d_state.cpp b/src/mongo/s/d_state.cpp index 4570886648a..eb3dca62040 100644 --- a/src/mongo/s/d_state.cpp +++ b/src/mongo/s/d_state.cpp @@ -82,16 +82,9 @@ namespace mongo { _configServerTickets( 3 /* max number of concurrent config server refresh threads */ ) { } - void ShardingState::enable( const string& server ) { + bool ShardingState::enabled() { boost::lock_guard lk(_mutex); - - _enabled = true; - verify( server.size() ); - if ( _configServer.size() == 0 ) - _configServer = server; - else { - verify( server == _configServer ); - } + return _enabled; } void ShardingState::initialize(const string& server) { @@ -99,14 +92,7 @@ namespace mongo { "Unable to obtain host name during sharding initialization.", !getHostName().empty()); - ShardedConnectionInfo::addHook(); - shardingState.enable(server); - - vector configdbs; - splitStringDelim(server, &configdbs, ','); - - configServer.init(configdbs); - grid.initCatalogManager(configdbs); + shardingState._initialize(server); } // TODO: Consolidate and eliminate these various ways of setting / validating shard names @@ -191,7 +177,7 @@ namespace mongo { return true; } - const ChunkVersion ShardingState::getVersion( const string& ns ) const { + ChunkVersion ShardingState::getVersion(const string& ns) { boost::lock_guard lk(_mutex); CollectionMetadataMap::const_iterator it = _collMetadata.find( ns ); @@ -470,6 +456,28 @@ namespace mongo { return doRefreshMetadata(txn, ns, ChunkVersion(0, 0, OID()), false, latestShardVersion); } + void ShardingState::_initialize(const string& server) { + // Ensure only one caller at a time initializes + boost::lock_guard lk(_mutex); + + if (_enabled) { + return; + } + + ShardedConnectionInfo::addHook(); + + invariant(_configServer.empty()); + _configServer = server; + + vector configdbs; + splitStringDelim(server, &configdbs, ','); + + configServer.init(configdbs); + grid.initCatalogManager(configdbs); + + _enabled = true; + } + Status ShardingState::doRefreshMetadata( OperationContext* txn, const string& ns, const ChunkVersion& reqShardVersion, diff --git a/src/mongo/s/d_state.h b/src/mongo/s/d_state.h index 34368b0c143..3f528789a7f 100644 --- a/src/mongo/s/d_state.h +++ b/src/mongo/s/d_state.h @@ -49,9 +49,8 @@ namespace mongo { public: ShardingState(); - bool enabled() const { return _enabled; } + bool enabled(); const std::string& getConfigServer() const { return _configServer; } - void enable( const std::string& server ); // Initialize sharding state and begin authenticating outgoing connections and handling // shard versions. If this is not run before sharded operations occur auth will not work @@ -75,7 +74,7 @@ namespace mongo { bool hasVersion( const std::string& ns ); bool hasVersion( const std::string& ns , ChunkVersion& version ); - const ChunkVersion getVersion( const std::string& ns ) const; + ChunkVersion getVersion(const std::string& ns); /** * If the metadata for 'ns' at this shard is at or above the requested version, @@ -265,6 +264,8 @@ namespace mongo { private: + void _initialize(const std::string& server); + /** * Refreshes collection metadata by asking the config server for the latest information. * May or may not be based on a requested version. @@ -275,14 +276,16 @@ namespace mongo { bool useRequestedVersion, ChunkVersion* latestShardVersion ); - bool _enabled; - std::string _configServer; std::string _shardName; // protects state below - mutable mongo::mutex _mutex; + mongo::mutex _mutex; + + // Whether ::initialize has been called + bool _enabled; + // protects accessing the config server // Using a ticket holder so we can have multiple redundant tries at any given time mutable TicketHolder _configServerTickets;