blob: b7cdb51fabe17aa7937b9f88d209e2fefa634290 [file] [log] [blame]
Adriana Kobylak55f9e832017-05-14 16:13:00 -05001#include <experimental/filesystem>
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05002#include "activation.hpp"
Adriana Kobylak692b5552017-04-17 14:02:58 -05003#include "config.h"
Saqib Khan81bac882017-06-08 12:17:01 -05004#include "item_updater.hpp"
Michael Tritz60bc20f2017-07-29 23:32:21 -05005#include "serialize.hpp"
Saqib Khan7f80e0b2017-10-22 11:29:07 -05006#include <phosphor-logging/log.hpp>
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05007
Jayanth Othayoth4016e522018-03-20 09:39:06 -05008#ifdef WANT_SIGNATURE_VERIFY
9#include <phosphor-logging/elog.hpp>
10#include <phosphor-logging/elog-errors.hpp>
11#include <xyz/openbmc_project/Common/error.hpp>
12#include "image_verify.hpp"
13#include "config.h"
14#endif
15
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -050016namespace openpower
17{
18namespace software
19{
20namespace updater
21{
22
Adriana Kobylak55f9e832017-05-14 16:13:00 -050023namespace fs = std::experimental::filesystem;
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050024namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
25
Saqib Khan7f80e0b2017-10-22 11:29:07 -050026using namespace phosphor::logging;
27
Jayanth Othayoth4016e522018-03-20 09:39:06 -050028#ifdef WANT_SIGNATURE_VERIFY
29using InternalFailure =
30 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
31#endif
32
Adriana Kobylak70dcb632018-02-27 15:46:52 -060033constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
34constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
Michael Tritz9d25b602017-06-14 14:41:43 -050035
36void Activation::subscribeToSystemdSignals()
37{
Adriana Kobylak70dcb632018-02-27 15:46:52 -060038 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
39 SYSTEMD_INTERFACE, "Subscribe");
Michael Tritz9d25b602017-06-14 14:41:43 -050040 this->bus.call_noreply(method);
41
42 return;
43}
44
Michael Tritz1cb127f2017-07-26 15:40:38 -050045void Activation::unsubscribeFromSystemdSignals()
46{
Adriana Kobylak70dcb632018-02-27 15:46:52 -060047 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
48 SYSTEMD_INTERFACE, "Unsubscribe");
Michael Tritz1cb127f2017-07-26 15:40:38 -050049 this->bus.call_noreply(method);
50
51 return;
52}
53
Michael Tritz1cb127f2017-07-26 15:40:38 -050054void Activation::startActivation()
55{
56 // Since the squashfs image has not yet been loaded to pnor and the
57 // RW volumes have not yet been created, we need to start the
58 // service files for each of those actions.
59
60 if (!activationProgress)
61 {
Adriana Kobylak70dcb632018-02-27 15:46:52 -060062 activationProgress = std::make_unique<ActivationProgress>(bus, path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050063 }
64
65 if (!activationBlocksTransition)
66 {
67 activationBlocksTransition =
Adriana Kobylak70dcb632018-02-27 15:46:52 -060068 std::make_unique<ActivationBlocksTransition>(bus, path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050069 }
70
Michael Tritz1cb127f2017-07-26 15:40:38 -050071 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
Adriana Kobylak70dcb632018-02-27 15:46:52 -060072 auto ubimountServiceFile =
73 std::string(ubimountService) + versionId + ".service";
74 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
75 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritz1cb127f2017-07-26 15:40:38 -050076 method.append(ubimountServiceFile, "replace");
77 bus.call_noreply(method);
78
79 activationProgress->progress(10);
80}
81
82void Activation::finishActivation()
83{
84 activationProgress->progress(90);
Michael Tritz1cb127f2017-07-26 15:40:38 -050085
86 // Set Redundancy Priority before setting to Active
87 if (!redundancyPriority)
88 {
Adriana Kobylak70dcb632018-02-27 15:46:52 -060089 redundancyPriority =
90 std::make_unique<RedundancyPriority>(bus, path, *this, 0);
Michael Tritz1cb127f2017-07-26 15:40:38 -050091 }
92
93 activationProgress->progress(100);
94
95 activationBlocksTransition.reset(nullptr);
96 activationProgress.reset(nullptr);
97
Saqib Khan1e0aa5c2017-08-31 11:04:17 -050098 ubiVolumesCreated = false;
Michael Tritz1cb127f2017-07-26 15:40:38 -050099 Activation::unsubscribeFromSystemdSignals();
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500100 // Remove version object from image manager
101 Activation::deleteImageManagerObject();
Gunnar Mills9741cd12017-08-28 15:09:00 -0500102 // Create active association
103 parent.createActiveAssociation(path);
Michael Tritz1cb127f2017-07-26 15:40:38 -0500104}
105
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600106auto Activation::activation(Activations value) -> Activations
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500107{
Saqib Khan942df8a2017-06-01 14:09:27 -0500108
109 if (value != softwareServer::Activation::Activations::Active)
110 {
111 redundancyPriority.reset(nullptr);
112 }
113
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500114 if (value == softwareServer::Activation::Activations::Activating)
115 {
Saqib Khan2cbfa032017-08-17 14:52:37 -0500116 parent.freeSpace();
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500117 softwareServer::Activation::activation(value);
118
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500119 if (ubiVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500120 {
Jayanth Othayoth4016e522018-03-20 09:39:06 -0500121
122#ifdef WANT_SIGNATURE_VERIFY
123 using Signature = openpower::software::image::Signature;
124
125 fs::path imagePath(IMG_DIR);
126
Jayanth Othayoth5248f3c2018-03-28 11:04:14 -0500127 Signature signature(imagePath / versionId,
128 PNOR_SIGNED_IMAGE_CONF_PATH);
Jayanth Othayoth4016e522018-03-20 09:39:06 -0500129
130 // Validate the signed image.
131 if (!signature.verify())
132 {
133 log<level::ERR>("Error occurred during image validation");
134 report<InternalFailure>();
135
136 return softwareServer::Activation::activation(
137 softwareServer::Activation::Activations::Failed);
138 }
139#endif
140
Michael Tritz1cb127f2017-07-26 15:40:38 -0500141 Activation::startActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500142 return softwareServer::Activation::activation(value);
143 }
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500144 else if (ubiVolumesCreated == true)
Michael Tritz9d25b602017-06-14 14:41:43 -0500145 {
146 // Only when the squashfs image is finished loading AND the RW
Michael Tritz1cb127f2017-07-26 15:40:38 -0500147 // volumes have been created do we proceed with activation. To
148 // verify that this happened, we check for the mount dirs PNOR_PRSV
149 // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
Michael Tritz9d25b602017-06-14 14:41:43 -0500150
Michael Tritz9d25b602017-06-14 14:41:43 -0500151 if ((fs::is_directory(PNOR_PRSV)) &&
152 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
153 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
154 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500155 Activation::finishActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500156 return softwareServer::Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600157 softwareServer::Activation::Activations::Active);
Michael Tritz9d25b602017-06-14 14:41:43 -0500158 }
159 else
160 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500161 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500162 activationProgress.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500163 return softwareServer::Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600164 softwareServer::Activation::Activations::Failed);
Michael Tritz9d25b602017-06-14 14:41:43 -0500165 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500166 }
Adriana Kobylak692b5552017-04-17 14:02:58 -0500167 }
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500168 else
169 {
170 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500171 activationProgress.reset(nullptr);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500172 }
Michael Tritz1cb127f2017-07-26 15:40:38 -0500173
174 return softwareServer::Activation::activation(value);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500175}
176
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600177auto Activation::requestedActivation(RequestedActivations value)
178 -> RequestedActivations
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500179{
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500180 ubiVolumesCreated = false;
Michael Tritz9d25b602017-06-14 14:41:43 -0500181
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500182 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
183 (softwareServer::Activation::requestedActivation() !=
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600184 softwareServer::Activation::RequestedActivations::Active))
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500185 {
186 if ((softwareServer::Activation::activation() ==
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600187 softwareServer::Activation::Activations::Ready) ||
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500188 (softwareServer::Activation::activation() ==
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600189 softwareServer::Activation::Activations::Failed))
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500190 {
191 Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600192 softwareServer::Activation::Activations::Activating);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500193 }
194 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500195 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500196}
197
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500198void Activation::deleteImageManagerObject()
199{
200 // Get the Delete object for <versionID> inside image_manager
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600201 auto method = this->bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
202 MAPPER_INTERFACE, "GetObject");
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500203
204 method.append(path);
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600205 method.append(
206 std::vector<std::string>({"xyz.openbmc_project.Object.Delete"}));
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500207 auto mapperResponseMsg = bus.call(method);
208 if (mapperResponseMsg.is_method_error())
209 {
210 log<level::ERR>("Error in Get Delete Object",
211 entry("VERSIONPATH=%s", path));
212 return;
213 }
214 std::map<std::string, std::vector<std::string>> mapperResponse;
215 mapperResponseMsg.read(mapperResponse);
216 if (mapperResponse.begin() == mapperResponse.end())
217 {
218 log<level::ERR>("ERROR in reading the mapper response",
219 entry("VERSIONPATH=%s", path));
220 return;
221 }
222
223 // Call the Delete object for <versionID> inside image_manager
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600224 method = this->bus.new_method_call(
225 (mapperResponse.begin()->first).c_str(), path.c_str(),
226 "xyz.openbmc_project.Object.Delete", "Delete");
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500227 mapperResponseMsg = bus.call(method);
228
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600229 // Check that the bus call didn't result in an error
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500230 if (mapperResponseMsg.is_method_error())
231 {
232 log<level::ERR>("Error in Deleting image from image manager",
233 entry("VERSIONPATH=%s", path));
234 return;
235 }
236}
237
Saqib Khan2021b4c2017-06-07 14:37:36 -0500238uint8_t RedundancyPriority::priority(uint8_t value)
239{
Saqib Khanb8e7f312017-08-12 10:24:10 -0500240 parent.parent.freePriority(value, parent.versionId);
Michael Tritz60bc20f2017-07-29 23:32:21 -0500241 storeToFile(parent.versionId, value);
Saqib Khan2021b4c2017-06-07 14:37:36 -0500242 return softwareServer::RedundancyPriority::priority(value);
243}
244
Michael Tritz9d25b602017-06-14 14:41:43 -0500245void Activation::unitStateChange(sdbusplus::message::message& msg)
246{
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600247 uint32_t newStateID{};
Michael Tritz9d25b602017-06-14 14:41:43 -0500248 sdbusplus::message::object_path newStateObjPath;
249 std::string newStateUnit{};
250 std::string newStateResult{};
251
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600252 // Read the msg and populate each variable
Michael Tritz9d25b602017-06-14 14:41:43 -0500253 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
254
Michael Tritz9d25b602017-06-14 14:41:43 -0500255 auto ubimountServiceFile =
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600256 "obmc-flash-bios-ubimount@" + versionId + ".service";
Michael Tritz9d25b602017-06-14 14:41:43 -0500257
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600258 if (newStateUnit == ubimountServiceFile && newStateResult == "done")
Michael Tritz9d25b602017-06-14 14:41:43 -0500259 {
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500260 ubiVolumesCreated = true;
Michael Tritz1793b642017-06-28 18:35:58 -0500261 activationProgress->progress(activationProgress->progress() + 50);
Michael Tritz9d25b602017-06-14 14:41:43 -0500262 }
263
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600264 if (ubiVolumesCreated)
Michael Tritz9d25b602017-06-14 14:41:43 -0500265 {
266 Activation::activation(
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600267 softwareServer::Activation::Activations::Activating);
Michael Tritz9d25b602017-06-14 14:41:43 -0500268 }
269
Adriana Kobylak70dcb632018-02-27 15:46:52 -0600270 if ((newStateUnit == ubimountServiceFile) &&
Michael Tritz9d25b602017-06-14 14:41:43 -0500271 (newStateResult == "failed" || newStateResult == "dependency"))
272 {
273 Activation::activation(softwareServer::Activation::Activations::Failed);
274 }
275
276 return;
277}
278
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500279} // namespace updater
280} // namespace software
281} // namespace openpower