blob: b59ff466986b9f224984618fd99b1dc9c33e7c26 [file] [log] [blame]
Saqib Khan5d532672017-08-09 10:44:50 -05001#include "config.h"
2#include <experimental/filesystem>
3#include <cereal/archives/json.hpp>
4#include <fstream>
5#include "serialize.hpp"
Saqib Khan1eef62d2017-08-10 15:29:34 -05006#include <sdbusplus/server.hpp>
Saqib Khan5d532672017-08-09 10:44:50 -05007
8namespace phosphor
9{
10namespace software
11{
12namespace updater
13{
14
15namespace fs = std::experimental::filesystem;
16
17void storeToFile(std::string versionId, uint8_t priority)
18{
Saqib Khan1eef62d2017-08-10 15:29:34 -050019 auto bus = sdbusplus::bus::new_default();
20
Gunnar Millsffe04922017-10-06 13:20:43 -050021 if (!fs::is_directory(PERSIST_DIR))
Saqib Khan5d532672017-08-09 10:44:50 -050022 {
Michael Tritz49860e12017-09-18 14:33:54 -050023 fs::create_directories(PERSIST_DIR);
Saqib Khan5d532672017-08-09 10:44:50 -050024 }
25 std::string path = PERSIST_DIR + versionId;
26
27 std::ofstream os(path.c_str());
28 cereal::JSONOutputArchive oarchive(os);
29 oarchive(cereal::make_nvp("priority", priority));
Saqib Khan1eef62d2017-08-10 15:29:34 -050030
31 std::string serviceFile = "obmc-flash-bmc-setenv@" + versionId + "\\x3d" +
Adriana Kobylak2285fe02018-02-27 15:36:59 -060032 std::to_string(priority) + ".service";
33 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
34 SYSTEMD_INTERFACE, "StartUnit");
Saqib Khan1eef62d2017-08-10 15:29:34 -050035 method.append(serviceFile, "replace");
36 bus.call_noreply(method);
Saqib Khan5d532672017-08-09 10:44:50 -050037}
38
Saqib Khan1eef62d2017-08-10 15:29:34 -050039bool restoreFromFile(std::string versionId, uint8_t& priority)
Saqib Khan5d532672017-08-09 10:44:50 -050040{
41 std::string path = PERSIST_DIR + versionId;
42 if (fs::exists(path))
43 {
44 std::ifstream is(path.c_str(), std::ios::in);
Saqib Khan1eef62d2017-08-10 15:29:34 -050045 try
46 {
47 cereal::JSONInputArchive iarchive(is);
48 iarchive(cereal::make_nvp("priority", priority));
49 return true;
50 }
Gunnar Millsffe04922017-10-06 13:20:43 -050051 catch (cereal::RapidJSONException& e)
Saqib Khan1eef62d2017-08-10 15:29:34 -050052 {
53 fs::remove(path);
54 }
Saqib Khan5d532672017-08-09 10:44:50 -050055 }
Saqib Khan1eef62d2017-08-10 15:29:34 -050056
57 // Find the mtd device "u-boot-env" to retrieve the environment variables
58 std::ifstream mtdDevices("/proc/mtd");
59 std::string device, devicePath;
60
61 try
62 {
Gunnar Millsffe04922017-10-06 13:20:43 -050063 while (std::getline(mtdDevices, device))
64 {
Saqib Khan1eef62d2017-08-10 15:29:34 -050065 if (device.find("u-boot-env") != std::string::npos)
66 {
67 devicePath = "/dev/" + device.substr(0, device.find(':'));
68 break;
69 }
70 }
71
72 if (!devicePath.empty())
73 {
74 std::ifstream input(devicePath.c_str());
75 std::string envVars;
76 std::getline(input, envVars);
77
Michael Tritz6273efd2017-12-14 15:21:18 -060078 std::string versionVar = versionId + "=";
79 auto varPosition = envVars.find(versionVar);
80
81 if (varPosition != std::string::npos)
Saqib Khan1eef62d2017-08-10 15:29:34 -050082 {
83 // Grab the environment variable for this versionId. These
84 // variables follow the format "versionId=priority\0"
Michael Tritz6273efd2017-12-14 15:21:18 -060085 auto var = envVars.substr(varPosition);
86 priority = std::stoi(var.substr(versionVar.length()));
Saqib Khan1eef62d2017-08-10 15:29:34 -050087 return true;
88 }
89 }
90 }
Adriana Kobylak2285fe02018-02-27 15:36:59 -060091 catch (const std::exception& e)
92 {
93 }
Saqib Khan1eef62d2017-08-10 15:29:34 -050094
95 return false;
Saqib Khan5d532672017-08-09 10:44:50 -050096}
97
98void removeFile(std::string versionId)
99{
100 std::string path = PERSIST_DIR + versionId;
101 if (fs::exists(path))
102 {
103 fs::remove(path);
104 }
105}
106
Saqib Khan5d532672017-08-09 10:44:50 -0500107} // namespace phosphor
108} // namespace software
109} // namespace openpower