diff options
Diffstat (limited to 'manager.cpp')
-rw-r--r-- | manager.cpp | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/manager.cpp b/manager.cpp index 684f20c..286b81a 100644 --- a/manager.cpp +++ b/manager.cpp @@ -17,6 +17,7 @@ #include "manager.hpp" #include <algorithm> +#include <iostream> #include <memory> #include <string> #include <vector> @@ -67,6 +68,52 @@ int BlobManager::getOpen(const std::string& path) const return 0; } +void BlobManager::eraseSession(GenericBlobInterface* handler, uint16_t session) +{ + sessions.erase(session); + /* Ok for openSessions[handler] to be an empty set */ + openSessions[handler].erase(session); + decrementOpen(getPath(session)); +} + +void BlobManager::cleanUpStaleSessions(GenericBlobInterface* handler) +{ + if (openSessions.count(handler) == 0) + { + return; + } + + auto timeNow = std::chrono::steady_clock::now(); + std::set<uint16_t> expiredSet; + + for (auto sessionId : openSessions[handler]) + { + if (timeNow - sessions[sessionId].lastActionTime >= sessionTimeout) + { + expiredSet.insert(sessionId); + } + } + + for (auto sessionId : expiredSet) + { + std::cerr << "phosphor-ipmi-blobs: expiring stale session " << sessionId + << std::endl; + + /* We do a best case recovery by issuing an expire call. If it fails + * don't erase sessions since the handler side might be still tracking + * it as open. */ + if (handler->expire(sessionId)) + { + eraseSession(handler, sessionId); + } + else + { + std::cerr << "phosphor-ipmi-blobs: failed to expire session " + << sessionId << std::endl; + } + } +} + bool BlobManager::registerHandler(std::unique_ptr<GenericBlobInterface> handler) { if (!handler) @@ -130,6 +177,10 @@ bool BlobManager::open(uint16_t flags, const std::string& path, return false; } + /* Try to clean up anything that's falling out of cleanup timeout for this + * handler */ + cleanUpStaleSessions(handler); + if (!handler->open(*session, flags, path)) { return false; @@ -137,6 +188,7 @@ bool BlobManager::open(uint16_t flags, const std::string& path, /* Associate session with handler */ sessions[*session] = SessionInfo(path, handler, flags); + openSessions[handler].insert(*session); incrementOpen(path); return true; } @@ -206,8 +258,7 @@ bool BlobManager::close(uint16_t session) { return false; } - sessions.erase(session); - decrementOpen(getPath(session)); + eraseSession(handler, session); return true; } return false; |