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/mainloop.cpp b/mainloop.cpp
index 5fa66cd..d961a10 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -393,21 +393,19 @@
input = "";
}
+ int64_t value;
+ auto& objInfo = std::get<ObjectInfo>(i.second);
+ auto& obj = std::get<InterfaceMap>(objInfo);
+ std::unique_ptr<sensor::Sensor>& sensor = _sensorObjects[i.first];
+
+ auto& statusIface = std::any_cast<std::shared_ptr<StatusObject>&>(
+ obj[InterfaceType::STATUS]);
+ // As long as addStatus is called before addValue, statusIface
+ // should never be nullptr.
+ assert(statusIface);
+
try
{
- int64_t value;
- auto& objInfo = std::get<ObjectInfo>(i.second);
- auto& obj = std::get<InterfaceMap>(objInfo);
- std::unique_ptr<sensor::Sensor>& sensor =
- _sensorObjects[i.first];
-
- auto& statusIface =
- std::any_cast<std::shared_ptr<StatusObject>&>(
- obj[InterfaceType::STATUS]);
- // As long as addStatus is called before addValue, statusIface
- // should never be nullptr.
- assert(statusIface);
-
if (sensor->hasFaultFile())
{
auto fault = _ioAccess->read(
@@ -430,6 +428,8 @@
value =
_ioAccess->read(i.first.first, i.first.second, input,
hwmonio::retries, hwmonio::delay);
+ // Set functional property to true if we could read sensor
+ statusIface->functional(true);
value = sensor->adjustValue(value);
}
@@ -438,6 +438,13 @@
}
catch (const std::system_error& e)
{
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ // If UPDATE_FUNCTIONAL_ON_FAIL is defined and an exception was
+ // thrown, set the functional property to false.
+ // We cannot set this with the 'continue' in the lower block
+ // as the code may exit before reaching it.
+ statusIface->functional(false);
+#endif
auto file = sysfs::make_sysfs_path(
_ioAccess->path(), i.first.first, i.first.second,
hwmon::entry::cinput);
@@ -459,7 +466,10 @@
}
continue;
}
-
+#ifdef UPDATE_FUNCTIONAL_ON_FAIL
+ // Do not exit with failure if UPDATE_FUNCTIONAL_ON_FAIL is set
+ continue;
+#endif
using namespace sdbusplus::xyz::openbmc_project::Sensor::
Device::Error;
report<ReadFailure>(