diff options
Diffstat (limited to 'extensions/openpower-pels/manager.cpp')
-rw-r--r-- | extensions/openpower-pels/manager.cpp | 157 |
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() == ' ') { |