diff options
author | Blake Oler <blake.oler@mongodb.com> | 2018-04-20 11:59:06 -0400 |
---|---|---|
committer | Blake Oler <blake.oler@mongodb.com> | 2018-04-20 12:10:44 -0400 |
commit | 60cb34ea7351d25b0eb6bee947d21ada09cf438b (patch) | |
tree | b567e1415b8dd3e2b7270e96600adf3d66b84bef | |
parent | c6e3031ef797b9e3c65de9aaf9da812c49a97e5a (diff) | |
download | mongo-60cb34ea7351d25b0eb6bee947d21ada09cf438b.tar.gz |
SERVER-32677 Prevent sessions periodic refresh from prematurely accessing sharding internals
-rw-r--r-- | src/mongo/db/s/sharding_initialization_mongod.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/sessions_collection_config_server.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/sessions_collection_sharded.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/grid.cpp | 9 | ||||
-rw-r--r-- | src/mongo/s/grid.h | 14 | ||||
-rw-r--r-- | src/mongo/s/server.cpp | 2 |
6 files changed, 43 insertions, 1 deletions
diff --git a/src/mongo/db/s/sharding_initialization_mongod.cpp b/src/mongo/db/s/sharding_initialization_mongod.cpp index 8963f20de1a..325ace6d4a1 100644 --- a/src/mongo/db/s/sharding_initialization_mongod.cpp +++ b/src/mongo/db/s/sharding_initialization_mongod.cpp @@ -54,6 +54,7 @@ #include "mongo/s/client/shard_remote.h" #include "mongo/s/client/sharding_connection_hook.h" #include "mongo/s/config_server_catalog_cache_loader.h" +#include "mongo/s/grid.h" #include "mongo/s/sharding_initialization.h" #include "mongo/stdx/memory.h" #include "mongo/util/log.h" @@ -125,7 +126,7 @@ Status initializeGlobalShardingStateForMongod(OperationContext* opCtx, globalConnPool.addHook(new ShardingConnectionHook(false, makeEgressHooksList(service))); shardConnectionPool.addHook(new ShardingConnectionHook(true, makeEgressHooksList(service))); - return initializeGlobalShardingState( + Status initStatus = initializeGlobalShardingState( opCtx, configCS, distLockProcessId, @@ -135,6 +136,12 @@ Status initializeGlobalShardingStateForMongod(OperationContext* opCtx, // We only need one task executor here because sharding task executors aren't used for user // queries in mongod. 1); + + if (initStatus.isOK()) { + Grid::get(opCtx)->setShardingInitialized(); + } + + return initStatus; } } // namespace mongo diff --git a/src/mongo/db/sessions_collection_config_server.cpp b/src/mongo/db/sessions_collection_config_server.cpp index 179687e33d4..35fc8c5c837 100644 --- a/src/mongo/db/sessions_collection_config_server.cpp +++ b/src/mongo/db/sessions_collection_config_server.cpp @@ -91,6 +91,11 @@ Status SessionsCollectionConfigServer::_generateIndexesIfNeeded(OperationContext } Status SessionsCollectionConfigServer::setupSessionsCollection(OperationContext* opCtx) { + // If the sharding state is not yet initialized, fail. + if (!Grid::get(opCtx)->isShardingInitialized()) { + return {ErrorCodes::ShardingStateNotInitialized, "sharding state is not yet initialized"}; + } + stdx::lock_guard<stdx::mutex> lk(_mutex); { // Only try to set up this collection until we have done so successfully once. diff --git a/src/mongo/db/sessions_collection_sharded.cpp b/src/mongo/db/sessions_collection_sharded.cpp index a0142e2a2fd..8873f17be4b 100644 --- a/src/mongo/db/sessions_collection_sharded.cpp +++ b/src/mongo/db/sessions_collection_sharded.cpp @@ -56,6 +56,11 @@ BSONObj lsidQuery(const LogicalSessionId& lsid) { } // namespace Status SessionsCollectionSharded::_checkCacheForSessionsCollection(OperationContext* opCtx) { + // If the sharding state is not yet initialized, fail. + if (!Grid::get(opCtx)->isShardingInitialized()) { + return {ErrorCodes::ShardingStateNotInitialized, "sharding state is not yet initialized"}; + } + // If the collection doesn't exist, fail. Only the config servers generate it. auto res = Grid::get(opCtx)->catalogCache()->getShardedCollectionRoutingInfoWithRefresh( opCtx, NamespaceString(SessionsCollection::kSessionsFullNS.toString())); diff --git a/src/mongo/s/grid.cpp b/src/mongo/s/grid.cpp index e27d34f3891..6570ca0c751 100644 --- a/src/mongo/s/grid.cpp +++ b/src/mongo/s/grid.cpp @@ -85,6 +85,15 @@ void Grid::init(std::unique_ptr<ShardingCatalogClient> catalogClient, _shardRegistry->init(); } +bool Grid::isShardingInitialized() const { + return _shardingInitialized.load(); +} + +void Grid::setShardingInitialized() { + invariant(!_shardingInitialized.load()); + _shardingInitialized.store(true); +} + Grid::CustomConnectionPoolStatsFn Grid::getCustomConnectionPoolStatsFn() const { stdx::lock_guard<stdx::mutex> lk(_mutex); return _customConnectionPoolStatsFn; diff --git a/src/mongo/s/grid.h b/src/mongo/s/grid.h index ba47fa07c4e..443c9b81304 100644 --- a/src/mongo/s/grid.h +++ b/src/mongo/s/grid.h @@ -82,6 +82,18 @@ public: executor::NetworkInterface* network); /** + * Used to check if sharding is initialized for usage of global sharding services. Protected by + * an atomic access guard. + */ + bool isShardingInitialized() const; + + /** + * Used to indicate the sharding initialization process is complete. Should only be called once + * in the lifetime of a server. Protected by an atomic access guard. + */ + void setShardingInitialized(); + + /** * If the instance as which this sharding component is running (config/shard/mongos) uses * additional connection pools other than the default, this function will be present and can be * used to obtain statistics about them. Otherwise, the value will be unset. @@ -173,6 +185,8 @@ private: CustomConnectionPoolStatsFn _customConnectionPoolStatsFn; + AtomicBool _shardingInitialized{false}; + // Protects _configOpTime. mutable stdx::mutex _mutex; diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp index cedcf00ff64..b35b3ed28ab 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/server.cpp @@ -321,6 +321,8 @@ Status initializeSharding(OperationContext* opCtx) { return status; } + Grid::get(opCtx)->setShardingInitialized(); + return Status::OK(); } |