Monitor : handle inventory service offline
Using nameHasOwner and nameOwnerChanged D-Bus signals, a callback is
activated when inventory is started.
There are two primary modes for operation: Compatible Interfaces, the
inventory-detection callback will fail, however start() will be called a
second time after EntityManager starts and forces a reload of the proper
config for the machine type. Separately, if no EntityManager exists,
then the callback for Inventory-detection will succeed and use the
default configuration file.
To test: stop fan monitor and inventory services. start monitor, wait
10s, start Inventory, after about 15s you should see the online
detection.
Signed-off-by: Mike Capps <mikepcapps@gmail.com>
Change-Id: I289493a0aabb849abee8ce8de047513e94ee2219
diff --git a/monitor/system.cpp b/monitor/system.cpp
index f3863b0..fc38645 100644
--- a/monitor/system.cpp
+++ b/monitor/system.cpp
@@ -22,6 +22,7 @@
#include "types.hpp"
#include "utility.hpp"
#ifdef MONITOR_USE_JSON
+#include "json_config.hpp"
#include "json_parser.hpp"
#endif
@@ -55,19 +56,54 @@
void System::start()
{
- _started = true;
+ namespace match = sdbusplus::bus::match;
+
+ // must be done before service detection
+ _inventoryMatch = std::make_unique<match::match>(
+ _bus, match::rules::nameOwnerChanged(util::INVENTORY_SVC),
+ std::bind(&System::inventoryOnlineCb, this, std::placeholders::_1));
+
+ bool invServiceRunning = util::SDBusPlus::callMethodAndRead<bool>(
+ _bus, "org.freedesktop.DBus", "/org/freedesktop/DBus",
+ "org.freedesktop.DBus", "NameHasOwner", util::INVENTORY_SVC);
+
+ if (invServiceRunning)
+ {
+ _inventoryMatch.reset();
+
+ if (!_loaded)
+ {
+ load();
+ }
+ }
+}
+
+void System::load()
+{
json jsonObj = json::object();
#ifdef MONITOR_USE_JSON
- auto confFile =
- fan::JsonConfig::getConfFile(_bus, confAppName, confFileName);
- jsonObj = fan::JsonConfig::load(confFile);
+ try
+ {
+ jsonObj = getJsonObj(_bus);
#endif
- // Retrieve and set trust groups within the trust manager
- setTrustMgr(getTrustGroups(jsonObj));
- // Retrieve fan definitions and create fan objects to be monitored
- setFans(getFanDefinitions(jsonObj));
- setFaultConfig(jsonObj);
- log<level::INFO>("Configuration loaded");
+ auto trustGrps = getTrustGroups(jsonObj);
+ auto fanDefs = getFanDefinitions(jsonObj);
+ // Retrieve and set trust groups within the trust manager
+ setTrustMgr(getTrustGroups(jsonObj));
+ // Clear/set configured fan definitions
+ _fans.clear();
+ _fanHealth.clear();
+ // Retrieve fan definitions and create fan objects to be monitored
+ setFans(fanDefs);
+ setFaultConfig(jsonObj);
+ log<level::INFO>("Configuration loaded");
+
+ _loaded = true;
+#ifdef MONITOR_USE_JSON
+ }
+ catch (const phosphor::fan::NoConfigFound&)
+ {}
+#endif
if (_powerState->isPowerOn())
{
@@ -77,16 +113,15 @@
});
}
- if (_sensorMatch.empty())
- {
- subscribeSensorsToServices();
- }
+ subscribeSensorsToServices();
}
void System::subscribeSensorsToServices()
{
namespace match = sdbusplus::bus::match;
+ _sensorMatch.clear();
+
SensorMapType sensorMap;
// build a list of all interfaces, always including the value interface
@@ -152,38 +187,43 @@
}
}
+void System::inventoryOnlineCb(sdbusplus::message::message& msg)
+{
+ namespace match = sdbusplus::bus::match;
+
+ std::string iface;
+ msg.read(iface);
+
+ if (util::INVENTORY_INTF != iface)
+ {
+ return;
+ }
+
+ std::string oldName;
+ msg.read(oldName);
+
+ std::string newName;
+ msg.read(newName);
+
+ // newName should never be empty since match was reset on the first
+ // nameOwnerChanged signal received from the service.
+ if (!_loaded && !newName.empty())
+ {
+ load();
+ }
+
+ // cancel any further notifications about the service state
+ _inventoryMatch.reset();
+}
+
void System::sighupHandler(sdeventplus::source::Signal&,
const struct signalfd_siginfo*)
{
try
{
- json jsonObj = json::object();
-#ifdef MONITOR_USE_JSON
- jsonObj = getJsonObj(_bus);
-#endif
- auto trustGrps = getTrustGroups(jsonObj);
- auto fanDefs = getFanDefinitions(jsonObj);
- // Set configured trust groups
- setTrustMgr(trustGrps);
- // Clear/set configured fan definitions
- _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);
- });
- }
-
- _sensorMatch.clear();
- subscribeSensorsToServices();
+ load();
}
- catch (const std::runtime_error& re)
+ catch (std::runtime_error& re)
{
log<level::ERR>("Error reloading config, no config changes made",
entry("LOAD_ERROR=%s", re.what()));
@@ -317,7 +357,7 @@
if (powerStateOn)
{
- if (!_started)
+ if (!_loaded)
{
log<level::ERR>("No conf file found at power on");
throw std::runtime_error("No conf file found at power on");