sensor: Add UPDATE_FUNCTIONAL_ON_FAIL and its behavior
Add the build switch UPDATE_FUNCTIONAL_ON_FAIL. When enabled, sensor
read failures will not exit the mainloop. Instead, mainloop will update
the Functional property and skip the read of that sensor.
This will skip the "Remove RCs" check during value interface creation in
MainLoop::getObject. However, it will perform the "Remove RCs" checks
during MainLoop::read.
Tested: I was able to use busctl to read the Functional property of a
custom driver to test with UPDATE_FUNCTIONAL_ON_FAIL defined.
1. Negative values were reported, Functional was true
2. Sensor reporting errors had stale values, Functional was set to false
Resolves: openbmc/phosphor-hwmon#10
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I0984dad12250e9587ec36de2f9212de0b0e1cda6
diff --git a/sensor.cpp b/sensor.cpp
index a88410b..6e5e841 100644
--- a/sensor.cpp
+++ b/sensor.cpp
@@ -146,16 +146,32 @@
// Only read the input value if the status is functional
if (statusIface->functional())
{
- // RAII object for GPIO unlock / lock
- GpioLock gpioLock(getGpio());
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ try
+#endif
+ {
+ // RAII object for GPIO unlock / lock
+ GpioLock gpioLock(getGpio());
- // Retry for up to a second if device is busy
- // or has a transient error.
- val = _ioAccess->read(_sensor.first, _sensor.second,
- hwmon::entry::cinput, std::get<size_t>(retryIO),
- std::get<std::chrono::milliseconds>(retryIO));
+ // Retry for up to a second if device is busy
+ // or has a transient error.
+ val =
+ _ioAccess->read(_sensor.first, _sensor.second,
+ hwmon::entry::cinput, std::get<size_t>(retryIO),
+ std::get<std::chrono::milliseconds>(retryIO));
- val = adjustValue(val);
+ val = adjustValue(val);
+ }
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ catch (const std::system_error& e)
+ {
+ // Catch the exception here and update the functional property.
+ // By catching the exception, it will not propagate it up the stack
+ // and thus the code will skip the "Remove RCs" check in
+ // MainLoop::getObject and will not exit on failure.
+ statusIface->functional(false);
+ }
+#endif
}
auto iface =