blob: 8d4b202fc6cd20ec269dc51b000cf38105ba094a [file] [log] [blame]
Saqib Khanb0774702017-05-23 16:02:41 -05001#include "activation.hpp"
Saqib Khan4c1aec02017-07-06 11:46:13 -05002#include "item_updater.hpp"
Michael Tritzf2b5e0d2017-07-25 14:39:34 -05003#include "config.h"
Saqib Khan5d532672017-08-09 10:44:50 -05004#include "serialize.hpp"
Saqib Khanb9da6632017-09-13 09:48:37 -05005#include <phosphor-logging/log.hpp>
6
Jayanth Othayoth0e0c1272018-02-21 05:46:36 -06007#ifdef WANT_SIGNATURE_VERIFY
8#include <phosphor-logging/elog.hpp>
9#include <phosphor-logging/elog-errors.hpp>
10#include <xyz/openbmc_project/Common/error.hpp>
11#include "image_verify.hpp"
12#include "config.h"
13#endif
14
Saqib Khanb0774702017-05-23 16:02:41 -050015namespace phosphor
16{
17namespace software
18{
19namespace updater
20{
21
22namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
23
Saqib Khanb9da6632017-09-13 09:48:37 -050024using namespace phosphor::logging;
25
Jayanth Othayoth0e0c1272018-02-21 05:46:36 -060026#ifdef WANT_SIGNATURE_VERIFY
27using InternalFailure =
28 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
29#endif
30
Michael Tritzbed88af2017-07-19 16:00:06 -050031void Activation::subscribeToSystemdSignals()
32{
Adriana Kobylak2285fe02018-02-27 15:36:59 -060033 auto method = this->bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
34 SYSTEMD_INTERFACE, "Subscribe");
Michael Tritzbed88af2017-07-19 16:00:06 -050035 this->bus.call_noreply(method);
36
37 return;
38}
39
Michael Tritzf2b5e0d2017-07-25 14:39:34 -050040void Activation::unsubscribeFromSystemdSignals()
41{
Adriana Kobylak2285fe02018-02-27 15:36:59 -060042 auto method = this->bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
43 SYSTEMD_INTERFACE, "Unsubscribe");
Michael Tritzf2b5e0d2017-07-25 14:39:34 -050044 this->bus.call_noreply(method);
45
46 return;
47}
48
Adriana Kobylak2285fe02018-02-27 15:36:59 -060049auto Activation::activation(Activations value) -> Activations
Saqib Khanb0774702017-05-23 16:02:41 -050050{
Saqib Khan4c1aec02017-07-06 11:46:13 -050051
Adriana Kobylak8bd84c82018-01-24 14:19:24 -060052 if ((value != softwareServer::Activation::Activations::Active) &&
53 (value != softwareServer::Activation::Activations::Activating))
Saqib Khan4c1aec02017-07-06 11:46:13 -050054 {
55 redundancyPriority.reset(nullptr);
56 }
57
Saqib Khanb0774702017-05-23 16:02:41 -050058 if (value == softwareServer::Activation::Activations::Activating)
59 {
Michael Tritzbed88af2017-07-19 16:00:06 -050060 if (rwVolumeCreated == false && roVolumeCreated == false)
Saqib Khanb0774702017-05-23 16:02:41 -050061 {
Adriana Kobylak204e1e72018-01-24 16:00:05 -060062 parent.freeSpace();
63
Michael Tritz0edd4ad2017-07-26 14:27:42 -050064 if (!activationProgress)
65 {
Adriana Kobylak2285fe02018-02-27 15:36:59 -060066 activationProgress =
67 std::make_unique<ActivationProgress>(bus, path);
Michael Tritz0edd4ad2017-07-26 14:27:42 -050068 }
69
Michael Tritzbed88af2017-07-19 16:00:06 -050070 if (!activationBlocksTransition)
71 {
72 activationBlocksTransition =
Adriana Kobylak2285fe02018-02-27 15:36:59 -060073 std::make_unique<ActivationBlocksTransition>(bus, path);
Michael Tritzbed88af2017-07-19 16:00:06 -050074 }
Saqib Khan4c1aec02017-07-06 11:46:13 -050075
Jayanth Othayoth0e0c1272018-02-21 05:46:36 -060076#ifdef WANT_SIGNATURE_VERIFY
77 using Signature = phosphor::software::image::Signature;
78
79 fs::path uploadDir(IMG_UPLOAD_DIR);
80
81 Signature signature(uploadDir / versionId, SIGNED_IMAGE_CONF_PATH);
82
83 // Validate the signed image.
84 if (!signature.verify())
85 {
86 log<level::ERR>("Error occurred during image validation");
87 report<InternalFailure>();
88
89 return softwareServer::Activation::activation(
90 softwareServer::Activation::Activations::Failed);
91 }
92#endif
93
Adriana Kobylak2285fe02018-02-27 15:36:59 -060094 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
95 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritzbed88af2017-07-19 16:00:06 -050096 method.append("obmc-flash-bmc-ubirw.service", "replace");
97 bus.call_noreply(method);
98
Adriana Kobylak2285fe02018-02-27 15:36:59 -060099 auto roServiceFile =
100 "obmc-flash-bmc-ubiro@" + versionId + ".service";
101 method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
102 SYSTEMD_INTERFACE, "StartUnit");
Michael Tritzbed88af2017-07-19 16:00:06 -0500103 method.append(roServiceFile, "replace");
104 bus.call_noreply(method);
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500105
106 activationProgress->progress(10);
Michael Tritzbed88af2017-07-19 16:00:06 -0500107 }
108 else if (rwVolumeCreated == true && roVolumeCreated == true)
Saqib Khan4c1aec02017-07-06 11:46:13 -0500109 {
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600110 if (ubootEnvVarsUpdated == false)
Michael Tritzbed88af2017-07-19 16:00:06 -0500111 {
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600112 activationProgress->progress(90);
113
114 if (!redundancyPriority)
115 {
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600116 redundancyPriority = std::make_unique<RedundancyPriority>(
117 bus, path, *this, 0);
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600118 }
Michael Tritzbed88af2017-07-19 16:00:06 -0500119 }
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600120 else
121 {
122 activationProgress->progress(100);
Saqib Khan4c1aec02017-07-06 11:46:13 -0500123
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600124 activationBlocksTransition.reset(nullptr);
125 activationProgress.reset(nullptr);
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500126
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600127 rwVolumeCreated = false;
128 roVolumeCreated = false;
129 ubootEnvVarsUpdated = false;
130 Activation::unsubscribeFromSystemdSignals();
Michael Tritzf2b5e0d2017-07-25 14:39:34 -0500131
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600132 // Remove version object from image manager
133 Activation::deleteImageManagerObject();
Michael Tritzf2b5e0d2017-07-25 14:39:34 -0500134
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600135 // Create active association
136 parent.createActiveAssociation(path);
Saqib Khanee13e832017-10-23 12:53:11 -0500137
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600138 return softwareServer::Activation::activation(
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600139 softwareServer::Activation::Activations::Active);
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600140 }
Michael Tritzbed88af2017-07-19 16:00:06 -0500141 }
Saqib Khanb0774702017-05-23 16:02:41 -0500142 }
143 else
144 {
145 activationBlocksTransition.reset(nullptr);
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500146 activationProgress.reset(nullptr);
Saqib Khanb0774702017-05-23 16:02:41 -0500147 }
148 return softwareServer::Activation::activation(value);
149}
150
Saqib Khanee13e832017-10-23 12:53:11 -0500151void Activation::deleteImageManagerObject()
152{
Saqib Khanee13e832017-10-23 12:53:11 -0500153 // Call the Delete object for <versionID> inside image_manager
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600154 auto method = this->bus.new_method_call(VERSION_BUSNAME, path.c_str(),
155 "xyz.openbmc_project.Object.Delete",
156 "Delete");
Adriana Kobylak00bd9022018-01-24 13:55:58 -0600157 auto mapperResponseMsg = bus.call(method);
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600158 // Check that the bus call didn't result in an error
Saqib Khanee13e832017-10-23 12:53:11 -0500159 if (mapperResponseMsg.is_method_error())
160 {
161 log<level::ERR>("Error in Deleting image from image manager",
Adriana Kobylak596466b2018-02-13 14:48:53 -0600162 entry("VERSIONPATH=%s", path.c_str()));
Saqib Khanee13e832017-10-23 12:53:11 -0500163 return;
164 }
165}
166
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600167auto Activation::requestedActivation(RequestedActivations value)
168 -> RequestedActivations
Saqib Khanb0774702017-05-23 16:02:41 -0500169{
Michael Tritzbed88af2017-07-19 16:00:06 -0500170 rwVolumeCreated = false;
171 roVolumeCreated = false;
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600172 ubootEnvVarsUpdated = false;
Michael Tritzbed88af2017-07-19 16:00:06 -0500173
Saqib Khanb0774702017-05-23 16:02:41 -0500174 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
175 (softwareServer::Activation::requestedActivation() !=
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600176 softwareServer::Activation::RequestedActivations::Active))
Saqib Khanb0774702017-05-23 16:02:41 -0500177 {
178 if ((softwareServer::Activation::activation() ==
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600179 softwareServer::Activation::Activations::Ready) ||
Saqib Khanb0774702017-05-23 16:02:41 -0500180 (softwareServer::Activation::activation() ==
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600181 softwareServer::Activation::Activations::Failed))
Saqib Khanb0774702017-05-23 16:02:41 -0500182 {
183 Activation::activation(
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600184 softwareServer::Activation::Activations::Activating);
Saqib Khanb0774702017-05-23 16:02:41 -0500185 }
186 }
187 return softwareServer::Activation::requestedActivation(value);
188}
189
Saqib Khan4c1aec02017-07-06 11:46:13 -0500190uint8_t RedundancyPriority::priority(uint8_t value)
191{
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500192 // Set the priority value so that the freePriority() function can order
193 // the versions by priority.
194 auto newPriority = softwareServer::RedundancyPriority::priority(value);
Saqib Khan5d532672017-08-09 10:44:50 -0500195 storeToFile(parent.versionId, value);
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500196 parent.parent.freePriority(value, parent.versionId);
197 return newPriority;
Saqib Khan4c1aec02017-07-06 11:46:13 -0500198}
199
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500200uint8_t RedundancyPriority::sdbusPriority(uint8_t value)
Saqib Khanf0382c32017-10-24 13:36:22 -0500201{
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500202 storeToFile(parent.versionId, value);
203 return softwareServer::RedundancyPriority::priority(value);
Saqib Khanf0382c32017-10-24 13:36:22 -0500204}
205
Michael Tritzbed88af2017-07-19 16:00:06 -0500206void Activation::unitStateChange(sdbusplus::message::message& msg)
207{
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500208 if (softwareServer::Activation::activation() !=
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600209 softwareServer::Activation::Activations::Activating)
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500210 {
211 return;
212 }
213
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600214 uint32_t newStateID{};
Michael Tritzbed88af2017-07-19 16:00:06 -0500215 sdbusplus::message::object_path newStateObjPath;
216 std::string newStateUnit{};
217 std::string newStateResult{};
218
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600219 // Read the msg and populate each variable
Michael Tritzbed88af2017-07-19 16:00:06 -0500220 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
221
222 auto rwServiceFile = "obmc-flash-bmc-ubirw.service";
223 auto roServiceFile = "obmc-flash-bmc-ubiro@" + versionId + ".service";
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600224 auto ubootVarsServiceFile =
225 "obmc-flash-bmc-updateubootvars@" + versionId + ".service";
Michael Tritzbed88af2017-07-19 16:00:06 -0500226
Gunnar Mills3fa38202017-10-08 17:07:43 -0500227 if (newStateUnit == rwServiceFile && newStateResult == "done")
Michael Tritzbed88af2017-07-19 16:00:06 -0500228 {
229 rwVolumeCreated = true;
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500230 activationProgress->progress(activationProgress->progress() + 20);
Michael Tritzbed88af2017-07-19 16:00:06 -0500231 }
232
Gunnar Mills3fa38202017-10-08 17:07:43 -0500233 if (newStateUnit == roServiceFile && newStateResult == "done")
Michael Tritzbed88af2017-07-19 16:00:06 -0500234 {
235 roVolumeCreated = true;
Michael Tritz0edd4ad2017-07-26 14:27:42 -0500236 activationProgress->progress(activationProgress->progress() + 50);
Michael Tritzbed88af2017-07-19 16:00:06 -0500237 }
238
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600239 if (newStateUnit == ubootVarsServiceFile && newStateResult == "done")
240 {
241 ubootEnvVarsUpdated = true;
242 }
243
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600244 if (newStateUnit == rwServiceFile || newStateUnit == roServiceFile ||
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600245 newStateUnit == ubootVarsServiceFile)
Michael Tritzbed88af2017-07-19 16:00:06 -0500246 {
Adriana Kobylak8bd84c82018-01-24 14:19:24 -0600247 if (newStateResult == "failed" || newStateResult == "dependency")
248 {
249 Activation::activation(
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600250 softwareServer::Activation::Activations::Failed);
Adriana Kobylak8bd84c82018-01-24 14:19:24 -0600251 }
Adriana Kobylak4c3edc92018-01-24 14:50:15 -0600252 else if ((rwVolumeCreated && roVolumeCreated) || // Volumes were created
253 (ubootEnvVarsUpdated)) // Enviroment variables were updated
Adriana Kobylak8bd84c82018-01-24 14:19:24 -0600254 {
255 Activation::activation(
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600256 softwareServer::Activation::Activations::Activating);
Adriana Kobylak8bd84c82018-01-24 14:19:24 -0600257 }
Michael Tritzbed88af2017-07-19 16:00:06 -0500258 }
259
260 return;
261}
262
Saqib Khanf37cefc2017-09-12 08:44:41 -0500263void ActivationBlocksTransition::enableRebootGuard()
264{
265 log<level::INFO>("BMC image activating - BMC reboots are disabled.");
266
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600267 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
268 SYSTEMD_INTERFACE, "StartUnit");
Saqib Khanf37cefc2017-09-12 08:44:41 -0500269 method.append("reboot-guard-enable.service", "replace");
270 bus.call_noreply(method);
271}
272
273void ActivationBlocksTransition::disableRebootGuard()
274{
275 log<level::INFO>("BMC activation has ended - BMC reboots are re-enabled.");
276
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600277 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
278 SYSTEMD_INTERFACE, "StartUnit");
Saqib Khanf37cefc2017-09-12 08:44:41 -0500279 method.append("reboot-guard-disable.service", "replace");
280 bus.call_noreply(method);
281}
Michael Tritzbed88af2017-07-19 16:00:06 -0500282
Saqib Khanb0774702017-05-23 16:02:41 -0500283} // namespace updater
284} // namespace software
285} // namespace phosphor