sensordatahandler: Throw on sensor's OperationalStatus
Add UPDATE_FUNCTIONAL_ON_FAIL and only when defined, read sensor's
OperationalStatus interface for the functional property and throw if the
sensor is not funcitonal.
Bug: openbmc/phosphor-hwmon#10
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I1144a6d3f8145bda73f3363664ca48b848a295db
diff --git a/configure.ac b/configure.ac
index 869c53d..5ed0506 100644
--- a/configure.ac
+++ b/configure.ac
@@ -192,6 +192,26 @@
AS_IF([test "x$HOST_IPMI_LIB_PATH" == "x"], [HOST_IPMI_LIB_PATH="/usr/lib/ipmid-providers/"])
AC_DEFINE_UNQUOTED([HOST_IPMI_LIB_PATH], ["$HOST_IPMI_LIB_PATH"], [The file path to search for libraries.])
+# When a sensor read fails, hwmon will update the OperationalState interface's Functional property.
+# This will mark the sensor as not functional and we will skip reading from that sensor.
+AC_ARG_ENABLE([update-functional-on-fail],
+ AS_HELP_STRING(
+ [--enable-update-functional-on-fail],
+ [Check functional property to skip reading from faulty sensors.]
+ )
+)
+
+AC_ARG_VAR(UPDATE_FUNCTIONAL_ON_FAIL, [Check functional property to skip reading from faulty sensors.])
+AS_IF(
+ [test "x$enable_update_functional_on_fail" == "xyes"],
+ [UPDATE_FUNCTIONAL_ON_FAIL="yes"]
+ AC_DEFINE_UNQUOTED(
+ [UPDATE_FUNCTIONAL_ON_FAIL],
+ ["$UPDATE_FUNCTIONAL_ON_FAIL"],
+ [Check functional property to skip reading from faulty sensors.]
+ )
+)
+
# When disable-libuserlayer flag is set, libuserlayer won't be included in the build.
AC_ARG_ENABLE([libuserlayer],
AS_HELP_STRING([--disable-libuserlayer], [Set a flag to exclude libuserlayer])
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index 73f0dbf..129cbb4 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+
#include "sensorhandler.hpp"
#include <cmath>
@@ -190,6 +192,32 @@
auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
sensorInfo.sensorPath);
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ // Check the OperationalStatus interface for functional property
+ if (sensorInfo.propertyInterfaces.begin()->first ==
+ "xyz.openbmc_project.Sensor.Value")
+ {
+ bool functional = true;
+ try
+ {
+ auto funcValue = ipmi::getDbusProperty(
+ bus, service, sensorInfo.sensorPath,
+ "xyz.openbmc_project.State.Decorator.OperationalStatus",
+ "Functional");
+ functional = std::get<bool>(funcValue);
+ }
+ catch (...)
+ {
+ // No-op if Functional property could not be found since this
+ // check is only valid for Sensor.Value read for hwmonio
+ }
+ if (!functional)
+ {
+ throw SensorFunctionalError();
+ }
+ }
+#endif
+
auto propValue = ipmi::getDbusProperty(
bus, service, sensorInfo.sensorPath,
sensorInfo.propertyInterfaces.begin()->first,
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index d67e7f5..b321e96 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -1,3 +1,5 @@
+#include "config.h"
+
#include "sensorhandler.hpp"
#include "fruread.hpp"
@@ -420,6 +422,12 @@
resp->operation = 1 << scanningEnabledBit;
return IPMI_CC_OK;
}
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ catch (const SensorFunctionalError& e)
+ {
+ return IPMI_CC_RESPONSE_ERROR;
+ }
+#endif
catch (const std::exception& e)
{
*data_len = getResponse.size();
diff --git a/sensorhandler.hpp b/sensorhandler.hpp
index 56a7021..f5a8b41 100644
--- a/sensorhandler.hpp
+++ b/sensorhandler.hpp
@@ -2,6 +2,7 @@
#include <stdint.h>
+#include <exception>
#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
@@ -38,6 +39,16 @@
IPMI_SENSOR_TPM = 0xCC,
};
+/** @brief Custom exception for reading sensors that are not funcitonal.
+ */
+struct SensorFunctionalError : public std::exception
+{
+ const char* what() const noexcept
+ {
+ return "Sensor not functional";
+ }
+};
+
#define MAX_DBUS_PATH 128
struct dbus_interface_t
{