Create functional association on startup

Look at /var/lib/phosphor-software-manager/pnor/ro
to determine if there is a funcitonal image, if so
create a functional association.

Resolves openbmc/openbmc#2279

Change-Id: I6e576e2e21a592a98d843eb45cdab8bba8f55192
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 261b9d6..b451932 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -250,6 +250,13 @@
                                      *this)));
         }
     }
+
+    // Look at the RO symlink to determine if there is a functional image
+    auto id = determineId(PNOR_RO_ACTIVE_PATH);
+    if (!id.empty())
+    {
+        updateFunctionalAssociation(std::string{SOFTWARE_OBJPATH} + '/' + id);
+    }
     return;
 }
 
@@ -559,6 +566,26 @@
     }
 }
 
+std::string ItemUpdater::determineId(const std::string& symlinkPath)
+{
+    if (!fs::exists(symlinkPath))
+    {
+        return {};
+    }
+
+    auto target = fs::canonical(symlinkPath).string();
+
+    // check to make sure the target really exists
+    if (!fs::is_regular_file(target + "/" + PNOR_TOC_FILE))
+    {
+        return {};
+    }
+    // Get the image <id> from the symlink target
+    // for example /media/ro-2a1022fe
+    static const auto PNOR_RO_PREFIX_LEN = strlen(PNOR_RO_PREFIX);
+    return target.substr(PNOR_RO_PREFIX_LEN);
+}
+
 } // namespace updater
 } // namespace software
 } // namespace openpower