Determine functional versions from mount directory

In order to support the same version on the primary and backup flash
locations, the version string is not enough to determine which version
is functional. Therefore add a functional suffix to the mount directory
of the functional and use that to set the Version as functional.

Tested: The mount directories indicate which version is functional,
associations look correct.

- static:
root@romulus:~# ls -l /run/media/rofs-79139bc0-functional/etc/
lrwxrwxrwx    1 root     root            15 Jan 22 20:11 os-release ->
/etc/os-release

root@romulus:~# busctl call xyz.openbmc_project.ObjectMapper
/xyz/openbmc_project/software/functional org.freedesktop.DBus.Properties
Get ss xyz.openbmc_project.Association endpoints
v as 1 "/xyz/openbmc_project/software/79139bc0"

- ubi
root@witherspoon:~# df
/dev/ubiblock0_0         18816     18816         0 100% /media/rofs-cfb85943-functional
/dev/ubiblock4_0         18816     18816         0 100% /media/rofs-26085328

- mmc:
Verified functional association is correct, the rofs directories are
still unmounted after the bmc updater starts.

Change-Id: I8114a86b36ca1c6b1634b01fcce3cef0a2369eca
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 94de753..9309a3f 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -172,8 +172,8 @@
         return;
     }
 
-    // Read os-release from /etc/ to get the functional BMC version
-    auto functionalVersion = VersionClass::getBMCVersion(OS_RELEASE_FILE);
+    // Functional images are mounted as rofs-<location>-functional
+    constexpr auto functionalSuffix = "-functional";
 
     // Read os-release from folders under /media/ to get
     // BMC Software Versions.
@@ -229,6 +229,14 @@
 
             // The flash location is part of the mount name: rofs-<location>
             auto flashId = iter.path().native().substr(BMC_RO_PREFIX_LEN);
+            auto functional = false;
+            if (iter.path().native().find(functionalSuffix) !=
+                std::string::npos)
+            {
+                // Set functional to true and remove the functional suffix
+                functional = true;
+                flashId.erase(flashId.length() - strlen(functionalSuffix));
+            }
 
             auto purpose = server::Version::VersionPurpose::BMC;
             restorePurpose(flashId, purpose);
@@ -241,7 +249,7 @@
 
             // Create functional association if this is the functional
             // version
-            if (version.compare(functionalVersion) == 0)
+            if (functional)
             {
                 createFunctionalAssociation(path);
             }
@@ -267,8 +275,11 @@
             auto versionPtr = std::make_unique<VersionClass>(
                 bus, path, version, purpose, extendedVersion, flashId,
                 std::bind(&ItemUpdater::erase, this, std::placeholders::_1));
-            auto isVersionFunctional = versionPtr->isFunctional();
-            if (!isVersionFunctional)
+            if (functional)
+            {
+                versionPtr->setFunctional(true);
+            }
+            else
             {
                 versionPtr->deleteObject =
                     std::make_unique<phosphor::software::manager::Delete>(
@@ -288,7 +299,7 @@
                 uint8_t priority = std::numeric_limits<uint8_t>::max();
                 if (!restorePriority(flashId, priority))
                 {
-                    if (isVersionFunctional)
+                    if (functional)
                     {
                         priority = 0;
                     }
@@ -308,20 +319,21 @@
     }
 
     // If there are no bmc versions mounted under MEDIA_DIR, then read the
-    // /etc/os-release and create rofs-<versionId> under MEDIA_DIR, then call
-    // again processBMCImage() to create the D-Bus interface for it.
+    // /etc/os-release and create rofs-<versionId>-functional under MEDIA_DIR,
+    // then call again processBMCImage() to create the D-Bus interface for it.
     if (activations.size() == 0)
     {
         auto version = VersionClass::getBMCVersion(OS_RELEASE_FILE);
         auto id = phosphor::software::manager::Version::getId(version);
-        auto versionFileDir = BMC_ROFS_PREFIX + id + "/etc/";
+        auto versionFileDir = BMC_ROFS_PREFIX + id + functionalSuffix + "/etc/";
         try
         {
             if (!fs::is_directory(versionFileDir))
             {
                 fs::create_directories(versionFileDir);
             }
-            auto versionFilePath = BMC_ROFS_PREFIX + id + OS_RELEASE_FILE;
+            auto versionFilePath =
+                BMC_ROFS_PREFIX + id + functionalSuffix + OS_RELEASE_FILE;
             fs::create_directory_symlink(OS_RELEASE_FILE, versionFilePath);
             ItemUpdater::processBMCImage();
         }