monitor: Start checking power off rules
In the system object, load the power off rules and start checking them.
It will check them in the following cases (if power is on):
* When the object is constructed
* When the JSON config is reloaded
* When fan presence or sensor functional state changes
* When the power state changes to on
When the power is turned off, it will cancel any running rules.
Previously, fan monitor was only designed to run with power on, and
there still may be more changes than just the ones added here to support
it always running.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I8be81612ae4997d7568678471ac0f6f854a0e758
diff --git a/monitor/system.cpp b/monitor/system.cpp
index 41a5750..f9a8804 100644
--- a/monitor/system.cpp
+++ b/monitor/system.cpp
@@ -41,6 +41,10 @@
_mode(mode),
_bus(bus), _event(event)
{
+ _powerState = std::make_unique<PGoodState>(
+ bus, std::bind(std::mem_fn(&System::powerStateChanged), this,
+ std::placeholders::_1));
+
json jsonObj = json::object();
#ifdef MONITOR_USE_JSON
jsonObj = getJsonObj(bus);
@@ -49,7 +53,26 @@
setTrustMgr(getTrustGroups(jsonObj));
// Retrieve fan definitions and create fan objects to be monitored
setFans(getFanDefinitions(jsonObj));
+ setFaultConfig(jsonObj);
log<level::INFO>("Configuration loaded");
+
+ // Since this doesn't run at standby yet, powerStateChanged
+ // will never be called so for now treat start up as the
+ // pgood. When this does run at standby, the 'atPgood'
+ // rules won't need to be checked here.
+ if (_powerState->isPowerOn())
+ {
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) {
+ rule->check(PowerRuleState::atPgood, _fanHealth);
+ });
+ // Runtime rules still need to be checked since fans may already
+ // be missing that could trigger a runtime rule.
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) {
+ rule->check(PowerRuleState::runtime, _fanHealth);
+ });
+ }
}
void System::sighupHandler(sdeventplus::source::Signal&,
@@ -69,7 +92,16 @@
_fans.clear();
_fanHealth.clear();
setFans(fanDefs);
+ setFaultConfig(jsonObj);
log<level::INFO>("Configuration reloaded successfully");
+
+ if (_powerState->isPowerOn())
+ {
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) {
+ rule->check(PowerRuleState::runtime, _fanHealth);
+ });
+ }
}
catch (std::runtime_error& re)
{
@@ -138,6 +170,45 @@
void System::fanStatusChange(const Fan& fan)
{
updateFanHealth(fan);
+
+ if (_powerState->isPowerOn())
+ {
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) {
+ rule->check(PowerRuleState::runtime, _fanHealth);
+ });
+ }
+}
+
+void System::setFaultConfig(const json& jsonObj)
+{
+#ifdef MONITOR_USE_JSON
+ std::shared_ptr<PowerInterfaceBase> powerInterface =
+ std::make_shared<PowerInterface>();
+
+ _powerOffRules = getPowerOffRules(jsonObj, powerInterface);
+#endif
+}
+
+void System::powerStateChanged(bool powerStateOn)
+{
+ if (powerStateOn)
+ {
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) {
+ rule->check(PowerRuleState::atPgood, _fanHealth);
+ });
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) {
+ rule->check(PowerRuleState::runtime, _fanHealth);
+ });
+ }
+ else
+ {
+ // Cancel any in-progress power off actions
+ std::for_each(_powerOffRules.begin(), _powerOffRules.end(),
+ [this](auto& rule) { rule->cancel(); });
+ }
}
} // namespace phosphor::fan::monitor