presence: detect and report GPIO exceptions on startup
To address issue ibm2982, we will now catch exceptions when creating the
GPIO presence sensor and substitute it with a nullary sensor that always
reports non-present. This will give proper error logging for the basic
failure scenario of disconnected hardware. Currently this scenario
causes a core dump and subsequent investigation.
Additionally, an OpenBMC event log has been created using the label
xyz.openbmc_project.Fan.Presence.Error.GPIODeviceUnavailable
Signed-off-by: Mike Capps <mikepcapps@gmail.com>
Change-Id: Ib25fb27ed4a0a23aae667beb1e7708ada7ea7d65
diff --git a/presence/json_parser.cpp b/presence/json_parser.cpp
index 4c4a55c..bfaedaf 100644
--- a/presence/json_parser.cpp
+++ b/presence/json_parser.cpp
@@ -25,6 +25,8 @@
#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Logging/Create/server.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
#include <filesystem>
#include <fstream>
@@ -47,6 +49,9 @@
const std::map<std::string, rpolicyHandler> JsonConfig::_rpolicies = {
{"anyof", rpolicy::getAnyof}, {"fallback", rpolicy::getFallback}};
+const auto loggingPath = "/xyz/openbmc_project/logging";
+const auto loggingCreateIface = "xyz.openbmc_project.Logging.Create";
+
JsonConfig::JsonConfig(sdbusplus::bus::bus& bus) : _bus(bus)
{}
@@ -266,8 +271,47 @@
auto devpath = method["devpath"].get<std::string>();
auto key = method["key"].get<unsigned int>();
- return std::make_unique<PolicyAccess<Gpio, JsonConfig>>(fanIndex, physpath,
- devpath, key);
+ try
+ {
+ return std::make_unique<PolicyAccess<Gpio, JsonConfig>>(
+ fanIndex, physpath, devpath, key);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ namespace sdlogging = sdbusplus::xyz::openbmc_project::Logging::server;
+
+ log<level::ERR>(
+ fmt::format(
+ "Error creating Gpio device bridge, hardware not detected: {}",
+ e.what())
+ .c_str());
+
+ auto severity =
+ sdlogging::convertForMessage(sdlogging::Entry::Level::Error);
+
+ std::map<std::string, std::string> additionalData{
+ {"PHYSPATH", physpath},
+ {"DEVPATH", devpath},
+ {"FANINDEX", std::to_string(fanIndex)}};
+
+ try
+ {
+
+ util::SDBusPlus::lookupAndCallMethod(
+ loggingPath, loggingCreateIface, "Create",
+ "xyz.openbmc_project.Fan.Presence.Error.GPIODeviceUnavailable",
+ severity, additionalData);
+ }
+ catch (const util::DBusError& e)
+ {
+ log<level::ERR>(fmt::format("Call to create an error log for "
+ "presence-sensor failure failed: {}",
+ e.what())
+ .c_str());
+ }
+
+ return std::make_unique<PolicyAccess<NullGpio, JsonConfig>>();
+ }
}
} // namespace method