Commit a MaintenanceProcedure log entry on a 0xDE SEL record
In the case of a procedure callout, HB sends a eSEL of 0xDF type.
It is followed by a Add SEL record with OEM record type 0xDE
and byte 11 in the record indicate the procedure associated
with the eSEL.
Resolves openbmc/openbmc#2368
Change-Id: Ia57f423c9d533cd8968b613d7522b409a9820198
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/elog-errors.hpp b/elog-errors.hpp
index 02649f4..671d99f 100644
--- a/elog-errors.hpp
+++ b/elog-errors.hpp
@@ -128,6 +128,26 @@
namespace sdbusplus
{
+namespace org
+{
+namespace open_power
+{
+namespace Common
+{
+namespace Callout
+{
+namespace Error
+{
+ struct Procedure;
+} // namespace Error
+} // namespace Callout
+} // namespace Common
+} // namespace open_power
+} // namespace org
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
namespace xyz
{
namespace openbmc_project
@@ -431,6 +451,22 @@
} // namespace org
} // namespace sdbusplus
+namespace sdbusplus
+{
+namespace org
+{
+namespace open_power
+{
+namespace Host
+{
+namespace Error
+{
+ struct MaintenanceProcedure;
+} // namespace Error
+} // namespace Host
+} // namespace open_power
+} // namespace org
+} // namespace sdbusplus
namespace phosphor
{
@@ -695,6 +731,53 @@
}
+namespace org
+{
+namespace open_power
+{
+namespace Common
+{
+namespace Callout
+{
+namespace _Procedure
+{
+
+struct PROCEDURE
+{
+ static constexpr auto str = "PROCEDURE=%u";
+ static constexpr auto str_short = "PROCEDURE";
+ using type = std::tuple<std::decay_t<decltype(str)>,uint32_t>;
+ explicit constexpr PROCEDURE(uint32_t a) : _entry(entry(str, a)) {};
+ type _entry;
+};
+
+} // namespace _Procedure
+
+struct Procedure
+{
+ static constexpr auto L = level::ERR;
+ using PROCEDURE = _Procedure::PROCEDURE;
+ using metadata_types = std::tuple<PROCEDURE>;
+
+};
+
+} // namespace Callout
+} // namespace Common
+} // namespace open_power
+} // namespace org
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::org::open_power::Common::Callout::Error::Procedure>
+{
+ using type = org::open_power::Common::Callout::Procedure;
+};
+
+}
+
namespace xyz
{
namespace openbmc_project
@@ -1235,6 +1318,51 @@
}
+namespace org
+{
+namespace open_power
+{
+namespace Host
+{
+namespace _MaintenanceProcedure
+{
+
+struct ESEL
+{
+ static constexpr auto str = "ESEL=%s";
+ static constexpr auto str_short = "ESEL";
+ using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+ explicit constexpr ESEL(const char* a) : _entry(entry(str, a)) {};
+ type _entry;
+};
+
+} // namespace _MaintenanceProcedure
+
+struct MaintenanceProcedure
+{
+ static constexpr auto L = level::ERR;
+ using ESEL = _MaintenanceProcedure::ESEL;
+ using PROCEDURE = org::open_power::Common::Callout::Procedure::PROCEDURE;
+ using metadata_types = std::tuple<ESEL, PROCEDURE>;
+
+};
+
+} // namespace Host
+} // namespace open_power
+} // namespace org
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::org::open_power::Host::Error::MaintenanceProcedure>
+{
+ using type = org::open_power::Host::MaintenanceProcedure;
+};
+
+}
+
namespace xyz
{
namespace openbmc_project
diff --git a/error-HostEvent.hpp b/error-HostEvent.hpp
index 186e28e..40872a1 100644
--- a/error-HostEvent.hpp
+++ b/error-HostEvent.hpp
@@ -26,6 +26,19 @@
const char* what() const noexcept override;
};
+struct MaintenanceProcedure final : public sdbusplus::exception_t
+{
+ static constexpr auto errName = "org.open_power.Host.Error.MaintenanceProcedure";
+ static constexpr auto errDesc =
+ "A host system event with a procedure callout";
+ static constexpr auto errWhat =
+ "org.open_power.Host.Error.MaintenanceProcedure: A host system event with a procedure callout";
+
+ const char* name() const noexcept override;
+ const char* description() const noexcept override;
+ const char* what() const noexcept override;
+};
+
} // namespace Error
} // namespace Host
} // namespace open_power
diff --git a/storageaddsel.cpp b/storageaddsel.cpp
index 01147ac..82ac74b 100644
--- a/storageaddsel.cpp
+++ b/storageaddsel.cpp
@@ -241,3 +241,48 @@
return;
}
+
+std::string readESEL(const char* fileName)
+{
+ std::string content;
+ std::ifstream handle(fileName);
+
+ if (handle.fail())
+ {
+ log<level::ERR>("Failed to open eSEL", entry("FILENAME=%s", fileName));
+ return content;
+ }
+
+ handle.seekg(0, std::ios::end);
+ content.resize(handle.tellg());
+ handle.seekg(0, std::ios::beg);
+ handle.read(&content[0], content.size());
+ handle.close();
+
+ return content;
+}
+
+void createProcedureLogEntry(uint8_t procedureNum)
+{
+ // Read the eSEL data from the file.
+ static constexpr auto eSELFile = "/tmp/esel";
+ auto eSELData = readESEL(eSELFile);
+
+ // Each byte in eSEL is formatted as %02x with a space between bytes and
+ // insert '/0' at the end of the character array.
+ static constexpr auto byteSeparator = 3;
+ std::unique_ptr<char[]> data(new char[
+ (eSELData.size() * byteSeparator) + 1]());
+
+ for (size_t i = 0; i < eSELData.size(); i++)
+ {
+ sprintf(&data[i * byteSeparator], "%02x ", eSELData[i]);
+ }
+ data[eSELData.size() * byteSeparator] = '\0';
+
+ using error = sdbusplus::org::open_power::Host::Error::MaintenanceProcedure;
+ using metadata = org::open_power::Host::MaintenanceProcedure;
+
+ report<error>(metadata::ESEL(data.get()),
+ metadata::PROCEDURE(static_cast<uint32_t>(procedureNum)));
+}
diff --git a/storageaddsel.h b/storageaddsel.h
index 7535208..5cb826e 100644
--- a/storageaddsel.h
+++ b/storageaddsel.h
@@ -1,3 +1,17 @@
#include <stdint.h>
-void send_esel(uint16_t recordid) ;
\ No newline at end of file
+void send_esel(uint16_t recordid) ;
+
+/** @brief Read eSEL data into a string
+ *
+ * @param[in] filename - filename of file containing eSEL
+ *
+ * @return On success return the eSEL data
+ */
+std::string readESEL(const char* filename);
+
+/** @brief Create a log entry with maintenance procedure
+ *
+ * @param[in] procedureNum - procedure number associated with the log entry
+ */
+void createProcedureLogEntry(uint8_t procedureNum);
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 8d9e93d..9052b6f 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -578,7 +578,19 @@
// Pack the actual response
memcpy(response, &p->eventdata[1], 2);
- send_esel(recordid);
+ // Hostboot sends SEL with OEM record type 0xDE to indicate that there is
+ // a maintenance procedure associated with eSEL record.
+ static constexpr auto procedureType = 0xDE;
+ if (p->recordtype == procedureType)
+ {
+ // In the OEM record type 0xDE, byte 11 in the SEL record indicate the
+ // procedure number.
+ createProcedureLogEntry(p->sensortype);
+ }
+ else
+ {
+ send_esel(recordid);
+ }
return rc;
}