Refactor: Move serialize to ubi
Functions in serialize are specific to UBI, move it to ubi dir.
Tested: On the last commit of the patch series, run code update and
factory reset on Witherspoon and all work fine.
Change-Id: I9176e638d9f3bfe0d424b57f8da4667a751cb5bd
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/ubi/Makefile.am.include b/ubi/Makefile.am.include
index c75293d..decf1e9 100644
--- a/ubi/Makefile.am.include
+++ b/ubi/Makefile.am.include
@@ -1,4 +1,5 @@
openpower_update_manager_SOURCES += \
%reldir%/activation_ubi.cpp \
%reldir%/item_updater_ubi.cpp \
+ %reldir%/serialize.cpp \
%reldir%/watch.cpp
diff --git a/ubi/serialize.cpp b/ubi/serialize.cpp
new file mode 100644
index 0000000..7250a00
--- /dev/null
+++ b/ubi/serialize.cpp
@@ -0,0 +1,141 @@
+#include "config.h"
+
+#include "serialize.hpp"
+
+#include <cereal/archives/json.hpp>
+#include <experimental/filesystem>
+#include <fstream>
+#include <sdbusplus/server.hpp>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+namespace fs = std::experimental::filesystem;
+
+void storeToFile(std::string versionId, uint8_t priority)
+{
+ auto bus = sdbusplus::bus::new_default();
+
+ if (!fs::is_directory(PERSIST_DIR))
+ {
+ fs::create_directories(PERSIST_DIR);
+ }
+
+ // store one copy in /var/lib/obmc/openpower-pnor-code-mgmt/[versionId]
+ auto varPath = PERSIST_DIR + versionId;
+ std::ofstream varOutput(varPath.c_str());
+ cereal::JSONOutputArchive varArchive(varOutput);
+ varArchive(cereal::make_nvp("priority", priority));
+
+ if (fs::is_directory(PNOR_RW_PREFIX + versionId))
+ {
+ // store another copy in /media/pnor-rw-[versionId]/[versionId]
+ auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
+ std::ofstream rwOutput(rwPath.c_str());
+ cereal::JSONOutputArchive rwArchive(rwOutput);
+ rwArchive(cereal::make_nvp("priority", priority));
+ }
+
+ // lastly, store the priority as an environment variable pnor-[versionId]
+ std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId +
+ "\\x3d" + std::to_string(priority) + ".service";
+ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+ method.append(serviceFile, "replace");
+ bus.call_noreply(method);
+}
+
+bool restoreFromFile(std::string versionId, uint8_t& priority)
+{
+ auto varPath = PERSIST_DIR + versionId;
+ if (fs::exists(varPath))
+ {
+ std::ifstream varInput(varPath.c_str(), std::ios::in);
+ try
+ {
+ cereal::JSONInputArchive varArchive(varInput);
+ varArchive(cereal::make_nvp("priority", priority));
+ return true;
+ }
+ catch (cereal::RapidJSONException& e)
+ {
+ fs::remove(varPath);
+ }
+ }
+
+ auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
+ if (fs::exists(rwPath))
+ {
+ std::ifstream rwInput(rwPath.c_str(), std::ios::in);
+ try
+ {
+ cereal::JSONInputArchive rwArchive(rwInput);
+ rwArchive(cereal::make_nvp("priority", priority));
+ return true;
+ }
+ catch (cereal::RapidJSONException& e)
+ {
+ fs::remove(rwPath);
+ }
+ }
+
+ try
+ {
+ std::string devicePath = "/dev/mtd/u-boot-env";
+
+ if (fs::exists(devicePath) && !devicePath.empty())
+ {
+ std::ifstream input(devicePath.c_str());
+ std::string envVars;
+ std::getline(input, envVars);
+
+ std::string versionVar = "pnor-" + versionId + "=";
+ auto varPosition = envVars.find(versionVar);
+
+ if (varPosition != std::string::npos)
+ {
+ // Grab the environment variable for this versionId. These
+ // variables follow the format "pnor-[versionId]=[priority]\0"
+ auto var = envVars.substr(varPosition);
+ priority = std::stoi(var.substr(versionVar.length()));
+ return true;
+ }
+ }
+ }
+ catch (const std::exception& e)
+ {
+ }
+
+ return false;
+}
+
+void removeFile(std::string versionId)
+{
+ auto bus = sdbusplus::bus::new_default();
+
+ // Clear the environment variable pnor-[versionId].
+ std::string serviceFile =
+ "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + ".service";
+ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+ method.append(serviceFile, "replace");
+ bus.call_noreply(method);
+
+ // Delete the file /var/lib/obmc/openpower-pnor-code-mgmt/[versionId].
+ // Note that removeFile() is called in the case of a version being deleted,
+ // so the file /media/pnor-rw-[versionId]/[versionId] will also be deleted
+ // along with its surrounding directory.
+ std::string path = PERSIST_DIR + versionId;
+ if (fs::exists(path))
+ {
+ fs::remove(path);
+ }
+}
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
diff --git a/ubi/serialize.hpp b/ubi/serialize.hpp
new file mode 100644
index 0000000..e8860f3
--- /dev/null
+++ b/ubi/serialize.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <string>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+/** @brief Serialization function - stores activation information to file
+ * @param[in] versionId - The version for which to store information.
+ * @param[in] priority - RedundancyPriority value for that version.
+ */
+void storeToFile(std::string versionId, uint8_t priority);
+
+/** @brief Serialization function - restores activation information from file
+ * @param[in] versionId - The version for which to retrieve information.
+ * @param[in] priority - RedundancyPriority pointer for that version.
+ * @return true if restore was successful, false if not
+ */
+bool restoreFromFile(std::string versionId, uint8_t& priority);
+
+/** @brief Removes the serial file for a given version.
+ * @param[in] versionId - The version for which to remove a file, if it exists.
+ */
+void removeFile(std::string versionId);
+
+} // namespace updater
+} // namespace software
+} // namespace openpower