BMC: Restore version and activation dbus objects on BMC reboot.
- Read the /media/ dir for active bmc versions. Each active
version has a /etc/os-release inside /media/ which is used to
recreate the version and activation objects.
Resolves openbmc/openbmc#2137
Change-Id: I40e97396b0912095868172a5a6566e2189a3446b
Signed-off-by: Saqib Khan <khansa@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index aa072ef..7d7df3f 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -145,40 +145,88 @@
void ItemUpdater::processBMCImage()
{
- using VersionClass = phosphor::software::manager::Version;
-
- auto purpose = server::Version::VersionPurpose::BMC;
- auto version = phosphor::software::manager::Version::getBMCVersion();
- auto id = phosphor::software::manager::Version::getId(version);
- auto path = std::string{SOFTWARE_OBJPATH} + '/' + id;
-
// Create an association to the BMC inventory item
AssociationList associations{(std::make_tuple(
ACTIVATION_FWD_ASSOCIATION,
ACTIVATION_REV_ASSOCIATION,
bmcInventoryPath))};
- activations.insert(std::make_pair(
- id,
- std::make_unique<Activation>(
- bus,
- path,
- *this,
- id,
- server::Activation::Activations::Active,
- associations)));
- versions.insert(std::make_pair(
- id,
- std::make_unique<VersionClass>(
+ // Read os-release from folders under /media/ to get
+ // BMC Software Versions.
+ for(const auto& iter : fs::directory_iterator(MEDIA_DIR))
+ {
+ auto activationState = server::Activation::Activations::Active;
+ static const auto BMC_RO_PREFIX_LEN = strlen(BMC_RO_PREFIX);
+
+ // Check if the BMC_RO_PREFIXis the prefix of the iter.path
+ if (0 == iter.path().native().compare(0, BMC_RO_PREFIX_LEN,
+ BMC_RO_PREFIX))
+ {
+ auto osRelease = iter.path() / OS_RELEASE_FILE;
+ if (!fs::is_regular_file(osRelease))
+ {
+ log<level::ERR>("Failed to read osRelease\n",
+ entry("FileName=%s", osRelease.string()));
+ activationState = server::Activation::Activations::Invalid;
+ }
+ auto version =
+ phosphor::software::manager::Version::
+ getBMCVersion(osRelease);
+ if (version.empty())
+ {
+ log<level::ERR>("Failed to read version from osRelease",
+ entry("FILENAME=%s", osRelease.string()));
+ activationState = server::Activation::Activations::Invalid;
+ }
+ // The versionId is extracted from the path
+ // for example /media/ro-2a1022fe
+ auto id = iter.path().native().substr(BMC_RO_PREFIX_LEN);
+ auto purpose = server::Version::VersionPurpose::BMC;
+ auto path = fs::path(SOFTWARE_OBJPATH) / id;
+
+ // Create Activation instance for this version.
+ activations.insert(std::make_pair(
+ id,
+ std::make_unique<Activation>(
+ bus,
+ path,
+ *this,
+ id,
+ server::Activation::Activations::Active,
+ associations)));
+
+ // If Active, create RedundancyPriority instance for this version.
+ if (activationState == server::Activation::Activations::Active)
+ {
+ uint8_t priority = std::numeric_limits<uint8_t>::max();
+ if (!restoreFromFile(id, priority))
+ {
+ log<level::ERR>("Unable to restore priority from file.",
+ entry("VERSIONID=%s", id));
+ }
+ activations.find(id)->second->redundancyPriority =
+ std::make_unique<RedundancyPriority>(
bus,
path,
- version,
- purpose,
- "",
- std::bind(&ItemUpdater::erase,
+ *(activations.find(id)->second),
+ priority);
+ }
+
+ // Create Version instance for this version.
+ versions.insert(std::make_pair(
+ id,
+ std::make_unique<
+ phosphor::software::manager::Version>(
+ bus,
+ path,
+ version,
+ purpose,
+ "",
+ std::bind(&ItemUpdater::erase,
this,
std::placeholders::_1))));
-
+ }
+ }
return;
}
@@ -186,6 +234,17 @@
{
// Delete ReadOnly partitions
removeReadOnlyPartition(entryId);
+ removeFile(entryId);
+
+ // Remove the priority environment variable.
+ auto serviceFile = "obmc-flash-bmc-setenv@" + entryId + ".service";
+ auto method = bus.new_method_call(
+ SYSTEMD_BUSNAME,
+ SYSTEMD_PATH,
+ SYSTEMD_INTERFACE,
+ "StartUnit");
+ method.append(serviceFile, "replace");
+ bus.call_noreply(method);
// Removing entry in versions map
auto it = versions.find(entryId);
@@ -212,7 +271,6 @@
// If not, don't continue.
this->activations.erase(entryId);
- removeFile(entryId);
}
ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(