blob: cd973b5c048360f6f854d8259276478598c4149f [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"
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05006
7namespace openpower
8{
9namespace software
10{
11namespace updater
12{
13
Adriana Kobylak55f9e832017-05-14 16:13:00 -050014namespace fs = std::experimental::filesystem;
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050015namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
16
Michael Tritz9d25b602017-06-14 14:41:43 -050017constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
18constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
19
20void Activation::subscribeToSystemdSignals()
21{
22 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
23 SYSTEMD_OBJ_PATH,
24 SYSTEMD_INTERFACE,
25 "Subscribe");
26 this->bus.call_noreply(method);
27
28 return;
29}
30
Michael Tritz1cb127f2017-07-26 15:40:38 -050031void Activation::unsubscribeFromSystemdSignals()
32{
33 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
34 SYSTEMD_OBJ_PATH,
35 SYSTEMD_INTERFACE,
36 "Unsubscribe");
37 this->bus.call_noreply(method);
38
39 return;
40}
41
Michael Tritz1cb127f2017-07-26 15:40:38 -050042void Activation::startActivation()
43{
44 // Since the squashfs image has not yet been loaded to pnor and the
45 // RW volumes have not yet been created, we need to start the
46 // service files for each of those actions.
47
48 if (!activationProgress)
49 {
50 activationProgress = std::make_unique<ActivationProgress>(
51 bus, path);
52 }
53
54 if (!activationBlocksTransition)
55 {
56 activationBlocksTransition =
57 std::make_unique<ActivationBlocksTransition>(bus, path);
58 }
59
Michael Tritz1cb127f2017-07-26 15:40:38 -050060 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
61 auto ubimountServiceFile = std::string(ubimountService) +
62 versionId + ".service";
Saqib Khan1e0aa5c2017-08-31 11:04:17 -050063 auto method = bus.new_method_call(
Michael Tritz1cb127f2017-07-26 15:40:38 -050064 SYSTEMD_BUSNAME,
65 SYSTEMD_PATH,
66 SYSTEMD_INTERFACE,
67 "StartUnit");
68 method.append(ubimountServiceFile, "replace");
69 bus.call_noreply(method);
70
71 activationProgress->progress(10);
72}
73
74void Activation::finishActivation()
75{
76 activationProgress->progress(90);
Michael Tritz1cb127f2017-07-26 15:40:38 -050077
78 // Set Redundancy Priority before setting to Active
79 if (!redundancyPriority)
80 {
81 redundancyPriority = std::make_unique<RedundancyPriority>(
82 bus, path, *this, 0);
83 }
84
85 activationProgress->progress(100);
86
87 activationBlocksTransition.reset(nullptr);
88 activationProgress.reset(nullptr);
89
Saqib Khan1e0aa5c2017-08-31 11:04:17 -050090 ubiVolumesCreated = false;
Michael Tritz1cb127f2017-07-26 15:40:38 -050091 Activation::unsubscribeFromSystemdSignals();
Gunnar Mills9741cd12017-08-28 15:09:00 -050092 // Create active association
93 parent.createActiveAssociation(path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050094}
95
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -050096auto Activation::activation(Activations value) ->
97 Activations
98{
Saqib Khan942df8a2017-06-01 14:09:27 -050099
100 if (value != softwareServer::Activation::Activations::Active)
101 {
102 redundancyPriority.reset(nullptr);
103 }
104
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500105 if (value == softwareServer::Activation::Activations::Activating)
106 {
Saqib Khan2cbfa032017-08-17 14:52:37 -0500107 parent.freeSpace();
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500108 softwareServer::Activation::activation(value);
109
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500110 if (ubiVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500111 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500112 Activation::startActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500113 return softwareServer::Activation::activation(value);
114 }
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500115 else if (ubiVolumesCreated == true)
Michael Tritz9d25b602017-06-14 14:41:43 -0500116 {
117 // Only when the squashfs image is finished loading AND the RW
Michael Tritz1cb127f2017-07-26 15:40:38 -0500118 // volumes have been created do we proceed with activation. To
119 // verify that this happened, we check for the mount dirs PNOR_PRSV
120 // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
Michael Tritz9d25b602017-06-14 14:41:43 -0500121
Michael Tritz9d25b602017-06-14 14:41:43 -0500122 if ((fs::is_directory(PNOR_PRSV)) &&
123 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
124 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
125 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500126 Activation::finishActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500127 return softwareServer::Activation::activation(
128 softwareServer::Activation::Activations::Active);
129 }
130 else
131 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500132 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500133 activationProgress.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500134 return softwareServer::Activation::activation(
135 softwareServer::Activation::Activations::Failed);
136 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500137 }
Adriana Kobylak692b5552017-04-17 14:02:58 -0500138 }
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500139 else
140 {
141 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500142 activationProgress.reset(nullptr);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500143 }
Michael Tritz1cb127f2017-07-26 15:40:38 -0500144
145 return softwareServer::Activation::activation(value);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500146}
147
148auto Activation::requestedActivation(RequestedActivations value) ->
149 RequestedActivations
150{
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500151 ubiVolumesCreated = false;
Michael Tritz9d25b602017-06-14 14:41:43 -0500152
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500153 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
154 (softwareServer::Activation::requestedActivation() !=
155 softwareServer::Activation::RequestedActivations::Active))
156 {
157 if ((softwareServer::Activation::activation() ==
158 softwareServer::Activation::Activations::Ready) ||
159 (softwareServer::Activation::activation() ==
160 softwareServer::Activation::Activations::Failed))
161 {
162 Activation::activation(
163 softwareServer::Activation::Activations::Activating);
164
165 }
166 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500167 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500168}
169
Saqib Khan2021b4c2017-06-07 14:37:36 -0500170uint8_t RedundancyPriority::priority(uint8_t value)
171{
Saqib Khanb8e7f312017-08-12 10:24:10 -0500172 parent.parent.freePriority(value, parent.versionId);
Michael Tritz60bc20f2017-07-29 23:32:21 -0500173 storeToFile(parent.versionId, value);
Saqib Khan2021b4c2017-06-07 14:37:36 -0500174 return softwareServer::RedundancyPriority::priority(value);
175}
176
Michael Tritz9d25b602017-06-14 14:41:43 -0500177void Activation::unitStateChange(sdbusplus::message::message& msg)
178{
179 uint32_t newStateID {};
180 sdbusplus::message::object_path newStateObjPath;
181 std::string newStateUnit{};
182 std::string newStateResult{};
183
184 //Read the msg and populate each variable
185 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
186
Michael Tritz9d25b602017-06-14 14:41:43 -0500187 auto ubimountServiceFile =
188 "obmc-flash-bios-ubimount@" + versionId + ".service";
189
Michael Tritz9d25b602017-06-14 14:41:43 -0500190 if(newStateUnit == ubimountServiceFile && newStateResult == "done")
191 {
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500192 ubiVolumesCreated = true;
Michael Tritz1793b642017-06-28 18:35:58 -0500193 activationProgress->progress(activationProgress->progress() + 50);
Michael Tritz9d25b602017-06-14 14:41:43 -0500194 }
195
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500196 if(ubiVolumesCreated)
Michael Tritz9d25b602017-06-14 14:41:43 -0500197 {
198 Activation::activation(
199 softwareServer::Activation::Activations::Activating);
200 }
201
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500202 if((newStateUnit == ubimountServiceFile) &&
Michael Tritz9d25b602017-06-14 14:41:43 -0500203 (newStateResult == "failed" || newStateResult == "dependency"))
204 {
205 Activation::activation(softwareServer::Activation::Activations::Failed);
206 }
207
208 return;
209}
210
Michael Tritz5b756512017-10-06 16:52:01 -0500211void Activation::updateDeleteInterface(sdbusplus::message::message& msg)
212{
213 std::string interface, chassisState;
214 std::map<std::string, sdbusplus::message::variant<std::string>> properties;
215
216 msg.read(interface, properties);
217
218 for (const auto& p : properties)
219 {
220 if (p.first == "CurrentPowerState")
221 {
222 chassisState = p.second.get<std::string>();
223 }
224 }
225
226 if ((parent.isVersionFunctional(this->versionId)) &&
227 (chassisState != CHASSIS_STATE_OFF))
228 {
229 if (deleteObject)
230 {
231 deleteObject.reset(nullptr);
232 }
233 }
234 else
235 {
236 if (!deleteObject)
237 {
238 deleteObject = std::make_unique<Delete>(bus, path, *this);
239 }
240 }
241}
242
243void Delete::delete_()
Leonel Gonzalez9c8adfa2017-07-12 11:08:40 -0500244{
Gunnar Mills9741cd12017-08-28 15:09:00 -0500245 // Remove active association
Michael Tritz5b756512017-10-06 16:52:01 -0500246 parent.parent.removeActiveAssociation(parent.path);
Gunnar Mills9741cd12017-08-28 15:09:00 -0500247
Michael Tritz5b756512017-10-06 16:52:01 -0500248 parent.parent.erase(parent.versionId);
Leonel Gonzalez9c8adfa2017-07-12 11:08:40 -0500249}
250
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500251} // namespace updater
252} // namespace software
253} // namespace openpower