blob: fe9af2f58870ee35a73a3f7913161a56d73bb73d [file] [log] [blame]
Saqib Khan35e83f32017-05-22 11:37:32 -05001#include <fstream>
Gunnar Millsec1b41c2017-05-02 12:20:36 -05002#include <string>
Gunnar Mills2ce7da22017-05-04 15:37:56 -05003#include <phosphor-logging/log.hpp>
Gunnar Millsec1b41c2017-05-02 12:20:36 -05004#include "config.h"
Gunnar Mills2ce7da22017-05-04 15:37:56 -05005#include "item_updater.hpp"
6#include "xyz/openbmc_project/Software/Version/server.hpp"
Saqib Khan35e83f32017-05-22 11:37:32 -05007#include <experimental/filesystem>
Saqib Khan705f1bf2017-06-09 23:58:38 -05008#include "version.hpp"
Gunnar Millsec1b41c2017-05-02 12:20:36 -05009
10namespace phosphor
11{
12namespace software
13{
14namespace updater
15{
16
Gunnar Mills2ce7da22017-05-04 15:37:56 -050017// When you see server:: you know we're referencing our base class
18namespace server = sdbusplus::xyz::openbmc_project::Software::server;
19
20using namespace phosphor::logging;
Saqib Khan35e83f32017-05-22 11:37:32 -050021namespace fs = std::experimental::filesystem;
22
23constexpr auto bmcImage = "image-rofs";
Gunnar Mills2ce7da22017-05-04 15:37:56 -050024
Michael Tritz37a59042017-07-12 13:44:53 -050025constexpr auto SYSTEMD_BUSNAME = "org.freedesktop.systemd1";
26constexpr auto SYSTEMD_PATH = "/org/freedesktop/systemd1";
27constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
28
Patrick Williamse75d10f2017-05-30 16:56:32 -050029void ItemUpdater::createActivation(sdbusplus::message::message& msg)
Gunnar Millsec1b41c2017-05-02 12:20:36 -050030{
Saqib Khan84a0e692017-06-28 17:27:01 -050031
32 using SVersion = server::Version;
33 using VersionPurpose = SVersion::VersionPurpose;
34 namespace mesg = sdbusplus::message;
35 namespace variant_ns = mesg::variant_ns;
36
37 mesg::object_path objPath;
38 auto purpose = VersionPurpose::Unknown;
Saqib Khan705f1bf2017-06-09 23:58:38 -050039 std::string version;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050040 std::map<std::string,
Patrick Williamse75d10f2017-05-30 16:56:32 -050041 std::map<std::string,
Saqib Khan84a0e692017-06-28 17:27:01 -050042 mesg::variant<std::string>>> interfaces;
Patrick Williamse75d10f2017-05-30 16:56:32 -050043 msg.read(objPath, interfaces);
Gunnar Mills2ce7da22017-05-04 15:37:56 -050044 std::string path(std::move(objPath));
Saqib Khan19177d32017-06-20 08:11:49 -050045 std::string filePath;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050046
47 for (const auto& intf : interfaces)
48 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050049 if (intf.first == VERSION_IFACE)
Gunnar Mills2ce7da22017-05-04 15:37:56 -050050 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050051 for (const auto& property : intf.second)
Gunnar Mills2ce7da22017-05-04 15:37:56 -050052 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050053 if (property.first == "Purpose")
Gunnar Mills2ce7da22017-05-04 15:37:56 -050054 {
Saqib Khan84a0e692017-06-28 17:27:01 -050055 auto value = SVersion::convertVersionPurposeFromString(
56 variant_ns::get<std::string>(property.second));
57 if (value == VersionPurpose::BMC ||
58 value == VersionPurpose::System)
59 {
60 purpose = value;
61 }
Saqib Khan705f1bf2017-06-09 23:58:38 -050062 }
63 else if (property.first == "Version")
64 {
Saqib Khan84a0e692017-06-28 17:27:01 -050065 version = variant_ns::get<std::string>(property.second);
Gunnar Mills2ce7da22017-05-04 15:37:56 -050066 }
67 }
68 }
Saqib Khan19177d32017-06-20 08:11:49 -050069 else if (intf.first == FILEPATH_IFACE)
70 {
71 for (const auto& property : intf.second)
72 {
73 if (property.first == "Path")
74 {
Saqib Khan84a0e692017-06-28 17:27:01 -050075 filePath = variant_ns::get<std::string>(property.second);
Saqib Khan19177d32017-06-20 08:11:49 -050076 }
77 }
78 }
Gunnar Mills2ce7da22017-05-04 15:37:56 -050079 }
Saqib Khan705f1bf2017-06-09 23:58:38 -050080 if (version.empty() ||
Saqib Khan19177d32017-06-20 08:11:49 -050081 filePath.empty() ||
Saqib Khan84a0e692017-06-28 17:27:01 -050082 purpose == VersionPurpose::Unknown)
Saqib Khan705f1bf2017-06-09 23:58:38 -050083 {
84 return;
85 }
Gunnar Mills2ce7da22017-05-04 15:37:56 -050086
87 // Version id is the last item in the path
88 auto pos = path.rfind("/");
89 if (pos == std::string::npos)
90 {
91 log<level::ERR>("No version id found in object path",
92 entry("OBJPATH=%s", path));
Patrick Williamse75d10f2017-05-30 16:56:32 -050093 return;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050094 }
95
96 auto versionId = path.substr(pos + 1);
97
Patrick Williamse75d10f2017-05-30 16:56:32 -050098 if (activations.find(versionId) == activations.end())
Gunnar Mills2ce7da22017-05-04 15:37:56 -050099 {
Saqib Khan35e83f32017-05-22 11:37:32 -0500100 // Determine the Activation state by processing the given image dir.
101 auto activationState = server::Activation::Activations::Invalid;
102 ItemUpdater::ActivationStatus result = ItemUpdater::
Saqib Khan19177d32017-06-20 08:11:49 -0500103 validateSquashFSImage(filePath);
Saqib Khan35e83f32017-05-22 11:37:32 -0500104 if (result == ItemUpdater::ActivationStatus::ready)
105 {
106 activationState = server::Activation::Activations::Ready;
107 }
Saqib Khan35e83f32017-05-22 11:37:32 -0500108 activations.insert(std::make_pair(
Saqib Khan705f1bf2017-06-09 23:58:38 -0500109 versionId,
110 std::make_unique<Activation>(
111 bus,
112 path,
Saqib Khan4c1aec02017-07-06 11:46:13 -0500113 *this,
Saqib Khan35e83f32017-05-22 11:37:32 -0500114 versionId,
Saqib Khan705f1bf2017-06-09 23:58:38 -0500115 activationState)));
116 versions.insert(std::make_pair(
117 versionId,
118 std::make_unique<phosphor::software::
119 manager::Version>(
120 bus,
121 path,
122 version,
123 purpose,
Saqib Khan19177d32017-06-20 08:11:49 -0500124 filePath)));
Gunnar Mills2ce7da22017-05-04 15:37:56 -0500125 }
Patrick Williamse75d10f2017-05-30 16:56:32 -0500126 return;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500127}
128
Saqib Khanba239882017-05-26 08:41:54 -0500129void ItemUpdater::processBMCImage()
130{
131 auto purpose = server::Version::VersionPurpose::BMC;
132 auto version = phosphor::software::manager::Version::getBMCVersion();
133 auto id = phosphor::software::manager::Version::getId(version);
134 auto path = std::string{SOFTWARE_OBJPATH} + '/' + id;
135 activations.insert(std::make_pair(
136 id,
137 std::make_unique<Activation>(
138 bus,
139 path,
Saqib Khan4c1aec02017-07-06 11:46:13 -0500140 *this,
Saqib Khanba239882017-05-26 08:41:54 -0500141 id,
142 server::Activation::Activations::Active)));
143 versions.insert(std::make_pair(
144 id,
145 std::make_unique<phosphor::software::
146 manager::Version>(
147 bus,
148 path,
149 version,
150 purpose,
151 "")));
152 return;
153}
154
Saqib Khan35e83f32017-05-22 11:37:32 -0500155ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(
Saqib Khan19177d32017-06-20 08:11:49 -0500156 const std::string& filePath)
Saqib Khan35e83f32017-05-22 11:37:32 -0500157{
158
Saqib Khan19177d32017-06-20 08:11:49 -0500159 fs::path file(filePath);
Saqib Khan35e83f32017-05-22 11:37:32 -0500160 file /= bmcImage;
161 std::ifstream efile(file.c_str());
162
163 if (efile.good() == 1)
164 {
165 return ItemUpdater::ActivationStatus::ready;
166 }
167 else
168 {
Saqib Khan19177d32017-06-20 08:11:49 -0500169 log<level::ERR>("Failed to find the BMC image.");
Saqib Khan35e83f32017-05-22 11:37:32 -0500170 return ItemUpdater::ActivationStatus::invalid;
171 }
172}
173
Saqib Khan4c1aec02017-07-06 11:46:13 -0500174void ItemUpdater::freePriority(uint8_t value)
175{
176 //TODO openbmc/openbmc#1896 Improve the performance of this function
177 for (const auto& intf : activations)
178 {
179 if(intf.second->redundancyPriority)
180 {
181 if (intf.second->redundancyPriority.get()->priority() == value)
182 {
183 intf.second->redundancyPriority.get()->priority(value+1);
184 }
185 }
186 }
187}
188
Michael Tritz37a59042017-07-12 13:44:53 -0500189void ItemUpdater::reset()
190{
191 // Mark the read-write partition for recreation upon reboot.
192 auto method = bus.new_method_call(
193 SYSTEMD_BUSNAME,
194 SYSTEMD_PATH,
195 SYSTEMD_INTERFACE,
196 "StartUnit");
197 method.append("obmc-flash-bmc-setenv@rwreset=true.service", "replace");
198 bus.call_noreply(method);
199
200 log<level::INFO>("BMC factory reset will take effect upon reboot.");
201
202 return;
203}
204
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500205} // namespace updater
206} // namespace software
207} // namespace phosphor