sel-cache: Handle exception invalid entry ID
When the Logging service restarts, the match will get callbacks for all
objects, including /xyz/openbmc_project/logging/internal/manager which
is not a valid logging entry, and the stoul will throw.
Handle the exception properly so that ipmid does not crash on this
exception.
Tested: Manually restart xyz.openbmc_project.Logging.service and verify
ipmid does not crash, and `ipmitool sel list` works fine.
Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I12b665b6bcdbef4e6176ad2a7e376126fdce5939
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 292842d..9608dcc 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -17,6 +17,7 @@
#include <filesystem>
#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
+#include <optional>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/server.hpp>
@@ -80,20 +81,22 @@
return std::string(ipmi::sel::logBasePath) + "/" + std::to_string(id);
}
-std::pair<uint16_t, SELEntry> parseLoggingEntry(const std::string& p)
+std::optional<std::pair<uint16_t, SELEntry>>
+ parseLoggingEntry(const std::string& p)
{
- auto id = getLoggingId(p);
- ipmi::sel::GetSELEntryResponse record{};
try
{
+ auto id = getLoggingId(p);
+ ipmi::sel::GetSELEntryResponse record{};
record = ipmi::sel::convertLogEntrytoSEL(p);
+ return std::pair<uint16_t, SELEntry>({id, std::move(record.event)});
}
catch (const std::exception& e)
{
fprintf(stderr, "Failed to convert %s to SEL: %s\n", p.c_str(),
e.what());
}
- return {id, std::move(record.event)};
+ return std::nullopt;
}
static void selAddedCallback(sdbusplus::message::message& m)
@@ -109,7 +112,11 @@
return;
}
std::string p = objPath;
- selCacheMap.insert(parseLoggingEntry(p));
+ auto entry = parseLoggingEntry(p);
+ if (entry)
+ {
+ selCacheMap.insert(std::move(*entry));
+ }
}
static void selRemovedCallback(sdbusplus::message::message& m)
@@ -122,17 +129,26 @@
catch (const sdbusplus::exception::exception& e)
{
log<level::ERR>("Failed to read object path");
- return;
}
- std::string p = objPath;
- selCacheMap.erase(getLoggingId(p));
+ try
+ {
+ std::string p = objPath;
+ selCacheMap.erase(getLoggingId(p));
+ }
+ catch (const std::invalid_argument& e)
+ {
+ log<level::ERR>("Invalid logging entry ID");
+ }
}
static void selUpdatedCallback(sdbusplus::message::message& m)
{
std::string p = m.get_path();
auto entry = parseLoggingEntry(p);
- selCacheMap.insert_or_assign(entry.first, std::move(entry.second));
+ if (entry)
+ {
+ selCacheMap.insert_or_assign(entry->first, std::move(entry->second));
+ }
}
void registerSelCallbackHandler()
@@ -176,7 +192,11 @@
}
for (const auto& p : paths)
{
- selCacheMap.insert(parseLoggingEntry(p));
+ auto entry = parseLoggingEntry(p);
+ if (entry)
+ {
+ selCacheMap.insert(std::move(*entry));
+ }
}
registerSelCallbackHandler();
selCacheMapInitialized = true;