From 5ee0b3805e9116bf0f4655d5ee5cd5b108e7a7e4 Mon Sep 17 00:00:00 2001 From: David Storch Date: Wed, 30 Jan 2019 14:23:54 -0500 Subject: SERVER-39065 Delete withCursorManager() and visitAllCursorManagers(). --- src/mongo/db/commands/killcursors_cmd.cpp | 12 +-- src/mongo/db/cursor_manager.cpp | 115 +++++---------------- src/mongo/db/cursor_manager.h | 52 +++------- src/mongo/db/kill_sessions_common.h | 27 +++-- src/mongo/db/kill_sessions_local.cpp | 3 +- .../db/pipeline/process_interface_standalone.cpp | 2 +- src/mongo/db/service_liaison_mongod.cpp | 15 +-- src/mongo/s/query/cluster_cursor_manager.cpp | 7 +- 8 files changed, 66 insertions(+), 167 deletions(-) diff --git a/src/mongo/db/commands/killcursors_cmd.cpp b/src/mongo/db/commands/killcursors_cmd.cpp index 74d61b1ebdc..6efecd22edc 100644 --- a/src/mongo/db/commands/killcursors_cmd.cpp +++ b/src/mongo/db/commands/killcursors_cmd.cpp @@ -67,11 +67,7 @@ public: private: Status _checkAuth(Client* client, const NamespaceString& nss, CursorId id) const final { auto opCtx = client->getOperationContext(); - const auto check = [opCtx, id](CursorManager* manager) { - return manager->checkAuthForKillCursors(opCtx, id); - }; - - return CursorManager::withCursorManager(opCtx, id, nss, check); + return CursorManager::getGlobalCursorManager()->checkAuthForKillCursors(opCtx, id); } Status _killCursor(OperationContext* opCtx, @@ -87,10 +83,8 @@ private: dbProfilingLevel); } - return CursorManager::withCursorManager( - opCtx, id, nss, [opCtx, id](CursorManager* manager) { - return manager->killCursor(opCtx, id, true /* shouldAudit */); - }); + auto cursorManager = CursorManager::getGlobalCursorManager(); + return cursorManager->killCursor(opCtx, id, true /* shouldAudit */); } } killCursorsCmd; diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp index d8ed3a9e380..7b7fef06152 100644 --- a/src/mongo/db/cursor_manager.cpp +++ b/src/mongo/db/cursor_manager.cpp @@ -71,18 +71,6 @@ public: GlobalCursorIdCache(); ~GlobalCursorIdCache(); - /** - * Returns a unique 32-bit identifier to be used as the first 32 bits of all cursor ids for a - * new CursorManager. - */ - uint32_t registerCursorManager(const NamespaceString& nss); - - /** - * Must be called when a CursorManager is deleted. 'id' must be the identifier returned by - * registerCursorManager(). - */ - void deregisterCursorManager(uint32_t id, const NamespaceString& nss); - /** * works globally */ @@ -92,9 +80,6 @@ public: std::size_t timeoutCursors(OperationContext* opCtx, Date_t now); - template - void visitAllCursorManagers(OperationContext* opCtx, Visitor* visitor); - int64_t nextSeed(); private: @@ -137,34 +122,6 @@ int64_t GlobalCursorIdCache::nextSeed() { return _secureRandom->nextInt64(); } -uint32_t GlobalCursorIdCache::registerCursorManager(const NamespaceString& nss) { - static const uint32_t kMaxIds = 1000 * 1000 * 1000; - static_assert((kMaxIds & (0b11 << 30)) == 0, - "the first two bits of a collection identifier must always be zeroes"); - - stdx::lock_guard lk(_mutex); - - fassert(17359, _idToNss.size() < kMaxIds); - - for (uint32_t i = 0; i <= kMaxIds; i++) { - uint32_t id = ++_nextId; - if (id == 0) - continue; - if (_idToNss.count(id) > 0) - continue; - _idToNss[id] = nss; - return id; - } - - MONGO_UNREACHABLE; -} - -void GlobalCursorIdCache::deregisterCursorManager(uint32_t id, const NamespaceString& nss) { - stdx::lock_guard lk(_mutex); - invariant(nss == _idToNss[id]); - _idToNss.erase(id); -} - bool GlobalCursorIdCache::killCursor(OperationContext* opCtx, CursorId id, bool checkAuth) { // Figure out what the namespace of this cursor is. NamespaceString nss; @@ -191,18 +148,17 @@ bool GlobalCursorIdCache::killCursor(OperationContext* opCtx, CursorId id, bool // Check if we are authorized to kill this cursor. if (checkAuth) { - auto status = CursorManager::withCursorManager( - opCtx, id, nss, [nss, id, opCtx](CursorManager* manager) { - auto ccPin = manager->pinCursor(opCtx, id, CursorManager::kNoCheckSession); - if (!ccPin.isOK()) { - return ccPin.getStatus(); - } - AuthorizationSession* as = AuthorizationSession::get(opCtx->getClient()); - auto cursorOwner = ccPin.getValue().getCursor()->getAuthenticatedUsers(); - return as->checkAuthForKillCursors(nss, cursorOwner); - }); - if (!status.isOK()) { - audit::logKillCursorsAuthzCheck(opCtx->getClient(), nss, id, status.code()); + auto ccPin = globalCursorManager->pinCursor(opCtx, id, CursorManager::kNoCheckSession); + if (!ccPin.isOK()) { + audit::logKillCursorsAuthzCheck(opCtx->getClient(), nss, id, ccPin.getStatus().code()); + return false; + } + + AuthorizationSession* as = AuthorizationSession::get(opCtx->getClient()); + auto cursorOwner = ccPin.getValue().getCursor()->getAuthenticatedUsers(); + auto authStatus = as->checkAuthForKillCursors(nss, cursorOwner); + if (!authStatus.isOK()) { + audit::logKillCursorsAuthzCheck(opCtx->getClient(), nss, id, authStatus.code()); return false; } } @@ -220,42 +176,21 @@ std::size_t GlobalCursorIdCache::timeoutCursors(OperationContext* opCtx, Date_t } // namespace -template -void GlobalCursorIdCache::visitAllCursorManagers(OperationContext* opCtx, Visitor* visitor) { - (*visitor)(*globalCursorManager); -} - -// --- - CursorManager* CursorManager::getGlobalCursorManager() { return globalCursorManager.get(); } -void CursorManager::appendAllActiveSessions(OperationContext* opCtx, LogicalSessionIdSet* lsids) { - auto visitor = [&](CursorManager& mgr) { mgr.appendActiveSessions(lsids); }; - globalCursorIdCache->visitAllCursorManagers(opCtx, &visitor); -} - -std::vector CursorManager::getIdleCursors( - OperationContext* opCtx, MongoProcessInterface::CurrentOpUserMode userMode) { - std::vector cursors; - AuthorizationSession* ctxAuth = AuthorizationSession::get(opCtx->getClient()); - auto visitor = [&](CursorManager& mgr) { mgr.appendIdleCursors(ctxAuth, userMode, &cursors); }; - globalCursorIdCache->visitAllCursorManagers(opCtx, &visitor); - - return cursors; -} - std::pair CursorManager::killCursorsWithMatchingSessions( OperationContext* opCtx, const SessionKiller::Matcher& matcher) { auto eraser = [&](CursorManager& mgr, CursorId id) { uassertStatusOK(mgr.killCursor(opCtx, id, true)); }; - auto visitor = makeKillSessionsCursorManagerVisitor(opCtx, matcher, std::move(eraser)); - globalCursorIdCache->visitAllCursorManagers(opCtx, &visitor); + auto bySessionCursorKiller = makeKillCursorsBySessionAdaptor(opCtx, matcher, std::move(eraser)); + bySessionCursorKiller(*this); - return std::make_pair(visitor.getStatus(), visitor.getCursorsKilled()); + return std::make_pair(bySessionCursorKiller.getStatus(), + bySessionCursorKiller.getCursorsKilled()); } std::size_t CursorManager::timeoutCursorsGlobal(OperationContext* opCtx, Date_t now) { @@ -280,14 +215,6 @@ bool CursorManager::killCursorGlobal(OperationContext* opCtx, CursorId id) { return globalCursorIdCache->killCursor(opCtx, id, false); } -Status CursorManager::withCursorManager(OperationContext* opCtx, - CursorId id, - const NamespaceString& nss, - stdx::function callback) { - auto cursorManager = CursorManager::getGlobalCursorManager(); - return callback(cursorManager); -} - // -------------------------- CursorManager::CursorManager() @@ -426,9 +353,11 @@ void CursorManager::appendActiveSessions(LogicalSessionIdSet* lsids) const { } } -void CursorManager::appendIdleCursors(AuthorizationSession* ctxAuth, - MongoProcessInterface::CurrentOpUserMode userMode, - std::vector* cursors) const { +std::vector CursorManager::getIdleCursors( + OperationContext* opCtx, MongoProcessInterface::CurrentOpUserMode userMode) const { + std::vector cursors; + AuthorizationSession* ctxAuth = AuthorizationSession::get(opCtx->getClient()); + auto allPartitions = _cursorMap->lockAllPartitions(); for (auto&& partition : allPartitions) { for (auto&& entry : partition) { @@ -444,9 +373,11 @@ void CursorManager::appendIdleCursors(AuthorizationSession* ctxAuth, if (cursor->_operationUsingCursor) { continue; } - cursors->emplace_back(cursor->toGenericCursor()); + cursors.emplace_back(cursor->toGenericCursor()); } } + + return cursors; } stdx::unordered_set CursorManager::getCursorsForSession(LogicalSessionId lsid) const { diff --git a/src/mongo/db/cursor_manager.h b/src/mongo/db/cursor_manager.h index d9435da334d..2671d251ead 100644 --- a/src/mongo/db/cursor_manager.h +++ b/src/mongo/db/cursor_manager.h @@ -73,31 +73,6 @@ public: */ static CursorManager* getGlobalCursorManager(); - /** - * Appends the sessions that have open cursors on the global cursor manager and across - * all collection-level cursor managers to the given set of lsids. - */ - static void appendAllActiveSessions(OperationContext* opCtx, LogicalSessionIdSet* lsids); - - /** - * Returns a list of GenericCursors for all idle cursors on global cursor manager. Does not - * include currently pinned cursors. 'userMode': If auth is on, calling with userMode as - * kExcludeOthers will cause this function to only return cursors owned by the caller. If auth - * is off, this argument does not matter. - * - * TODO SERVER-37454: This method should become non-static now that there are no more - * per-collection cursor managers. - */ - static std::vector getIdleCursors( - OperationContext* opCtx, MongoProcessInterface::CurrentOpUserMode userMode); - - /** - * Kills cursors with matching logical sessions. Returns a pair with the overall Status of the - * operation and the number of cursors successfully killed. - */ - static std::pair killCursorsWithMatchingSessions( - OperationContext* opCtx, const SessionKiller::Matcher& matcher); - static int killCursorGlobalIfAuthorized(OperationContext* opCtx, int n, const char* ids); static bool killCursorGlobalIfAuthorized(OperationContext* opCtx, CursorId id); @@ -113,16 +88,6 @@ public: */ static std::size_t timeoutCursorsGlobal(OperationContext* opCtx, Date_t now); - /** - * This method is deprecated. Do not add new call sites. - * - * TODO SERVER-39065: Delete this method. - */ - static Status withCursorManager(OperationContext* opCtx, - CursorId id, - const NamespaceString& nss, - stdx::function callback); - CursorManager(); /** @@ -187,11 +152,13 @@ public: void appendActiveSessions(LogicalSessionIdSet* lsids) const; /** - * Appends all idle (non-pinned) cursors in this cursor manager to the output vector. + * Returns a vector of all idle (non-pinned) cursors in this cursor manager. + * + * If auth is on, calling with 'userMode' as 'kExcludeOthers' will cause this function to only + * return cursors owned by the caller. If auth is off, this argument does not matter. */ - void appendIdleCursors(AuthorizationSession* ctxAuth, - MongoProcessInterface::CurrentOpUserMode userMode, - std::vector* cursors) const; + std::vector getIdleCursors( + OperationContext* opCtx, MongoProcessInterface::CurrentOpUserMode userMode) const; /* * Returns a list of all open cursors for the given session. @@ -203,6 +170,13 @@ public: */ std::size_t numCursors() const; + /** + * Kills cursors in this cursor manager with matching logical sessions. Returns a pair with the + * overall Status of the operation and the number of cursors successfully killed. + */ + std::pair killCursorsWithMatchingSessions(OperationContext* opCtx, + const SessionKiller::Matcher& matcher); + private: static constexpr int kNumPartitions = 16; friend class ClientCursorPin; diff --git a/src/mongo/db/kill_sessions_common.h b/src/mongo/db/kill_sessions_common.h index 255ac6cde86..9ef2c64c55c 100644 --- a/src/mongo/db/kill_sessions_common.h +++ b/src/mongo/db/kill_sessions_common.h @@ -81,13 +81,17 @@ private: * two types share no code, but do share enough shape to re-use some boilerplate. */ template -class KillSessionsCursorManagerVisitor { +class KillCursorsBySessionAdaptor { public: - KillSessionsCursorManagerVisitor(OperationContext* opCtx, - const SessionKiller::Matcher& matcher, - Eraser&& eraser) + KillCursorsBySessionAdaptor(OperationContext* opCtx, + const SessionKiller::Matcher& matcher, + Eraser&& eraser) : _opCtx(opCtx), _matcher(matcher), _cursorsKilled(0), _eraser(eraser) {} + /** + * Kills cursors in 'mgr' which belong to a session matching the SessionKilled::Matcher with + * which this adaptor was constructed. + */ template void operator()(Mgr& mgr) { LogicalSessionIdSet activeSessions; @@ -110,6 +114,10 @@ public: } } + /** + * Returns an OK status if no errors were encountered during cursor killing, or a non-OK status + * summarizing any errors encountered. + */ Status getStatus() const { if (_failures.empty()) { return Status::OK(); @@ -126,6 +134,9 @@ public: << _failures.back().reason()); } + /** + * Returns the number of cursors killed by operator(). + */ int getCursorsKilled() const { return _cursorsKilled; } @@ -139,10 +150,10 @@ private: }; template -auto makeKillSessionsCursorManagerVisitor(OperationContext* opCtx, - const SessionKiller::Matcher& matcher, - Eraser&& eraser) { - return KillSessionsCursorManagerVisitor>{ +auto makeKillCursorsBySessionAdaptor(OperationContext* opCtx, + const SessionKiller::Matcher& matcher, + Eraser&& eraser) { + return KillCursorsBySessionAdaptor>{ opCtx, matcher, std::forward(eraser)}; } diff --git a/src/mongo/db/kill_sessions_local.cpp b/src/mongo/db/kill_sessions_local.cpp index ed16522171d..d244143ed4e 100644 --- a/src/mongo/db/kill_sessions_local.cpp +++ b/src/mongo/db/kill_sessions_local.cpp @@ -105,7 +105,8 @@ SessionKiller::Result killSessionsLocal(OperationContext* opCtx, killSessionsAbortUnpreparedTransactions(opCtx, matcher); uassertStatusOK(killSessionsLocalKillOps(opCtx, matcher)); - auto res = CursorManager::killCursorsWithMatchingSessions(opCtx, matcher); + auto res = + CursorManager::getGlobalCursorManager()->killCursorsWithMatchingSessions(opCtx, matcher); uassertStatusOK(res.first); return {std::vector{}}; diff --git a/src/mongo/db/pipeline/process_interface_standalone.cpp b/src/mongo/db/pipeline/process_interface_standalone.cpp index e9de70428dc..1cd3d461ab4 100644 --- a/src/mongo/db/pipeline/process_interface_standalone.cpp +++ b/src/mongo/db/pipeline/process_interface_standalone.cpp @@ -383,7 +383,7 @@ std::vector MongoInterfaceStandalone::collectDocumentKeyFieldsActingA std::vector MongoInterfaceStandalone::getIdleCursors( const intrusive_ptr& expCtx, CurrentOpUserMode userMode) const { - return CursorManager::getIdleCursors(expCtx->opCtx, userMode); + return CursorManager::getGlobalCursorManager()->getIdleCursors(expCtx->opCtx, userMode); } boost::optional MongoInterfaceStandalone::lookupSingleDocument( diff --git a/src/mongo/db/service_liaison_mongod.cpp b/src/mongo/db/service_liaison_mongod.cpp index af214b60227..364ed83438c 100644 --- a/src/mongo/db/service_liaison_mongod.cpp +++ b/src/mongo/db/service_liaison_mongod.cpp @@ -68,20 +68,7 @@ LogicalSessionIdSet ServiceLiaisonMongod::getActiveOpSessions() const { LogicalSessionIdSet ServiceLiaisonMongod::getOpenCursorSessions() const { LogicalSessionIdSet cursorSessions; - // Append any in-use session ids from the global and collection-level cursor managers - boost::optional uniqueCtx; - auto client = Client::getCurrent(); - - auto* const opCtx = [&client, &uniqueCtx] { - if (client->getOperationContext()) { - return client->getOperationContext(); - } - - uniqueCtx.emplace(client->makeOperationContext()); - return uniqueCtx->get(); - }(); - - CursorManager::appendAllActiveSessions(opCtx, &cursorSessions); + CursorManager::getGlobalCursorManager()->appendActiveSessions(&cursorSessions); return cursorSessions; } diff --git a/src/mongo/s/query/cluster_cursor_manager.cpp b/src/mongo/s/query/cluster_cursor_manager.cpp index 860327f6216..98cbb05f2b5 100644 --- a/src/mongo/s/query/cluster_cursor_manager.cpp +++ b/src/mongo/s/query/cluster_cursor_manager.cpp @@ -673,9 +673,10 @@ std::pair ClusterCursorManager::killCursorsWithMatchingSessions( uassertStatusOK(mgr.killCursor(opCtx, getNamespaceForCursorId(id).get(), id)); }; - auto visitor = makeKillSessionsCursorManagerVisitor(opCtx, matcher, std::move(eraser)); - visitor(*this); - return std::make_pair(visitor.getStatus(), visitor.getCursorsKilled()); + auto bySessionCursorKiller = makeKillCursorsBySessionAdaptor(opCtx, matcher, std::move(eraser)); + bySessionCursorKiller(*this); + return std::make_pair(bySessionCursorKiller.getStatus(), + bySessionCursorKiller.getCursorsKilled()); } stdx::unordered_set ClusterCursorManager::getCursorsForSession( -- cgit v1.2.1