NVMeSensorMain: Merge interface and subsystem config loops

The startup state machine of NVMeMi is (eventually) asynchronous,
and the events driving it are deferred beyond the startup of the
NVMeSubsystem. The comment justifying the split-loop approach no-longer
seems to make sense, and even if it did at some stage, the delay implied
is quite uncontrolled. Further, the NVMeMi instance will (now) reject
attempts to communicate with the endpoint until its own initialization
process is complete, meaning there will not be any additional bus
contention from subsystem-related traffic.

Change-Id: Id7754d8e45932b7f7db38cce668a8d143c7eea22
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/src/NVMeSensorMain.cpp b/src/NVMeSensorMain.cpp
index 78c7c2a..daa2772 100644
--- a/src/NVMeSensorMain.cpp
+++ b/src/NVMeSensorMain.cpp
@@ -41,7 +41,6 @@
     std::shared_ptr<MctpDevice> dev;
     NVMeIntf intf;
     std::shared_ptr<NVMeSubsystem> subsys;
-    bool enableFeatureLockdown = false;
 };
 
 // a map with key value of {path, NVMeSubsystem}
@@ -287,15 +286,6 @@
     // Initialize banned i2c bus info on every configuration change
     initBannedI2cBus();
 
-    /* We perform two iterations for configurations here. The first iteration is
-     * to set up NVMeIntf. The second iter is to setup NVMe subsystem.
-     *
-     * The reason to seperate these two processes is NVMeIntf initialization of
-     * NVMeMI is via MCTPd, from which the mctp control msg should be relatively
-     * short and should not be delayed by NVMe-MI protocol msg from NVMe
-     * subsystem.
-     */
-    std::map<std::string, NVMeDevice> updatedDevices;
     for (const auto& [nvmeObjectPath, configData] : nvmeConfigurations)
     {
         // find base configuration
@@ -377,15 +367,18 @@
                 NVMeIntf nvmeIntf = NVMeIntf::create<NVMeBasic>(io, *busNumber,
                                                                 *address);
 
-                NVMeDevice dev{{}, nvmeIntf, {}, enableFeatureLockdown};
-                updatedDevices.emplace(nvmeObjectPath, std::move(dev));
+                auto nvmeSubsys = NVMeSubsystem::create(
+                    io, objectServer, dbusConnection, nvmeObjectPath,
+                    *sensorName, configData, nvmeIntf, enableFeatureLockdown);
+                nvmeSubsys->start();
+                NVMeDevice dev{{}, nvmeIntf, nvmeSubsys};
+                nvmeDevices.emplace(nvmeObjectPath, std::move(dev));
             }
             catch (std::exception& ex)
             {
                 lg2::error(
                     "Failed to add nvme basic interface for '{PATH}': {ERROR}",
                     "PATH", nvmeObjectPath.str, "ERROR", ex.what());
-                continue;
             }
         }
         else if (*nvmeProtocol == "mi_i2c")
@@ -443,75 +436,28 @@
 
                 NVMeIntf nvmeIntf = NVMeIntf::create<NVMeMi>(
                     io, dbusConnection, mctpDev, worker, powerState);
+                auto nvmeSubsys = NVMeSubsystem::create(
+                    io, objectServer, dbusConnection, nvmeObjectPath,
+                    *sensorName, configData, nvmeIntf, enableFeatureLockdown);
 
-                // Create a partial NVMeDevice entry in the temporary
-                // updatedDevices map
-                NVMeDevice nvmeDev{
-                    mctpDev, nvmeIntf, {}, enableFeatureLockdown};
-                updatedDevices.emplace(nvmeObjectPath, std::move(nvmeDev));
+                NVMeDevice nvmeDev{mctpDev, nvmeIntf, nvmeSubsys};
+                nvmeDevices.emplace(nvmeObjectPath, std::move(nvmeDev));
+                nvmeSubsys->start();
+                auto timer = std::make_shared<boost::asio::steady_timer>(
+                    io, std::chrono::seconds(5));
+                setupMctpDevice(mctpDev,
+                                std::get<std::shared_ptr<NVMeMiIntf>>(
+                                    nvmeIntf.getInferface()),
+                                nvmeSubsys, timer);
             }
             catch (std::exception& ex)
             {
                 lg2::error(
                     "Failed to add nvme mi interface for '{PATH}': {ERROR}",
                     "PATH", nvmeObjectPath.str, "ERROR", ex.what());
-                continue;
             }
         }
     }
-
-    for (const auto& [interfacePath, configData] : nvmeConfigurations)
-    {
-        // find base configuration
-        auto sensorBase =
-            configData.find(configInterfaceName(nvme::sensorType));
-        if (sensorBase == configData.end())
-        {
-            continue;
-        }
-
-        const SensorBaseConfigMap& sensorConfig = sensorBase->second;
-
-        std::optional<std::string> sensorName = extractName(interfacePath,
-                                                            sensorConfig);
-
-        auto find = updatedDevices.find(interfacePath);
-        if (find == updatedDevices.end())
-        {
-            continue;
-        }
-        try
-        {
-            bool lockdownFeature = find->second.enableFeatureLockdown;
-
-            auto nvmeSubsys = NVMeSubsystem::create(
-                io, objectServer, dbusConnection, interfacePath, *sensorName,
-                configData, find->second.intf, lockdownFeature);
-            // Complete the NVMeDevice entry with its subsystem and record it in
-            // the persistent nvmeDeviceMap
-            find->second.subsys = nvmeSubsys;
-            auto [entry, _] = nvmeDevices.emplace(interfacePath,
-                                                  std::move(find->second));
-            auto nvmeDev = entry->second;
-            nvmeSubsys->start();
-            if (nvmeDev.intf.getProtocol() != NVMeIntf::Protocol::NVMeMI)
-            {
-                continue;
-            }
-
-            auto miIntf = std::get<std::shared_ptr<NVMeMiIntf>>(
-                nvmeDev.intf.getInferface());
-            auto timer = std::make_shared<boost::asio::steady_timer>(
-                io, std::chrono::seconds(5));
-            setupMctpDevice(nvmeDev.dev, miIntf, nvmeSubsys, timer);
-        }
-        catch (std::exception& ex)
-        {
-            lg2::error("Failed to add nvme subsystem for '{PATH}': {ERROR}",
-                       "PATH", std::string(interfacePath), "ERROR", ex.what());
-            continue;
-        }
-    }
 }
 
 void createNVMeSubsystems(