PHAL: Log Informational error for PEL created during poweroff
1)Log informational PELS in case system state is transitioning to
power-off for IPL procedures/hardware access failures
2) Don't add callouts to PEL's created during transition to
power-off as the CEC will not be in expected state.
Tested: transition to poweroff
root@xxxbmc:/usr# peltool -lfh
{
"0x50003BEB": {
"SRC": "BD503001",
"Message": "Failure occurred during boot process",
"PLID": "0x50003BEB",
"CreatorID": "BMC",
"Subsystem": "CEC Hardware",
"Commit Time": "05/23/2022 13:57:53",
"Sev": "Informational Event",
"CompID": "0x3000"
}
}
root@xxxbmc:~# peltool -i 0x50003be0
{
"Private Header": {
"Section Version": "1",
"Sub-section type": "0",
"Created by": "0x3000",
"Created at": "05/23/2022 13:48:12",
"Committed at": "05/23/2022 13:48:12",
"Creator Subsystem": "BMC",
"CSSVER": "",
"Platform Log Id": "0x50003BE0",
"Entry Id": "0x50003BE0",
"BMC Event Log Id": "510"
},
"User Header": {
"Section Version": "1",
"Sub-section type": "0",
"Log Committed by": "0x2000",
"Subsystem": "CEC Hardware",
"Event Scope": "Entire Platform",
"Event Severity": "Informational Event",
"Event Type": "Miscellaneous, Informational Only",
"Action Flags": [
"Event not customer viewable",
"Report Externally"
],
"Host Transmission": "Not Sent",
"HMC Transmission": "Not Sent"
},
.
.
.
Tested: transition to running
root@ever8bmc:/tmp# peltool -i 0x50003CF9
{
"Private Header": {
"Section Version": "1",
"Sub-section type": "0",
"Created by": "0x3000",
},
"User Header": {
"Section Version": "1",
"Sub-section type": "0",
"Log Committed by": "0x2000",
"Subsystem": "CEC Hardware",
"Event Scope": "Entire Platform",
"Event Severity": "Unrecoverable Error",
},
"User Data 0": {
"Created by": "0x2000",
"BMCState": "Ready",
"BootState": "Unspecified",
"ChassisState": "On",
"FW Version ID": "fw1020.00-57.7-2-gd86188a773",
"HostState": "TransitioningToRunning",
"Process Name": "/usr/bin/openpower-proc-control",
"System IM": "50003000"
},
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
Change-Id: I078d5cba2e0fb705bf424d2f8f3010f2cd2063bb
diff --git a/extensions/phal/create_pel.cpp b/extensions/phal/create_pel.cpp
index 8638d5c..75ee064 100644
--- a/extensions/phal/create_pel.cpp
+++ b/extensions/phal/create_pel.cpp
@@ -79,7 +79,7 @@
}
void createErrorPEL(const std::string& event, const json& calloutData,
- const FFDCData& ffdcData)
+ const FFDCData& ffdcData, const Severity severity)
{
std::map<std::string, std::string> additionalData;
auto bus = sdbusplus::bus::new_default();
@@ -111,8 +111,7 @@
loggingInterface, "CreateWithFFDCFiles");
auto level =
sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
- sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
- Error);
+ severity);
method.append(event, level, additionalData, pelCalloutInfo);
auto resp = bus.call(method);
}
diff --git a/extensions/phal/create_pel.hpp b/extensions/phal/create_pel.hpp
index 674381b..ffd1315 100644
--- a/extensions/phal/create_pel.hpp
+++ b/extensions/phal/create_pel.hpp
@@ -29,9 +29,11 @@
* @param[in] event - the event type
* @param[in] calloutData - callout data to append to PEL
* @param[in] ffdcData - failure data to append to PEL
+ * @param[in] severity - severity of the log default to Informational
*/
void createErrorPEL(const std::string& event, const json& calloutData = {},
- const FFDCData& ffdcData = {});
+ const FFDCData& ffdcData = {},
+ const Severity severity = Severity::Informational);
/**
* @brief Create SBE boot error PEL and return id
diff --git a/extensions/phal/phal_error.cpp b/extensions/phal/phal_error.cpp
index a53ba77..8879964 100644
--- a/extensions/phal/phal_error.cpp
+++ b/extensions/phal/phal_error.cpp
@@ -7,6 +7,7 @@
#include "dump_utils.hpp"
#include "extensions/phal/common_utils.hpp"
#include "phal_error.hpp"
+#include "util.hpp"
#include <attributes_info.H>
#include <fmt/format.h>
@@ -31,6 +32,7 @@
{
using namespace phosphor::logging;
using namespace openpower::phal::exception;
+using Severity = sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level;
/**
* Used to pass buffer to pdbg callback api to get required target
@@ -321,7 +323,7 @@
});
openpower::pel::createErrorPEL(
"org.open_power.PHAL.Error.NonFunctionalBootProc", jsonCalloutDataList,
- pelAdditionalData);
+ pelAdditionalData, Severity::Error);
// reset trace log and exit
reset();
}
@@ -387,6 +389,69 @@
jsonCalloutDataList.emplace_back(jsonCalloutData);
}
+/**
+ * @brief processPoweroffError
+ *
+ * Creates informational PEL for the PLAT/HWP error occured during poweroff
+ *
+ * Not adding callouts from FFDC as the hardware errors in the poweroff path
+ * should be non-visible. so that we don't throw out extraneous callouts for
+ * power errors or because the CEC is just not in an expected state.
+ *
+ * @param[in] ffdc - FFDC data capturd by the HWP
+ * @param[in] ffdc_prefix - prefix string for logging the data.
+ */
+
+void processPoweroffError(FFDC* ffdc, const std::string& ffdc_prefix)
+{
+ try
+ {
+ log<level::INFO>(
+ fmt::format("processPoweroffError: Message[{}]", ffdc->message)
+ .c_str());
+
+ // To store phal trace and other additional data about ffdc.
+ FFDCData pelAdditionalData;
+
+ if (ffdc->ffdc_type == FFDC_TYPE_HWP)
+ {
+ std::string keyWithPrefix(ffdc_prefix + "RC");
+ // Adding hardware procedures return code details
+ pelAdditionalData.emplace_back(keyWithPrefix,
+ ffdc->hwp_errorinfo.rc);
+ keyWithPrefix = ffdc_prefix + "RC_DESC";
+ pelAdditionalData.emplace_back(keyWithPrefix,
+ ffdc->hwp_errorinfo.rc_desc);
+ }
+ else if ((ffdc->ffdc_type != FFDC_TYPE_NONE) &&
+ (ffdc->ffdc_type != FFDC_TYPE_UNSUPPORTED))
+ {
+ log<level::ERR>(
+ fmt::format("Unsupported phal FFDC type to create PEL. "
+ "MSG: {}",
+ ffdc->message)
+ .c_str());
+ }
+
+ // Adding collected phal logs into PEL additional data
+ for_each(traceLog.begin(), traceLog.end(),
+ [&pelAdditionalData](
+ std::pair<std::string, std::string>& ele) -> void {
+ pelAdditionalData.emplace_back(ele.first, ele.second);
+ });
+
+ openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot", {},
+ pelAdditionalData,
+ Severity::Informational);
+ }
+ catch (const std::exception& ex)
+ {
+ reset();
+ throw ex;
+ }
+ reset();
+}
+
void processBootErrorHelper(FFDC* ffdc, const std::string& ffdc_prefix)
{
log<level::INFO>("processBootErrorHelper ");
@@ -622,7 +687,8 @@
return true;
});
openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot",
- jsonCalloutDataList, pelAdditionalData);
+ jsonCalloutDataList, pelAdditionalData,
+ Severity::Error);
}
catch (const std::exception& ex)
{
@@ -640,7 +706,14 @@
FFDC* ffdc = reinterpret_cast<FFDC*>(errInfo.private_data);
try
{
- processBootErrorHelper(ffdc, "PLAT_");
+ if (util::isHostPoweringOff())
+ {
+ processPoweroffError(ffdc, "PLAT_");
+ }
+ else
+ {
+ processBootErrorHelper(ffdc, "PLAT_");
+ }
}
catch (const std::exception& ex)
{
@@ -661,12 +734,18 @@
// return If no failure during hwp execution
if (status)
return;
-
// Collecting ffdc details from phal
FFDC ffdc;
libekb_get_ffdc(ffdc);
- processBootErrorHelper(&ffdc, "HWP_");
+ if (util::isHostPoweringOff())
+ {
+ processPoweroffError(&ffdc, "HWP_");
+ }
+ else
+ {
+ processBootErrorHelper(&ffdc, "HWP_");
+ }
}
catch (const std::exception& ex)
{
@@ -716,7 +795,7 @@
jsonCalloutDataList.emplace_back(jsonCalloutData);
openpower::pel::createErrorPEL(
"org.open_power.Processor.Error.SbeBootFailure",
- jsonCalloutDataList);
+ jsonCalloutDataList, {}, Severity::Error);
return;
}
// SBE error object.
diff --git a/meson.build b/meson.build
index a8586e1..76bc8fe 100644
--- a/meson.build
+++ b/meson.build
@@ -112,6 +112,7 @@
'extensions/phal/phal_error.cpp',
'extensions/phal/dump_utils.cpp',
'temporary_file.cpp',
+ 'util.cpp',
]
extra_dependencies += [
dependency('libdt-api'),
diff --git a/procedures/phal/reinit_devtree.cpp b/procedures/phal/reinit_devtree.cpp
index 60e6e49..c5ae058 100644
--- a/procedures/phal/reinit_devtree.cpp
+++ b/procedures/phal/reinit_devtree.cpp
@@ -107,6 +107,8 @@
void reinitDevtree()
{
using json = nlohmann::json;
+ using Severity =
+ sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level;
log<level::INFO>("reinitDevtree: started");
@@ -213,7 +215,8 @@
jsonCalloutData["Priority"] = "M";
jsonCalloutDataList.emplace_back(jsonCalloutData);
openpower::pel::createErrorPEL(
- "org.open_power.PHAL.Error.devtreeReinit", jsonCalloutDataList);
+ "org.open_power.PHAL.Error.devtreeReinit", jsonCalloutDataList, {},
+ Severity::Error);
}
// Step 4: Update devtree r/w file
@@ -252,7 +255,8 @@
jsonCalloutData["Priority"] = "H";
jsonCalloutDataList.emplace_back(jsonCalloutData);
openpower::pel::createErrorPEL(
- "org.open_power.PHAL.Error.devtreeReinit", jsonCalloutDataList);
+ "org.open_power.PHAL.Error.devtreeReinit", jsonCalloutDataList, {},
+ Severity::Error);
throw;
}
}
diff --git a/procedures/phal/start_host.cpp b/procedures/phal/start_host.cpp
index 01cada9..fc30ecc 100644
--- a/procedures/phal/start_host.cpp
+++ b/procedures/phal/start_host.cpp
@@ -188,6 +188,8 @@
try
{
using json = nlohmann::json;
+ using Severity =
+ sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level;
json jsonCalloutDataList;
jsonCalloutDataList = json::array();
@@ -197,7 +199,8 @@
jsonCalloutDataList.emplace_back(jsonCalloutData);
openpower::pel::createErrorPEL("org.open_power.PHAL.Error.Boot",
- jsonCalloutDataList, additionalData);
+ jsonCalloutDataList, additionalData,
+ Severity::Error);
}
catch (const std::exception& e)
{
diff --git a/procedures/phal/thread_stopall.cpp b/procedures/phal/thread_stopall.cpp
index 983a7ca..8c77690 100644
--- a/procedures/phal/thread_stopall.cpp
+++ b/procedures/phal/thread_stopall.cpp
@@ -137,7 +137,7 @@
jsonCalloutDataList.emplace_back(jsonCalloutData);
openpower::pel::createErrorPEL(
"org.open_power.Processor.Error.SbeChipOpFailure",
- jsonCalloutDataList, pelAdditionalData);
+ jsonCalloutDataList, pelAdditionalData, Severity::Informational);
return;
}
}
diff --git a/util.cpp b/util.cpp
index 0c3e669..ed4eed9 100644
--- a/util.cpp
+++ b/util.cpp
@@ -43,5 +43,51 @@
}
return response.begin()->first;
}
+
+bool isHostPoweringOff()
+{
+ try
+ {
+ constexpr auto object = "/xyz/openbmc_project/state/host0";
+ constexpr auto service = "xyz.openbmc_project.State.Host";
+ constexpr auto interface = "xyz.openbmc_project.State.Host";
+ constexpr auto property = "CurrentHostState";
+ auto bus = sdbusplus::bus::new_default();
+
+ std::variant<std::string> retval;
+ auto properties = bus.new_method_call(
+ service, object, "org.freedesktop.DBus.Properties", "Get");
+ properties.append(interface);
+ properties.append(property);
+ auto result = bus.call(properties);
+ result.read(retval);
+
+ const std::string* state = std::get_if<std::string>(&retval);
+ if (state == nullptr)
+ {
+ std::string err = fmt::format(
+ "CurrentHostState property is not set ({})", object);
+ log<level::ERR>(err.c_str());
+ return false;
+ }
+ if ((*state == "xyz.openbmc_project.State.Host.HostState."
+ "TransitioningToOff") ||
+ (*state == "xyz.openbmc_project.State.Host.HostState."
+ "Off") ||
+ (*state == "xyz.openbmc_project.State.Host.HostState."
+ "Quiesced"))
+ {
+ return true;
+ }
+ }
+ catch (const std::exception& ex)
+ {
+ log<level::ERR>(
+ fmt::format("Failed to read CurrentHostState property ({})",
+ ex.what())
+ .c_str());
+ }
+ return false;
+}
} // namespace util
} // namespace openpower
diff --git a/util.hpp b/util.hpp
index 19a162e..442bd22 100644
--- a/util.hpp
+++ b/util.hpp
@@ -19,5 +19,14 @@
*/
std::string getService(sdbusplus::bus::bus& bus, const std::string& objectPath,
const std::string& interface);
+
+/**
+ * Returns true if host is in poweringoff state else false
+ *
+ * @return bool - true if host is powering off else false. if failed
+ * to read property false will be returned.
+ */
+bool isHostPoweringOff();
+
} // namespace util
} // namespace openpower