presence: Sensor conflict checking for AnyOf
There can be more than one way to detect the presence of a fan, such as
by a GPIO and by a nonzero tach reading. The AnyOf redundancy policy
only requires one of these to indicate present when determining the
overall fan presence state.
This commit adds the functionality to check for the case when one of the
method reports not present while another reports present. In this case,
the one reporting not present will be considered the wrong one, and
depending on the detection type either an information event log or just
a journal trace will be created.
Only one log per method per power cycle will occur. Since one of the
methods probably looks for nonzero tach readings, there is a 5 second
delay after a power on is detected before a conflict check is done.
If the GPIO method is where the problem is detected, an event log is
created. If it's instead the tach sensor method, then a trace will just
be put in the journal because there is already code watching for and
creating event logs for stopped tachs - the fan monitor code.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I72a764ecff4076d6dc40335b92d177b6b3cfa2d9
diff --git a/presence/gpio.cpp b/presence/gpio.cpp
index 1aa63a4..8e4a6d2 100644
--- a/presence/gpio.cpp
+++ b/presence/gpio.cpp
@@ -15,12 +15,15 @@
*/
#include "gpio.hpp"
+#include "logging.hpp"
#include "rpolicy.hpp"
+#include "sdbusplus.hpp"
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <sdeventplus/event.hpp>
#include <xyz/openbmc_project/Common/Callout/error.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
#include <functional>
#include <tuple>
@@ -32,6 +35,10 @@
namespace presence
{
+const auto loggingService = "xyz.openbmc_project.Logging";
+const auto loggingPath = "/xyz/openbmc_project/logging";
+const auto loggingCreateIface = "xyz.openbmc_project.Logging.Create";
+
Gpio::Gpio(const std::string& physDevice, const std::string& device,
unsigned int physPin) :
currentState(false),
@@ -86,6 +93,40 @@
currentState = newState;
}
}
+
+void Gpio::logConflict(const std::string& fanInventoryPath) const
+{
+ using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+ std::map<std::string, std::string> ad;
+ Entry::Level severity = Entry::Level::Informational;
+
+ static constexpr auto errorName =
+ "xyz.openbmc_project.Fan.Presence.Error.Detection";
+
+ ad.emplace("_PID", std::to_string(getpid()));
+ ad.emplace("CALLOUT_INVENTORY_PATH", fanInventoryPath);
+ ad.emplace("GPIO_NUM", std::to_string(pin));
+ ad.emplace("GPIO_DEVICE_PATH", (phys.c_str()));
+
+ getLogger().log(
+ fmt::format("GPIO presence detect for fan {} said not present but "
+ "other methods indicated present",
+ fanInventoryPath));
+ try
+ {
+ util::SDBusPlus::callMethod(loggingService, loggingPath,
+ loggingCreateIface, "Create", errorName,
+ severity, ad);
+ }
+ catch (const util::DBusError& e)
+ {
+ getLogger().log(
+ fmt::format("Call to create a {} error for fan {} failed: {}",
+ errorName, fanInventoryPath, e.what()),
+ Logger::error);
+ }
+}
+
} // namespace presence
} // namespace fan
} // namespace phosphor