blob: 5060c9a3ca04dc0c2cbfe98269a378c00ba73f09 [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" +
32 std::to_string(priority) + ".service";
33 auto method = bus.new_method_call(
34 SYSTEMD_BUSNAME,
35 SYSTEMD_PATH,
36 SYSTEMD_INTERFACE,
37 "StartUnit");
38 method.append(serviceFile, "replace");
39 bus.call_noreply(method);
Saqib Khan5d532672017-08-09 10:44:50 -050040}
41
Saqib Khan1eef62d2017-08-10 15:29:34 -050042bool restoreFromFile(std::string versionId, uint8_t& priority)
Saqib Khan5d532672017-08-09 10:44:50 -050043{
44 std::string path = PERSIST_DIR + versionId;
45 if (fs::exists(path))
46 {
47 std::ifstream is(path.c_str(), std::ios::in);
Saqib Khan1eef62d2017-08-10 15:29:34 -050048 try
49 {
50 cereal::JSONInputArchive iarchive(is);
51 iarchive(cereal::make_nvp("priority", priority));
52 return true;
53 }
Gunnar Millsffe04922017-10-06 13:20:43 -050054 catch (cereal::RapidJSONException& e)
Saqib Khan1eef62d2017-08-10 15:29:34 -050055 {
56 fs::remove(path);
57 }
Saqib Khan5d532672017-08-09 10:44:50 -050058 }
Saqib Khan1eef62d2017-08-10 15:29:34 -050059
60 // Find the mtd device "u-boot-env" to retrieve the environment variables
61 std::ifstream mtdDevices("/proc/mtd");
62 std::string device, devicePath;
63
64 try
65 {
Gunnar Millsffe04922017-10-06 13:20:43 -050066 while (std::getline(mtdDevices, device))
67 {
Saqib Khan1eef62d2017-08-10 15:29:34 -050068 if (device.find("u-boot-env") != std::string::npos)
69 {
70 devicePath = "/dev/" + device.substr(0, device.find(':'));
71 break;
72 }
73 }
74
75 if (!devicePath.empty())
76 {
77 std::ifstream input(devicePath.c_str());
78 std::string envVars;
79 std::getline(input, envVars);
80
Michael Tritz6273efd2017-12-14 15:21:18 -060081 std::string versionVar = versionId + "=";
82 auto varPosition = envVars.find(versionVar);
83
84 if (varPosition != std::string::npos)
Saqib Khan1eef62d2017-08-10 15:29:34 -050085 {
86 // Grab the environment variable for this versionId. These
87 // variables follow the format "versionId=priority\0"
Michael Tritz6273efd2017-12-14 15:21:18 -060088 auto var = envVars.substr(varPosition);
89 priority = std::stoi(var.substr(versionVar.length()));
Saqib Khan1eef62d2017-08-10 15:29:34 -050090 return true;
91 }
92 }
93 }
94 catch (const std::exception& e){}
95
96 return false;
Saqib Khan5d532672017-08-09 10:44:50 -050097}
98
99void removeFile(std::string versionId)
100{
101 std::string path = PERSIST_DIR + versionId;
102 if (fs::exists(path))
103 {
104 fs::remove(path);
105 }
106}
107
108} // namespace phosphor
109} // namespace software
110} // namespace openpower