blob: d96bf0b8e26f6699312668c86a52f9ab35b9589c [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 +
Adriana Kobylak70dcb632018-02-27 15:46:52 -060043 "\\x3d" + std::to_string(priority) + ".service";
44 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
45 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritz40ecdb62017-11-20 16:56:41 -060046 method.append(serviceFile, "replace");
47 bus.call_noreply(method);
Michael Tritz60bc20f2017-07-29 23:32:21 -050048}
49
Michael Tritz36417922017-08-04 14:00:29 -050050bool restoreFromFile(std::string versionId, uint8_t& priority)
Michael Tritz60bc20f2017-07-29 23:32:21 -050051{
Michael Tritz4fb952c2017-08-13 14:55:04 -050052 auto varPath = PERSIST_DIR + versionId;
53 if (fs::exists(varPath))
Michael Tritz60bc20f2017-07-29 23:32:21 -050054 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050055 std::ifstream varInput(varPath.c_str(), std::ios::in);
Michael Tritz36417922017-08-04 14:00:29 -050056 try
57 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050058 cereal::JSONInputArchive varArchive(varInput);
59 varArchive(cereal::make_nvp("priority", priority));
Michael Tritz36417922017-08-04 14:00:29 -050060 return true;
61 }
Gunnar Millse7ff6452017-09-21 16:19:36 -050062 catch (cereal::RapidJSONException& e)
Michael Tritz36417922017-08-04 14:00:29 -050063 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050064 fs::remove(varPath);
65 }
66 }
67
68 auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
69 if (fs::exists(rwPath))
70 {
71 std::ifstream rwInput(rwPath.c_str(), std::ios::in);
72 try
73 {
74 cereal::JSONInputArchive rwArchive(rwInput);
75 rwArchive(cereal::make_nvp("priority", priority));
76 return true;
77 }
Gunnar Millse7ff6452017-09-21 16:19:36 -050078 catch (cereal::RapidJSONException& e)
Michael Tritz4fb952c2017-08-13 14:55:04 -050079 {
80 fs::remove(rwPath);
Michael Tritz36417922017-08-04 14:00:29 -050081 }
Michael Tritz60bc20f2017-07-29 23:32:21 -050082 }
Michael Tritz40ecdb62017-11-20 16:56:41 -060083
84 try
85 {
86 std::string devicePath = "/dev/mtd/u-boot-env";
87
88 if (fs::exists(devicePath) && !devicePath.empty())
89 {
90 std::ifstream input(devicePath.c_str());
91 std::string envVars;
92 std::getline(input, envVars);
93
94 std::string versionVar = "pnor-" + versionId + "=";
95 auto varPosition = envVars.find(versionVar);
96
97 if (varPosition != std::string::npos)
98 {
99 // Grab the environment variable for this versionId. These
100 // variables follow the format "pnor-[versionId]=[priority]\0"
101 auto var = envVars.substr(varPosition);
102 priority = std::stoi(var.substr(versionVar.length()));
103 return true;
104 }
105 }
106 }
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600107 catch (const std::exception& e)
108 {
109 }
Michael Tritz40ecdb62017-11-20 16:56:41 -0600110
Michael Tritz36417922017-08-04 14:00:29 -0500111 return false;
Michael Tritz60bc20f2017-07-29 23:32:21 -0500112}
113
114void removeFile(std::string versionId)
115{
Michael Tritz40ecdb62017-11-20 16:56:41 -0600116 auto bus = sdbusplus::bus::new_default();
117
118 // Clear the environment variable pnor-[versionId].
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600119 std::string serviceFile =
120 "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + ".service";
121 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
122 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritz40ecdb62017-11-20 16:56:41 -0600123 method.append(serviceFile, "replace");
124 bus.call_noreply(method);
125
126 // Delete the file /var/lib/obmc/openpower-pnor-code-mgmt/[versionId].
127 // Note that removeFile() is called in the case of a version being deleted,
128 // so the file /media/pnor-rw-[versionId]/[versionId] will also be deleted
129 // along with its surrounding directory.
Michael Tritz60bc20f2017-07-29 23:32:21 -0500130 std::string path = PERSIST_DIR + versionId;
131 if (fs::exists(path))
132 {
133 fs::remove(path);
134 }
135}
136
137} // namespace updater
138} // namespace software
139} // namespace openpower