blob: 595a970b379fc98931e06821effbefac243e5ce7 [file] [log] [blame]
Michael Tritz60bc20f2017-07-29 23:32:21 -05001#include "config.h"
2#include <experimental/filesystem>
Michael Tritz5c907112017-08-02 15:25:51 -05003#include <cereal/archives/json.hpp>
Michael Tritz60bc20f2017-07-29 23:32:21 -05004#include <fstream>
5#include "serialize.hpp"
Michael Tritz40ecdb62017-11-20 16:56:41 -06006#include <sdbusplus/server.hpp>
Michael Tritz60bc20f2017-07-29 23:32:21 -05007
8namespace openpower
9{
10namespace software
11{
12namespace updater
13{
14
15namespace fs = std::experimental::filesystem;
16
17void storeToFile(std::string versionId, uint8_t priority)
18{
Michael Tritz40ecdb62017-11-20 16:56:41 -060019 auto bus = sdbusplus::bus::new_default();
20
Gunnar Millse7ff6452017-09-21 16:19:36 -050021 if (!fs::is_directory(PERSIST_DIR))
Michael Tritz60bc20f2017-07-29 23:32:21 -050022 {
Michael Tritz48d9a4e2017-09-18 14:30:46 -050023 fs::create_directories(PERSIST_DIR);
Michael Tritz60bc20f2017-07-29 23:32:21 -050024 }
Michael Tritz60bc20f2017-07-29 23:32:21 -050025
Michael Tritz4fb952c2017-08-13 14:55:04 -050026 // store one copy in /var/lib/obmc/openpower-pnor-code-mgmt/[versionId]
27 auto varPath = PERSIST_DIR + versionId;
28 std::ofstream varOutput(varPath.c_str());
29 cereal::JSONOutputArchive varArchive(varOutput);
30 varArchive(cereal::make_nvp("priority", priority));
31
Gunnar Millse7ff6452017-09-21 16:19:36 -050032 if (fs::is_directory(PNOR_RW_PREFIX + versionId))
Michael Tritz4fb952c2017-08-13 14:55:04 -050033 {
34 // store another copy in /media/pnor-rw-[versionId]/[versionId]
35 auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
36 std::ofstream rwOutput(rwPath.c_str());
37 cereal::JSONOutputArchive rwArchive(rwOutput);
38 rwArchive(cereal::make_nvp("priority", priority));
39 }
Michael Tritz40ecdb62017-11-20 16:56:41 -060040
41 // lastly, store the priority as an environment variable pnor-[versionId]
42 std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId +
43 "\\x3d" + std::to_string(priority) + ".service";
44 auto method = bus.new_method_call(
45 SYSTEMD_BUSNAME,
46 SYSTEMD_PATH,
47 SYSTEMD_INTERFACE,
48 "StartUnit");
49 method.append(serviceFile, "replace");
50 bus.call_noreply(method);
Michael Tritz60bc20f2017-07-29 23:32:21 -050051}
52
Michael Tritz36417922017-08-04 14:00:29 -050053bool restoreFromFile(std::string versionId, uint8_t& priority)
Michael Tritz60bc20f2017-07-29 23:32:21 -050054{
Michael Tritz4fb952c2017-08-13 14:55:04 -050055 auto varPath = PERSIST_DIR + versionId;
56 if (fs::exists(varPath))
Michael Tritz60bc20f2017-07-29 23:32:21 -050057 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050058 std::ifstream varInput(varPath.c_str(), std::ios::in);
Michael Tritz36417922017-08-04 14:00:29 -050059 try
60 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050061 cereal::JSONInputArchive varArchive(varInput);
62 varArchive(cereal::make_nvp("priority", priority));
Michael Tritz36417922017-08-04 14:00:29 -050063 return true;
64 }
Gunnar Millse7ff6452017-09-21 16:19:36 -050065 catch (cereal::RapidJSONException& e)
Michael Tritz36417922017-08-04 14:00:29 -050066 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050067 fs::remove(varPath);
68 }
69 }
70
71 auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
72 if (fs::exists(rwPath))
73 {
74 std::ifstream rwInput(rwPath.c_str(), std::ios::in);
75 try
76 {
77 cereal::JSONInputArchive rwArchive(rwInput);
78 rwArchive(cereal::make_nvp("priority", priority));
79 return true;
80 }
Gunnar Millse7ff6452017-09-21 16:19:36 -050081 catch (cereal::RapidJSONException& e)
Michael Tritz4fb952c2017-08-13 14:55:04 -050082 {
83 fs::remove(rwPath);
Michael Tritz36417922017-08-04 14:00:29 -050084 }
Michael Tritz60bc20f2017-07-29 23:32:21 -050085 }
Michael Tritz40ecdb62017-11-20 16:56:41 -060086
87 try
88 {
89 std::string devicePath = "/dev/mtd/u-boot-env";
90
91 if (fs::exists(devicePath) && !devicePath.empty())
92 {
93 std::ifstream input(devicePath.c_str());
94 std::string envVars;
95 std::getline(input, envVars);
96
97 std::string versionVar = "pnor-" + versionId + "=";
98 auto varPosition = envVars.find(versionVar);
99
100 if (varPosition != std::string::npos)
101 {
102 // Grab the environment variable for this versionId. These
103 // variables follow the format "pnor-[versionId]=[priority]\0"
104 auto var = envVars.substr(varPosition);
105 priority = std::stoi(var.substr(versionVar.length()));
106 return true;
107 }
108 }
109 }
110 catch (const std::exception& e){}
111
Michael Tritz36417922017-08-04 14:00:29 -0500112 return false;
Michael Tritz60bc20f2017-07-29 23:32:21 -0500113}
114
115void removeFile(std::string versionId)
116{
Michael Tritz40ecdb62017-11-20 16:56:41 -0600117 auto bus = sdbusplus::bus::new_default();
118
119 // Clear the environment variable pnor-[versionId].
120 std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId +
121 ".service";
122 auto method = bus.new_method_call(
123 SYSTEMD_BUSNAME,
124 SYSTEMD_PATH,
125 SYSTEMD_INTERFACE,
126 "StartUnit");
127 method.append(serviceFile, "replace");
128 bus.call_noreply(method);
129
130 // Delete the file /var/lib/obmc/openpower-pnor-code-mgmt/[versionId].
131 // Note that removeFile() is called in the case of a version being deleted,
132 // so the file /media/pnor-rw-[versionId]/[versionId] will also be deleted
133 // along with its surrounding directory.
Michael Tritz60bc20f2017-07-29 23:32:21 -0500134 std::string path = PERSIST_DIR + versionId;
135 if (fs::exists(path))
136 {
137 fs::remove(path);
138 }
139}
140
141} // namespace updater
142} // namespace software
143} // namespace openpower