monitor: Track fan health in the System object
To prepare for being able to power off the system based on missing fans
or nonfunctional fan sensors, put a global view of this health for all
fans in the System object. This requires now keeping track of fan
presence.
This information is stored in a map based on the fan name. It is done
this way, as opposed to just always calling present/functional APIs on
the Fan objects, so that the code that will be using this information
can be tested in isolation without the System or Fan objects.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ieb1d4003bd13cebc806fd06f0064c63ea8ac6180
diff --git a/monitor/fan.cpp b/monitor/fan.cpp
index 525a22b..6abd2da 100644
--- a/monitor/fan.cpp
+++ b/monitor/fan.cpp
@@ -48,7 +48,12 @@
_monitorDelay(std::get<monitorStartDelayField>(def)),
_monitorTimer(event, std::bind(std::mem_fn(&Fan::startMonitor), this)),
#endif
- _system(system)
+ _system(system),
+ _presenceMatch(bus,
+ rules::propertiesChanged(util::INVENTORY_PATH + _name,
+ util::INV_ITEM_IFACE),
+ std::bind(std::mem_fn(&Fan::presenceChanged), this,
+ std::placeholders::_1))
{
// Start from a known state of functional
updateInventory(true);
@@ -92,8 +97,11 @@
// If it used the JSON config, then it also will do all the work
// out of fan-monitor-init, after _monitorDelay.
_monitorTimer.restartOnce(std::chrono::seconds(_monitorDelay));
-
#endif
+
+ // Get the initial presence state
+ _present = util::SDBusPlus::getProperty<bool>(
+ util::INVENTORY_PATH + _name, util::INV_ITEM_IFACE, "Present");
}
void Fan::startMonitor()
@@ -229,6 +237,8 @@
updateInventory(false);
}
+
+ _system.fanStatusChange(*this);
}
void Fan::updateInventory(bool functional)
@@ -248,6 +258,21 @@
_functional = functional;
}
+void Fan::presenceChanged(sdbusplus::message::message& msg)
+{
+ std::string interface;
+ std::map<std::string, std::variant<bool>> properties;
+
+ msg.read(interface, properties);
+
+ auto presentProp = properties.find("Present");
+ if (presentProp != properties.end())
+ {
+ _present = std::get<bool>(presentProp->second);
+
+ _system.fanStatusChange(*this);
+ }
+}
} // namespace monitor
} // namespace fan
} // namespace phosphor