sensor-mon: Check service on D-Bus at power on

If sensor-monitor has detected a threshold alarm when power is off, it
would log an error for that when the power turns on.

Add a check that the alarm interface is still on D-Bus before logging
the error, in case the sensor-daemon stopped running.

Alternatively, the code could listen for a NameOwnerChanged signal to
see if the daemon stopped, but then it would have to keep a map of
sensor names to service names and always keep it up to date.  The chosen
method seems more straightforward and less error prone.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Idd6201e5b974a6e0d8f9960b39176374a2a01af8
diff --git a/sensor-monitor/threshold_alarm_logger.cpp b/sensor-monitor/threshold_alarm_logger.cpp
index 03b35ba..34090f9 100644
--- a/sensor-monitor/threshold_alarm_logger.cpp
+++ b/sensor-monitor/threshold_alarm_logger.cpp
@@ -404,6 +404,8 @@
 
 void ThresholdAlarmLogger::checkThresholds()
 {
+    std::vector<InterfaceKey> toErase;
+
     for (const auto& [interfaceKey, alarmMap] : alarms)
     {
         for (const auto& [propertyName, alarmValue] : alarmMap)
@@ -412,11 +414,36 @@
             {
                 const auto& sensorPath = std::get<0>(interfaceKey);
                 const auto& interface = std::get<1>(interfaceKey);
+                std::string service;
 
-                createEventLog(sensorPath, interface, propertyName, alarmValue);
+                try
+                {
+                    // Check that the service that provides the alarm is still
+                    // running, because if it died when the alarm was active
+                    // there would be no indication of it unless we listened
+                    // for NameOwnerChanged and tracked services, and this is
+                    // easier.
+                    service = SDBusPlus::getService(bus, sensorPath, interface);
+                }
+                catch (const DBusServiceError& e)
+                {
+                    // No longer on D-Bus delete the alarm entry
+                    toErase.emplace_back(sensorPath, interface);
+                }
+
+                if (!service.empty())
+                {
+                    createEventLog(sensorPath, interface, propertyName,
+                                   alarmValue);
+                }
             }
         }
     }
+
+    for (const auto& e : toErase)
+    {
+        alarms.erase(e);
+    }
 }
 
 } // namespace sensor::monitor