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/serialize.cpp b/serialize.cpp
index 8c97c89..da9e878 100644
--- a/serialize.cpp
+++ b/serialize.cpp
@@ -3,6 +3,7 @@
#include <cereal/archives/json.hpp>
#include <fstream>
#include "serialize.hpp"
+#include <sdbusplus/server.hpp>
namespace phosphor
{
@@ -15,6 +16,8 @@
void storeToFile(std::string versionId, uint8_t priority)
{
+ auto bus = sdbusplus::bus::new_default();
+
if(!fs::is_directory(PERSIST_DIR))
{
fs::create_directory(PERSIST_DIR);
@@ -24,17 +27,69 @@
std::ofstream os(path.c_str());
cereal::JSONOutputArchive oarchive(os);
oarchive(cereal::make_nvp("priority", priority));
+
+ std::string serviceFile = "obmc-flash-bmc-setenv@" + 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);
}
-void restoreFromFile(std::string versionId, uint8_t& priority)
+bool restoreFromFile(std::string versionId, uint8_t& priority)
{
std::string path = PERSIST_DIR + versionId;
if (fs::exists(path))
{
std::ifstream is(path.c_str(), std::ios::in);
- cereal::JSONInputArchive iarchive(is);
- iarchive(cereal::make_nvp("priority", priority));
+ try
+ {
+ cereal::JSONInputArchive iarchive(is);
+ iarchive(cereal::make_nvp("priority", priority));
+ return true;
+ }
+ catch(cereal::RapidJSONException& e)
+ {
+ fs::remove(path);
+ }
}
+
+ // Find the mtd device "u-boot-env" to retrieve the environment variables
+ std::ifstream mtdDevices("/proc/mtd");
+ std::string device, devicePath;
+
+ try
+ {
+ while (std::getline(mtdDevices, device)) {
+ if (device.find("u-boot-env") != std::string::npos)
+ {
+ devicePath = "/dev/" + device.substr(0, device.find(':'));
+ break;
+ }
+ }
+
+ if (!devicePath.empty())
+ {
+ std::ifstream input(devicePath.c_str());
+ std::string envVars;
+ std::getline(input, envVars);
+
+ if (envVars.find(versionId) != std::string::npos)
+ {
+ // Grab the environment variable for this versionId. These
+ // variables follow the format "versionId=priority\0"
+ auto var = envVars.substr(envVars.find(versionId));
+ priority = std::stoi(var.substr(var.find('=') + 1));
+ return true;
+ }
+ }
+ }
+ catch (const std::exception& e){}
+
+ return false;
}
void removeFile(std::string versionId)