monitor : do not trigger error when inventory unavailable
Under some startup scenarios, fan-monitor can start before the
InventoryManager service has populated inventory. This leads to
false-positives when marking fans non-functional.
This fix detects D-Bus exceptions and defaults the fans to functional.
They subscribe to the interfaces-added signal which will populate the
fans with correct values as soon as Inventory Manager completes startup.
Signed-off-by: Mike Capps <mikepcapps@gmail.com>
Change-Id: I14bff20da14cba3f5ef4b79763867b5cecab0267
diff --git a/monitor/fan.cpp b/monitor/fan.cpp
index 5f0414d..c5322b1 100644
--- a/monitor/fan.cpp
+++ b/monitor/fan.cpp
@@ -84,7 +84,16 @@
(_numSensorFailsForNonFunc == 0) ||
(countNonFunctionalSensors() < _numSensorFailsForNonFunc);
- updateInventory(functionalState);
+ if (updateInventory(functionalState) && !functionalState)
+ {
+ // the inventory update threw an exception, possibly because D-Bus
+ // wasn't ready. Try to update sensors back to functional to avoid a
+ // false-alarm. They will be updated again from subscribing to the
+ // properties-changed event
+
+ for (auto& sensor : _sensors)
+ sensor->setFunctional(true);
+ }
#ifndef MONITOR_USE_JSON
// Check current tach state when entering monitor mode
@@ -406,21 +415,41 @@
_system.fanStatusChange(*this);
}
-void Fan::updateInventory(bool functional)
+bool Fan::updateInventory(bool functional)
{
- auto objectMap =
- util::getObjMap<bool>(_name, util::OPERATIONAL_STATUS_INTF,
- util::FUNCTIONAL_PROPERTY, functional);
- auto response = util::SDBusPlus::lookupAndCallMethod(
- _bus, util::INVENTORY_PATH, util::INVENTORY_INTF, "Notify", objectMap);
- if (response.is_method_error())
+ bool dbusError = false;
+
+ try
{
- log<level::ERR>("Error in Notify call to update inventory");
- return;
+ auto objectMap =
+ util::getObjMap<bool>(_name, util::OPERATIONAL_STATUS_INTF,
+ util::FUNCTIONAL_PROPERTY, functional);
+
+ auto response = util::SDBusPlus::lookupAndCallMethod(
+ _bus, util::INVENTORY_PATH, util::INVENTORY_INTF, "Notify",
+ objectMap);
+
+ if (response.is_method_error())
+ {
+ log<level::ERR>("Error in Notify call to update inventory");
+
+ dbusError = true;
+ }
+ }
+ catch (const util::DBusError& e)
+ {
+ dbusError = true;
+
+ getLogger().log(
+ fmt::format("D-Bus Exception reading/updating inventory : {}",
+ e.what()),
+ Logger::error);
}
// This will always track the current state of the inventory.
_functional = functional;
+
+ return dbusError;
}
void Fan::presenceChanged(sdbusplus::message::message& msg)
diff --git a/monitor/fan.hpp b/monitor/fan.hpp
index d4bcb2d..8d9f3b2 100644
--- a/monitor/fan.hpp
+++ b/monitor/fan.hpp
@@ -213,8 +213,10 @@
*
* @param[in] functional - If the Functional property should
* be set to true or false.
+ *
+ * @return - True if an exception was encountered during update
*/
- void updateInventory(bool functional);
+ bool updateInventory(bool functional);
/**
* @brief Called by _monitorTimer to start fan monitoring some
diff --git a/monitor/tach_sensor.cpp b/monitor/tach_sensor.cpp
index cc35c97..daeb1f0 100644
--- a/monitor/tach_sensor.cpp
+++ b/monitor/tach_sensor.cpp
@@ -84,11 +84,13 @@
{
// Query functional state from inventory
// TODO - phosphor-fan-presence/issues/25
- auto service = util::SDBusPlus::getService(
- _bus, util::INVENTORY_PATH + _invName, util::OPERATIONAL_STATUS_INTF);
try
{
+ auto service =
+ util::SDBusPlus::getService(_bus, util::INVENTORY_PATH + _invName,
+ util::OPERATIONAL_STATUS_INTF);
+
if (!service.empty())
{
_functional = util::SDBusPlus::getProperty<bool>(
@@ -100,14 +102,12 @@
// default to functional when service not up. Error handling done
// later
_functional = true;
- updateInventory(_functional);
}
}
catch (util::DBusError& e)
{
log<level::DEBUG>(e.what());
_functional = true;
- updateInventory(_functional);
}
if (!_functional && MethodMode::count == _method)