NVMeSensorMain: Remove sensors when removing configs

Handle drive hot-unplug through the InterfacesRemoved signal from EM.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I685f0f2d3c8adc5b305c59546b306d5d8c8910c9
diff --git a/src/NVMeSensorMain.cpp b/src/NVMeSensorMain.cpp
index 165cf2b..8eaeb57 100644
--- a/src/NVMeSensorMain.cpp
+++ b/src/NVMeSensorMain.cpp
@@ -184,6 +184,40 @@
     getter->getConfiguration(std::vector<std::string>{NVMeSensor::CONFIG_TYPE});
 }
 
+static void interfaceRemoved(sdbusplus::message::message& message,
+                             NVMEMap& contexts)
+{
+    if (message.is_method_error())
+    {
+        std::cerr << "interfacesRemoved callback method error\n";
+        return;
+    }
+
+    sdbusplus::message::object_path path;
+    std::vector<std::string> interfaces;
+
+    message.read(path, interfaces);
+
+    for (auto& [_, context] : contexts)
+    {
+        std::optional<std::shared_ptr<NVMeSensor>> sensor =
+            context->getSensorAtPath(path);
+        if (!sensor)
+        {
+            continue;
+        }
+
+        auto interface = std::find(interfaces.begin(), interfaces.end(),
+                                   (*sensor)->objectType);
+        if (interface == interfaces.end())
+        {
+            continue;
+        }
+
+        context->removeSensor(sensor.value());
+    }
+}
+
 int main()
 {
     boost::asio::io_service io;
@@ -226,6 +260,16 @@
             std::string(NVMeSensor::CONFIG_TYPE) + "'",
         eventHandler);
 
+    // Watch for entity-manager to remove configuration interfaces
+    // so the corresponding sensors can be removed.
+    auto ifaceRemovedMatch = std::make_unique<sdbusplus::bus::match::match>(
+        static_cast<sdbusplus::bus::bus&>(*systemBus),
+        "type='signal',member='InterfacesRemoved',arg0path='" +
+            std::string(inventoryPath) + "/'",
+        [](sdbusplus::message::message& msg) {
+            interfaceRemoved(msg, nvmeDeviceMap);
+        });
+
     setupManufacturingModeMatch(*systemBus);
     io.run();
 }