Call freeSpace() function before update
Add new function to delete version objects as part of the Activation.
The code update service automatically removes the ubi volumes to make
space, but it does not remove the dbus object associated with the
removed volume. The side effect of leaving the dbus object is that
when freePriority() is called at the end of the Activation, a new
priority value is assigned to all version dbus objects (including the
deleted one) which fills up the u-boot environment variables.
Tested: Verified that after an Activation, there were only 2 priority
values in the u-boot env variables instead of 3, and they corresponded
to existing volumes.
Change-Id: I41a7ea95eeea1c8a2cb8ce4b41671e77f5c42cac
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/activation.cpp b/activation.cpp
index de7d982..8f7d8a1 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -51,6 +51,8 @@
{
if (rwVolumeCreated == false && roVolumeCreated == false)
{
+ parent.freeSpace();
+
if (!activationProgress)
{
activationProgress = std::make_unique<ActivationProgress>(bus,
diff --git a/configure.ac b/configure.ac
index 749f537..bb53edd 100755
--- a/configure.ac
+++ b/configure.ac
@@ -108,6 +108,11 @@
AS_IF([test "x$MANIFEST_FILE_NAME" == "x"], [MANIFEST_FILE_NAME="MANIFEST"])
AC_DEFINE_UNQUOTED([MANIFEST_FILE_NAME], ["$MANIFEST_FILE_NAME"], [The name of the MANIFEST file])
+AC_ARG_VAR(ACTIVE_BMC_MAX_ALLOWED, [The maximum allowed active BMC versions])
+AS_IF([test "x$ACTIVE_BMC_MAX_ALLOWED" == "x"], [ACTIVE_BMC_MAX_ALLOWED=2])
+AC_DEFINE_UNQUOTED([ACTIVE_BMC_MAX_ALLOWED], [$ACTIVE_BMC_MAX_ALLOWED],
+ [The maximum allowed active BMC versions])
+
AC_DEFINE(BUSNAME_UPDATER, "xyz.openbmc_project.Software.BMC.Updater",
[The item updater DBus busname to own.])
diff --git a/item_updater.cpp b/item_updater.cpp
index e4c9e9c..1596a4b 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -1,4 +1,5 @@
#include <fstream>
+#include <queue>
#include <set>
#include <string>
#include <phosphor-logging/log.hpp>
@@ -658,6 +659,44 @@
updateUbootEnvVars(lowestPriorityVersion);
}
+void ItemUpdater::freeSpace()
+{
+ // Versions with the highest priority in front
+ std::priority_queue<std::pair<int, std::string>,
+ std::vector<std::pair<int, std::string>>,
+ std::less<std::pair<int, std::string>>> versionsPQ;
+
+ std::size_t count = 0;
+ for (const auto& iter : activations)
+ {
+ if ((iter.second.get()->activation() ==
+ server::Activation::Activations::Active) ||
+ (iter.second.get()->activation() ==
+ server::Activation::Activations::Failed))
+ {
+ count++;
+ // Don't put the functional version on the queue since we can't
+ // remove the "running" BMC version.
+ if (versions.find(iter.second->versionId)->second->isFunctional())
+ {
+ continue;
+ }
+ versionsPQ.push(std::make_pair(
+ iter.second->redundancyPriority.get()->priority(),
+ iter.second->versionId));
+ }
+ }
+
+ // If the number of BMC versions is over ACTIVE_BMC_MAX_ALLOWED -1,
+ // remove the highest priority one(s).
+ while ((count >= ACTIVE_BMC_MAX_ALLOWED) && (!versionsPQ.empty()))
+ {
+ erase(versionsPQ.top().second);
+ versionsPQ.pop();
+ count--;
+ }
+}
+
} // namespace updater
} // namespace software
} // namespace phosphor
diff --git a/item_updater.hpp b/item_updater.hpp
index ea88c4b..61be15d 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -130,6 +130,15 @@
*/
void resetUbootEnvVars();
+ /** @brief Brings the total number of active BMC versions to
+ * ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be
+ * run before activating a new BMC version. If this function
+ * needs to delete any BMC version(s) it will delete the
+ * version(s) with the highest priority, skipping the
+ * functional BMC version.
+ */
+ void freeSpace();
+
private:
/** @brief Callback function for Software.Version match.
* @details Creates an Activation D-Bus object.