psu-ng: Create errors for detected faults
Add in a function for creating errors using the Create D-Bus call.
Update the analyze function to create errors when faults are found.
We would want to log a fault per power supply, so move the faultLogged
concept down to the PowerSupply object itself.
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
Change-Id: I94d22b2b8a495abde87fb921c9177c6d25225ef7
diff --git a/phosphor-power-supply/psu_manager.cpp b/phosphor-power-supply/psu_manager.cpp
index 0fcd566..c84201e 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -2,6 +2,10 @@
#include "utility.hpp"
+#include <fmt/format.h>
+#include <sys/types.h>
+#include <unistd.h>
+
using namespace phosphor::logging;
namespace phosphor::power::manager
@@ -125,6 +129,44 @@
}
}
+void PSUManager::createError(
+ const std::string& faultName,
+ const std::map<std::string, std::string>& additionalData)
+{
+ using namespace sdbusplus::xyz::openbmc_project;
+ constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging";
+ constexpr auto loggingCreateInterface =
+ "xyz.openbmc_project.Logging.Create";
+
+ try
+ {
+ auto service =
+ util::getService(loggingObjectPath, loggingCreateInterface, bus);
+
+ if (service.empty())
+ {
+ log<level::ERR>("Unable to get logging manager service");
+ return;
+ }
+
+ auto method = bus.new_method_call(service.c_str(), loggingObjectPath,
+ loggingCreateInterface, "Create");
+
+ auto level = Logging::server::Entry::Level::Error;
+ method.append(faultName, level, additionalData);
+
+ auto reply = bus.call(method);
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(
+ fmt::format(
+ "Failed creating event log for fault {} due to error {}",
+ faultName, e.what())
+ .c_str());
+ }
+}
+
void PSUManager::analyze()
{
for (auto& psu : psus)
@@ -135,21 +177,45 @@
for (auto& psu : psus)
{
// TODO: Fault priorities #918
- if (!faultLogged && psu->isFaulted())
+ if (!psu->isFaultLogged() && psu->isFaulted())
{
- if (psu->hasInputFault())
- {
- // TODO: Create error log
- }
+ std::map<std::string, std::string> additionalData;
+ additionalData["_PID"] = std::to_string(getpid());
+ additionalData["STATUS_WORD"] =
+ std::to_string(psu->getStatusWord());
- if (psu->hasMFRFault())
+ if ((psu->hasInputFault() || psu->hasVINUVFault()))
{
- // TODO: Create error log
+ /* The power supply location might be needed if the input fault
+ * is due to a problem with the power supply itself. Include the
+ * inventory path with a call out priority of low.
+ */
+ additionalData["CALLOUT_INVENTORY_PATH"] =
+ psu->getInventoryPath();
+ additionalData["CALLOUT_PRIORITY"] = "L";
+ createError(
+ "xyz.openbmc_project.Power.PowerSupply.Error.InputFault",
+ additionalData);
+ psu->setFaultLogged();
}
-
- if (psu->hasVINUVFault())
+ else if (psu->hasMFRFault())
{
- // TODO: Create error log
+ /* This can represent a variety of faults that result in calling
+ * out the power supply for replacement:
+ * Output OverCurrent, Output Under Voltage, and potentially
+ * other faults.
+ *
+ * Also plan on putting specific fault in AdditionalData,
+ * along with register names and register values
+ * (STATUS_WORD, STATUS_MFR, etc.).*/
+
+ additionalData["CALLOUT_INVENTORY_PATH"] =
+ psu->getInventoryPath();
+
+ createError("xyz.openbmc_project.Power.PowerSupply.Error.Fault",
+ additionalData);
+
+ psu->setFaultLogged();
}
}
}