processBMCImage: Dynamically calculate version id

With the UBI layout, the name of the mount directories have the
version id because the UBI volume names have the id so it's
easy to get.

With other layouts where static partition names are used, the id
is not part of the partition name so it can only be calculated
from the version string, which requires to mount the filesystem
to read it from the os-release file.

Change the logic to have processBMCImage() calculate the id from
the version string for each mounted filesystem instead of the
mount directory name, as long as the mount directory name starts
with BMC_ROFS_PREFIX, ex: /media/rofs-a. The current UBI mount
directory names rofs-<id> continue to work, just the directory
name is not used anymore to get the id.

If the os-release file is not found or does not contain a version
string, assume it's corrupted and attempt to get the id from the
mount directory name.

Tested: Verified in witherspoon that the d-bus objects are
        created with the expected version ids.

Change-Id: Iff0103c9cbd060c7fb49ff29c48a72f2873f0f32
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 71ed3fd..3ee85b2 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -175,9 +175,7 @@
         if (0 ==
             iter.path().native().compare(0, BMC_RO_PREFIX_LEN, BMC_ROFS_PREFIX))
         {
-            // The versionId is extracted from the path
-            // for example /media/ro-2a1022fe.
-            auto id = iter.path().native().substr(BMC_RO_PREFIX_LEN);
+            // Get the version to calculate the id
             fs::path releaseFile(OS_RELEASE_FILE);
             auto osRelease = iter.path() / releaseFile.relative_path();
             if (!fs::is_regular_file(osRelease))
@@ -185,7 +183,15 @@
                 log<level::ERR>(
                     "Failed to read osRelease",
                     entry("FILENAME=%s", osRelease.string().c_str()));
+
+                // Try to get the version id from the mount directory name and
+                // call to delete it as this version may be corrupted. Dynamic
+                // volumes created by the UBI layout for example have the id in
+                // the mount directory name. The worst that can happen is that
+                // erase() is called with an non-existent id and returns.
+                auto id = iter.path().native().substr(BMC_RO_PREFIX_LEN);
                 ItemUpdater::erase(id);
+
                 continue;
             }
             auto version = VersionClass::getBMCVersion(osRelease);
@@ -194,9 +200,17 @@
                 log<level::ERR>(
                     "Failed to read version from osRelease",
                     entry("FILENAME=%s", osRelease.string().c_str()));
-                activationState = server::Activation::Activations::Invalid;
+
+                // Try to delete the version, same as above if the
+                // OS_RELEASE_FILE does not exist.
+                auto id = iter.path().native().substr(BMC_RO_PREFIX_LEN);
+                ItemUpdater::erase(id);
+
+                continue;
             }
 
+            auto id = VersionClass::getId(version);
+
             auto purpose = server::Version::VersionPurpose::BMC;
             restorePurpose(id, purpose);
 
@@ -269,8 +283,9 @@
         }
     }
 
-    // If there is no ubi volume for bmc version then read the /etc/os-release
-    // and create rofs-<versionId> under /media
+    // 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.
     if (activations.size() == 0)
     {
         auto version = VersionClass::getBMCVersion(OS_RELEASE_FILE);