sel-cache: Use the cache for delete and get info
Use the cached SEL data for other handlers and remove the previous
cache::paths.
Tested: Verify ipmi sel list/get/del/clear commands work fine.
Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I0fc14d76eb567fb52b71a58876f006a5acf5104e
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 0f2fc2f..292842d 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -50,22 +50,6 @@
constexpr auto logDeleteIntf = "xyz.openbmc_project.Object.Delete";
} // namespace
-namespace cache
-{
-/*
- * This cache contains the object paths of the logging entries sorted in the
- * order of the filename(numeric order). The cache is initialized by
- * invoking readLoggingObjectPaths with the cache as the parameter. The
- * cache is invoked in the execution of the Get SEL info and Delete SEL
- * entry command. The Get SEL Info command is typically invoked before the
- * Get SEL entry command, so the cache is utilized for responding to Get SEL
- * entry command. The cache is invalidated by clearing after Delete SEL
- * entry and Clear SEL command.
- */
-ipmi::sel::ObjectPaths paths;
-
-} // namespace cache
-
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
using namespace phosphor::logging;
@@ -91,6 +75,11 @@
return std::stoul(entryPath.filename().string());
}
+static inline std::string getLoggingObjPath(uint16_t id)
+{
+ return std::string(ipmi::sel::logBasePath) + "/" + std::to_string(id);
+}
+
std::pair<uint16_t, SELEntry> parseLoggingEntry(const std::string& p)
{
auto id = getLoggingId(p);
@@ -175,16 +164,17 @@
void initSELCache()
{
+ ipmi::sel::ObjectPaths paths;
try
{
- ipmi::sel::readLoggingObjectPaths(cache::paths);
+ ipmi::sel::readLoggingObjectPaths(paths);
}
catch (const sdbusplus::exception::exception& e)
{
log<level::ERR>("Failed to get logging object paths");
return;
}
- for (const auto& p : cache::paths)
+ for (const auto& p : paths)
{
selCacheMap.insert(parseLoggingEntry(p));
}
@@ -230,26 +220,20 @@
// Most recent addition timestamp.
uint32_t addTimeStamp = ipmi::sel::invalidTimeStamp;
- try
+ if (!selCacheMapInitialized)
{
- ipmi::sel::readLoggingObjectPaths(cache::paths);
+ // In case the initSELCache() fails, try it again
+ initSELCache();
}
- catch (const sdbusplus::exception::exception& e)
+ if (!selCacheMap.empty())
{
- // No action if reading log objects have failed for this command.
- // readLoggingObjectPaths will throw exception if there are no log
- // entries. The command will be responded with number of SEL entries
- // as 0.
- }
-
- if (!cache::paths.empty())
- {
- entries = static_cast<uint16_t>(cache::paths.size());
+ entries = static_cast<uint16_t>(selCacheMap.size());
try
{
+ auto objPath = getLoggingObjPath(selCacheMap.rbegin()->first);
addTimeStamp = static_cast<uint32_t>(
- (ipmi::sel::getEntryTimeStamp(cache::paths.back()).count()));
+ (ipmi::sel::getEntryTimeStamp(objPath).count()));
}
catch (const InternalFailure& e)
{
@@ -404,46 +388,32 @@
// deleted
cancelSELReservation();
- try
+ if (!selCacheMapInitialized)
{
- ipmi::sel::readLoggingObjectPaths(cache::paths);
- }
- catch (const sdbusplus::exception::exception& e)
- {
- // readLoggingObjectPaths will throw exception if there are no error
- // log entries.
- return ipmi::responseSensorInvalid();
+ // In case the initSELCache() fails, try it again
+ initSELCache();
}
- if (cache::paths.empty())
+ if (selCacheMap.empty())
{
return ipmi::responseSensorInvalid();
}
- ipmi::sel::ObjectPaths::const_iterator iter;
+ SELCacheMap::const_iterator iter;
uint16_t delRecordID = 0;
if (selRecordID == ipmi::sel::firstEntry)
{
- iter = cache::paths.begin();
- fs::path path(*iter);
- delRecordID = static_cast<uint16_t>(
- std::stoul(std::string(path.filename().c_str())));
+ delRecordID = selCacheMap.begin()->first;
}
else if (selRecordID == ipmi::sel::lastEntry)
{
- iter = cache::paths.end();
- fs::path path(*iter);
- delRecordID = static_cast<uint16_t>(
- std::stoul(std::string(path.filename().c_str())));
+ delRecordID = selCacheMap.rbegin()->first;
}
else
{
- std::string objPath = std::string(ipmi::sel::logBasePath) + "/" +
- std::to_string(selRecordID);
-
- iter = std::find(cache::paths.begin(), cache::paths.end(), objPath);
- if (iter == cache::paths.end())
+ iter = selCacheMap.find(selRecordID);
+ if (iter == selCacheMap.end())
{
return ipmi::responseSensorInvalid();
}
@@ -453,9 +423,10 @@
sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
std::string service;
+ auto objPath = getLoggingObjPath(iter->first);
try
{
- service = ipmi::getService(bus, ipmi::sel::logDeleteIntf, *iter);
+ service = ipmi::getService(bus, ipmi::sel::logDeleteIntf, objPath);
}
catch (const std::runtime_error& e)
{
@@ -463,7 +434,7 @@
return ipmi::responseUnspecifiedError();
}
- auto methodCall = bus.new_method_call(service.c_str(), (*iter).c_str(),
+ auto methodCall = bus.new_method_call(service.c_str(), objPath.c_str(),
ipmi::sel::logDeleteIntf, "Delete");
auto reply = bus.call(methodCall);
if (reply.is_method_error())
@@ -471,9 +442,6 @@
return ipmi::responseUnspecifiedError();
}
- // Invalidate the cache of dbus entry objects.
- cache::paths.clear();
-
return ipmi::responseSuccess(delRecordID);
}
@@ -574,8 +542,6 @@
}
}
- // Invalidate the cache of dbus entry objects.
- cache::paths.clear();
return ipmi::responseSuccess(
static_cast<uint8_t>(ipmi::sel::eraseComplete));
}