summaryrefslogtreecommitdiffstats
path: root/extensions/openpower-pels/manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/openpower-pels/manager.cpp')
-rw-r--r--extensions/openpower-pels/manager.cpp157
1 files changed, 112 insertions, 45 deletions
diff --git a/extensions/openpower-pels/manager.cpp b/extensions/openpower-pels/manager.cpp
index 05ccb42..4eb6772 100644
--- a/extensions/openpower-pels/manager.cpp
+++ b/extensions/openpower-pels/manager.cpp
@@ -39,7 +39,8 @@ namespace common_error = sdbusplus::xyz::openbmc_project::Common::Error;
namespace additional_data
{
constexpr auto rawPEL = "RAWPEL";
-}
+constexpr auto esel = "ESEL";
+} // namespace additional_data
void Manager::create(const std::string& message, uint32_t obmcLogID,
uint64_t timestamp, Entry::Level severity,
@@ -48,7 +49,8 @@ void Manager::create(const std::string& message, uint32_t obmcLogID,
{
AdditionalData ad{additionalData};
- // If a PEL was passed in, use that. Otherwise, create one.
+ // If a PEL was passed in via a filename or in an ESEL,
+ // use that. Otherwise, create one.
auto rawPelPath = ad.getValue(additional_data::rawPEL);
if (rawPelPath)
{
@@ -56,8 +58,16 @@ void Manager::create(const std::string& message, uint32_t obmcLogID,
}
else
{
- createPEL(message, obmcLogID, timestamp, severity, additionalData,
- associations);
+ auto esel = ad.getValue(additional_data::esel);
+ if (esel)
+ {
+ addESELPEL(*esel, obmcLogID);
+ }
+ else
+ {
+ createPEL(message, obmcLogID, timestamp, severity, additionalData,
+ associations);
+ }
}
}
@@ -80,55 +90,113 @@ void Manager::addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID)
file.close();
- auto pel = std::make_unique<openpower::pels::PEL>(data, obmcLogID);
- if (pel->valid())
- {
- // PELs created by others still need these fields set by us.
- pel->assignID();
- pel->setCommitTime();
+ addPEL(data, obmcLogID);
+ }
+ else
+ {
+ log<level::ERR>("Raw PEL file from BMC event log does not exist",
+ entry("PELFILE=%s", (rawPelPath).c_str()),
+ entry("OBMCLOGID=%d", obmcLogID));
+ }
+}
- try
- {
- _repo.add(pel);
- }
- catch (std::exception& e)
- {
- // Probably a full or r/o filesystem, not much we can do.
- log<level::ERR>("Unable to add PEL to Repository",
- entry("PEL_ID=0x%X", pel->id()));
- }
+void Manager::addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID)
+{
+
+ auto pel = std::make_unique<openpower::pels::PEL>(pelData, obmcLogID);
+ if (pel->valid())
+ {
+ // PELs created by others still need these fields set by us.
+ pel->assignID();
+ pel->setCommitTime();
+
+ try
+ {
+ _repo.add(pel);
}
- else
+ catch (std::exception& e)
{
- log<level::ERR>("Invalid PEL received from the host",
- entry("PELFILE=%s", rawPelPath.c_str()),
- entry("OBMCLOGID=%d", obmcLogID));
+ // Probably a full or r/o filesystem, not much we can do.
+ log<level::ERR>("Unable to add PEL to Repository",
+ entry("PEL_ID=0x%X", pel->id()));
+ }
+ }
+ else
+ {
+ log<level::ERR>("Invalid PEL received from the host",
+ entry("OBMCLOGID=%d", obmcLogID));
- AdditionalData ad;
- ad.add("PLID", getNumberString("0x%08X", pel->plid()));
- ad.add("OBMC_LOG_ID", std::to_string(obmcLogID));
- ad.add("RAW_PEL_FILENAME", rawPelPath);
- ad.add("PEL_SIZE", std::to_string(data.size()));
+ AdditionalData ad;
+ ad.add("PLID", getNumberString("0x%08X", pel->plid()));
+ ad.add("OBMC_LOG_ID", std::to_string(obmcLogID));
+ ad.add("PEL_SIZE", std::to_string(pelData.size()));
- std::string asciiString;
- auto src = pel->primarySRC();
- if (src)
- {
- asciiString = (*src)->asciiString();
- }
+ std::string asciiString;
+ auto src = pel->primarySRC();
+ if (src)
+ {
+ asciiString = (*src)->asciiString();
+ }
- ad.add("SRC", asciiString);
+ ad.add("SRC", asciiString);
- _eventLogger.log("org.open_power.Logging.Error.BadHostPEL",
- Entry::Level::Error, ad);
- }
+ _eventLogger.log("org.open_power.Logging.Error.BadHostPEL",
+ Entry::Level::Error, ad);
}
- else
+}
+
+void Manager::addESELPEL(const std::string& esel, uint32_t obmcLogID)
+{
+ std::vector<uint8_t> data;
+
+ try
{
- log<level::ERR>("Raw PEL file from BMC event log does not exist",
- entry("PELFILE=%s", (rawPelPath).c_str()),
- entry("OBMCLOGID=%d", obmcLogID));
+ data = std::move(eselToRawData(esel));
+ }
+ catch (std::exception& e)
+ {
+ // Try to add it below anyway, so it follows the usual bad data path.
+ log<level::ERR>("Problems converting ESEL string to a byte vector");
+ }
+
+ addPEL(data, obmcLogID);
+}
+
+std::vector<uint8_t> Manager::eselToRawData(const std::string& esel)
+{
+ std::vector<uint8_t> data;
+ std::string byteString;
+
+ // As the eSEL string looks like: "50 48 00 ab ..." there are 3
+ // characters per raw byte, and since the actual PEL data starts
+ // at the 16th byte, the code will grab the PEL data starting at
+ // offset 48 in the string.
+ static constexpr size_t pelStart = 16 * 3;
+
+ if (esel.size() <= pelStart)
+ {
+ log<level::ERR>("ESEL data too short",
+ entry("ESEL_SIZE=%d", esel.size()));
+
+ throw std::length_error("ESEL data too short");
}
+
+ for (size_t i = pelStart; i < esel.size(); i += 3)
+ {
+ if (i + 1 < esel.size())
+ {
+ byteString = esel.substr(i, 2);
+ data.push_back(std::stoi(byteString, nullptr, 16));
+ }
+ else
+ {
+ log<level::ERR>("ESEL data too short",
+ entry("ESEL_SIZE=%d", esel.size()));
+ throw std::length_error("ESEL data too short");
+ }
+ }
+
+ return data;
}
void Manager::erase(uint32_t obmcLogID)
@@ -165,8 +233,7 @@ void Manager::createPEL(const std::string& message, uint32_t obmcLogID,
if (src)
{
using namespace std::literals::string_literals;
- char id[11];
- sprintf(id, "0x%08X", pel->id());
+ auto id = getNumberString("0x%08X", pel->id());
msg = "Created PEL "s + id + " with SRC "s + (*src)->asciiString();
while (msg.back() == ' ')
{
OpenPOWER on IntegriCloud