summaryrefslogtreecommitdiffstats
path: root/manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'manager.cpp')
-rw-r--r--manager.cpp55
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;
OpenPOWER on IntegriCloud