blob: 7250a005021363b0448556ada6e9a161a37c6b6e [file] [log] [blame]
Michael Tritz60bc20f2017-07-29 23:32:21 -05001#include "config.h"
Gunnar Millsf6ed5892018-09-07 17:08:02 -05002
Michael Tritz60bc20f2017-07-29 23:32:21 -05003#include "serialize.hpp"
Gunnar Millsf6ed5892018-09-07 17:08:02 -05004
5#include <cereal/archives/json.hpp>
6#include <experimental/filesystem>
7#include <fstream>
Michael Tritz40ecdb62017-11-20 16:56:41 -06008#include <sdbusplus/server.hpp>
Michael Tritz60bc20f2017-07-29 23:32:21 -05009
10namespace openpower
11{
12namespace software
13{
14namespace updater
15{
16
17namespace fs = std::experimental::filesystem;
18
19void storeToFile(std::string versionId, uint8_t priority)
20{
Michael Tritz40ecdb62017-11-20 16:56:41 -060021 auto bus = sdbusplus::bus::new_default();
22
Gunnar Millse7ff6452017-09-21 16:19:36 -050023 if (!fs::is_directory(PERSIST_DIR))
Michael Tritz60bc20f2017-07-29 23:32:21 -050024 {
Michael Tritz48d9a4e2017-09-18 14:30:46 -050025 fs::create_directories(PERSIST_DIR);
Michael Tritz60bc20f2017-07-29 23:32:21 -050026 }
Michael Tritz60bc20f2017-07-29 23:32:21 -050027
Michael Tritz4fb952c2017-08-13 14:55:04 -050028 // store one copy in /var/lib/obmc/openpower-pnor-code-mgmt/[versionId]
29 auto varPath = PERSIST_DIR + versionId;
30 std::ofstream varOutput(varPath.c_str());
31 cereal::JSONOutputArchive varArchive(varOutput);
32 varArchive(cereal::make_nvp("priority", priority));
33
Gunnar Millse7ff6452017-09-21 16:19:36 -050034 if (fs::is_directory(PNOR_RW_PREFIX + versionId))
Michael Tritz4fb952c2017-08-13 14:55:04 -050035 {
36 // store another copy in /media/pnor-rw-[versionId]/[versionId]
37 auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
38 std::ofstream rwOutput(rwPath.c_str());
39 cereal::JSONOutputArchive rwArchive(rwOutput);
40 rwArchive(cereal::make_nvp("priority", priority));
41 }
Michael Tritz40ecdb62017-11-20 16:56:41 -060042
43 // lastly, store the priority as an environment variable pnor-[versionId]
44 std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId +
Adriana Kobylak70dcb632018-02-27 15:46:52 -060045 "\\x3d" + std::to_string(priority) + ".service";
46 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
47 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritz40ecdb62017-11-20 16:56:41 -060048 method.append(serviceFile, "replace");
49 bus.call_noreply(method);
Michael Tritz60bc20f2017-07-29 23:32:21 -050050}
51
Michael Tritz36417922017-08-04 14:00:29 -050052bool restoreFromFile(std::string versionId, uint8_t& priority)
Michael Tritz60bc20f2017-07-29 23:32:21 -050053{
Michael Tritz4fb952c2017-08-13 14:55:04 -050054 auto varPath = PERSIST_DIR + versionId;
55 if (fs::exists(varPath))
Michael Tritz60bc20f2017-07-29 23:32:21 -050056 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050057 std::ifstream varInput(varPath.c_str(), std::ios::in);
Michael Tritz36417922017-08-04 14:00:29 -050058 try
59 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050060 cereal::JSONInputArchive varArchive(varInput);
61 varArchive(cereal::make_nvp("priority", priority));
Michael Tritz36417922017-08-04 14:00:29 -050062 return true;
63 }
Gunnar Millse7ff6452017-09-21 16:19:36 -050064 catch (cereal::RapidJSONException& e)
Michael Tritz36417922017-08-04 14:00:29 -050065 {
Michael Tritz4fb952c2017-08-13 14:55:04 -050066 fs::remove(varPath);
67 }
68 }
69
70 auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
71 if (fs::exists(rwPath))
72 {
73 std::ifstream rwInput(rwPath.c_str(), std::ios::in);
74 try
75 {
76 cereal::JSONInputArchive rwArchive(rwInput);
77 rwArchive(cereal::make_nvp("priority", priority));
78 return true;
79 }
Gunnar Millse7ff6452017-09-21 16:19:36 -050080 catch (cereal::RapidJSONException& e)
Michael Tritz4fb952c2017-08-13 14:55:04 -050081 {
82 fs::remove(rwPath);
Michael Tritz36417922017-08-04 14:00:29 -050083 }
Michael Tritz60bc20f2017-07-29 23:32:21 -050084 }
Michael Tritz40ecdb62017-11-20 16:56:41 -060085
86 try
87 {
88 std::string devicePath = "/dev/mtd/u-boot-env";
89
90 if (fs::exists(devicePath) && !devicePath.empty())
91 {
92 std::ifstream input(devicePath.c_str());
93 std::string envVars;
94 std::getline(input, envVars);
95
96 std::string versionVar = "pnor-" + versionId + "=";
97 auto varPosition = envVars.find(versionVar);
98
99 if (varPosition != std::string::npos)
100 {
101 // Grab the environment variable for this versionId. These
102 // variables follow the format "pnor-[versionId]=[priority]\0"
103 auto var = envVars.substr(varPosition);
104 priority = std::stoi(var.substr(versionVar.length()));
105 return true;
106 }
107 }
108 }
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600109 catch (const std::exception& e)
110 {
111 }
Michael Tritz40ecdb62017-11-20 16:56:41 -0600112
Michael Tritz36417922017-08-04 14:00:29 -0500113 return false;
Michael Tritz60bc20f2017-07-29 23:32:21 -0500114}
115
116void removeFile(std::string versionId)
117{
Michael Tritz40ecdb62017-11-20 16:56:41 -0600118 auto bus = sdbusplus::bus::new_default();
119
120 // Clear the environment variable pnor-[versionId].
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600121 std::string serviceFile =
122 "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + ".service";
123 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
124 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritz40ecdb62017-11-20 16:56:41 -0600125 method.append(serviceFile, "replace");
126 bus.call_noreply(method);
127
128 // Delete the file /var/lib/obmc/openpower-pnor-code-mgmt/[versionId].
129 // Note that removeFile() is called in the case of a version being deleted,
130 // so the file /media/pnor-rw-[versionId]/[versionId] will also be deleted
131 // along with its surrounding directory.
Michael Tritz60bc20f2017-07-29 23:32:21 -0500132 std::string path = PERSIST_DIR + versionId;
133 if (fs::exists(path))
134 {
135 fs::remove(path);
136 }
137}
138
139} // namespace updater
140} // namespace software
141} // namespace openpower