Fix being able to activate a Failed version

When an activation fails, the version is marked as Failed.
On a subsequent activation, the bmc updater core dumps due
to 2 issues during the freeSpace call:
1. The Failed activation doesn't have a Priority object, so
default its priority to a large value.
2. If the subsequent activation is to the same version id,
then freeSpace should not do an erase on it, because that
removes the activations object that it's trying to activate.

Tested: Verified that doing an activation after a version
was marked as Failed did not core dump the updater anymore.

Change-Id: Iba36497b53738e00283cfec55e8c666f943cd5d5
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 0fd2345..90a97d4 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -583,7 +583,7 @@
     updateUbootEnvVars(lowestPriorityVersion);
 }
 
-void ItemUpdater::freeSpace()
+void ItemUpdater::freeSpace(Activation& caller)
 {
     //  Versions with the highest priority in front
     std::priority_queue<std::pair<int, std::string>,
@@ -604,14 +604,25 @@
             // remove the "running" BMC version.
             // If ACTIVE_BMC_MAX_ALLOWED <= 1, there is only one active BMC,
             // so remove functional version as well.
-            if (versions.find(iter.second->versionId)->second->isFunctional() &&
-                ACTIVE_BMC_MAX_ALLOWED > 1)
+            // Don't delete the the Activation object that called this function.
+            if ((versions.find(iter.second->versionId)
+                     ->second->isFunctional() &&
+                 ACTIVE_BMC_MAX_ALLOWED > 1) ||
+                (iter.second->versionId == caller.versionId))
             {
                 continue;
             }
-            versionsPQ.push(std::make_pair(
-                iter.second->redundancyPriority.get()->priority(),
-                iter.second->versionId));
+
+            // Failed activations don't have priority, assign them a large value
+            // for sorting purposes.
+            auto priority = 999;
+            if (iter.second.get()->activation() ==
+                server::Activation::Activations::Active)
+            {
+                priority = iter.second->redundancyPriority.get()->priority();
+            }
+
+            versionsPQ.push(std::make_pair(priority, iter.second->versionId));
         }
     }