serialize: Add version purpose
Add store/restore of the version purpose. Only need to store it if the
activation was successful, since those are the only versions that are
restored after BMC reboot.
Tested: Verified a code update with an image of purpose System got its
value restored instead of being set to BMC by default.
Change-Id: I6414e9f3b992a8c29046b4d3a3d581c20a166cee
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/activation.cpp b/activation.cpp
index 0c18821..2966b2f 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -134,6 +134,9 @@
{
activationProgress->progress(90);
+ storePurpose(
+ versionId,
+ parent.versions.find(versionId)->second->purpose());
if (!redundancyPriority)
{
redundancyPriority = std::make_unique<RedundancyPriority>(
@@ -188,6 +191,8 @@
flashWrite();
+ storePurpose(versionId,
+ parent.versions.find(versionId)->second->purpose());
if (!redundancyPriority)
{
redundancyPriority =
diff --git a/item_updater.cpp b/item_updater.cpp
index 7fc9fa3..2cd9c39 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -190,6 +190,8 @@
}
auto purpose = server::Version::VersionPurpose::BMC;
+ restorePurpose(id, purpose);
+
auto path = fs::path(SOFTWARE_OBJPATH) / id;
// Create functional association if this is the functional
diff --git a/item_updater.hpp b/item_updater.hpp
index 4a4d1b4..52607bc 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -148,6 +148,10 @@
*/
void freeSpace(Activation& caller);
+ /** @brief Persistent map of Version D-Bus objects and their
+ * version id */
+ std::map<std::string, std::unique_ptr<VersionClass>> versions;
+
private:
/** @brief Callback function for Software.Version match.
* @details Creates an Activation D-Bus object.
@@ -208,10 +212,6 @@
* version id */
std::map<std::string, std::unique_ptr<Activation>> activations;
- /** @brief Persistent map of Version D-Bus objects and their
- * version id */
- std::map<std::string, std::unique_ptr<VersionClass>> versions;
-
/** @brief sdbusplus signal match for Software.Version */
sdbusplus::bus::match_t versionMatch;
diff --git a/serialize.cpp b/serialize.cpp
index 483cd7a..31ac971 100644
--- a/serialize.cpp
+++ b/serialize.cpp
@@ -19,6 +19,7 @@
namespace fs = std::experimental::filesystem;
const std::string priorityName = "priority";
+const std::string purposeName = "purpose";
void storePriority(const std::string& versionId, uint8_t priority)
{
@@ -41,6 +42,27 @@
oarchive(cereal::make_nvp(priorityName, priority));
}
+void storePurpose(const std::string& versionId, VersionPurpose purpose)
+{
+ auto path = fs::path(PERSIST_DIR) / versionId;
+ if (!fs::is_directory(path))
+ {
+ if (fs::exists(path))
+ {
+ // Delete if it's a non-directory file
+ log<level::WARNING>("Removing non-directory file",
+ entry("PATH=%s", path.c_str()));
+ fs::remove_all(path);
+ }
+ fs::create_directories(path);
+ }
+ path = path / purposeName;
+
+ std::ofstream os(path.c_str());
+ cereal::JSONOutputArchive oarchive(os);
+ oarchive(cereal::make_nvp(purposeName, purpose));
+}
+
bool restorePriority(const std::string& versionId, uint8_t& priority)
{
auto path = fs::path(PERSIST_DIR) / versionId / priorityName;
@@ -100,6 +122,27 @@
return false;
}
+bool restorePurpose(const std::string& versionId, VersionPurpose& purpose)
+{
+ auto path = fs::path(PERSIST_DIR) / versionId / purposeName;
+ if (fs::exists(path))
+ {
+ std::ifstream is(path.c_str(), std::ios::in);
+ try
+ {
+ cereal::JSONInputArchive iarchive(is);
+ iarchive(cereal::make_nvp(purposeName, purpose));
+ return true;
+ }
+ catch (cereal::Exception& e)
+ {
+ fs::remove_all(path);
+ }
+ }
+
+ return false;
+}
+
void removePersistDataDirectory(const std::string& versionId)
{
auto path = fs::path(PERSIST_DIR) / versionId;
diff --git a/serialize.hpp b/serialize.hpp
index 9a9df09..08fc504 100644
--- a/serialize.hpp
+++ b/serialize.hpp
@@ -2,6 +2,8 @@
#include "config.h"
+#include "version.hpp"
+
#include <experimental/filesystem>
namespace phosphor
@@ -12,6 +14,8 @@
{
namespace fs = std::experimental::filesystem;
+using VersionPurpose =
+ sdbusplus::xyz::openbmc_project::Software::server::Version::VersionPurpose;
/** @brief Serialization function - stores priority information to file
* @param[in] versionId - The version for which to store information.
@@ -19,6 +23,12 @@
**/
void storePriority(const std::string& versionId, uint8_t priority);
+/** @brief Serialization function - stores purpose information to file
+ * @param[in] versionId - The version for which to store information.
+ * @param[in] purpose - VersionPurpose value for that version.
+ **/
+void storePurpose(const std::string& versionId, VersionPurpose purpose);
+
/** @brief Serialization function - restores priority information from file
* @param[in] versionId - The version for which to retrieve information.
* @param[in] priority - RedundancyPriority reference for that version.
@@ -26,6 +36,13 @@
**/
bool restorePriority(const std::string& versionId, uint8_t& priority);
+/** @brief Serialization function - restores purpose information from file
+ * @param[in] versionId - The version for which to retrieve information.
+ * @param[in] purpose - VersionPurpose reference for that version.
+ * @return true if restore was successful, false if not
+ **/
+bool restorePurpose(const std::string& versionId, VersionPurpose& purpose);
+
/** @brief Removes the serial directory for a given version.
* @param[in] versionId - The version for which to remove a file, if it exists.
**/