blob: 40acc894d5abc4a01da80fd23e065e172c45f336 [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
8namespace openpower
9{
10namespace software
11{
12namespace updater
13{
14
Adriana Kobylak55f9e832017-05-14 16:13:00 -050015namespace fs = std::experimental::filesystem;
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050016namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
17
Saqib Khan7f80e0b2017-10-22 11:29:07 -050018using namespace phosphor::logging;
19
Michael Tritz9d25b602017-06-14 14:41:43 -050020constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
21constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
22
23void Activation::subscribeToSystemdSignals()
24{
25 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
26 SYSTEMD_OBJ_PATH,
27 SYSTEMD_INTERFACE,
28 "Subscribe");
29 this->bus.call_noreply(method);
30
31 return;
32}
33
Michael Tritz1cb127f2017-07-26 15:40:38 -050034void Activation::unsubscribeFromSystemdSignals()
35{
36 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
37 SYSTEMD_OBJ_PATH,
38 SYSTEMD_INTERFACE,
39 "Unsubscribe");
40 this->bus.call_noreply(method);
41
42 return;
43}
44
Michael Tritz1cb127f2017-07-26 15:40:38 -050045void Activation::startActivation()
46{
47 // Since the squashfs image has not yet been loaded to pnor and the
48 // RW volumes have not yet been created, we need to start the
49 // service files for each of those actions.
50
51 if (!activationProgress)
52 {
53 activationProgress = std::make_unique<ActivationProgress>(
54 bus, path);
55 }
56
57 if (!activationBlocksTransition)
58 {
59 activationBlocksTransition =
60 std::make_unique<ActivationBlocksTransition>(bus, path);
61 }
62
Michael Tritz1cb127f2017-07-26 15:40:38 -050063 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
64 auto ubimountServiceFile = std::string(ubimountService) +
65 versionId + ".service";
Saqib Khan1e0aa5c2017-08-31 11:04:17 -050066 auto method = bus.new_method_call(
Michael Tritz1cb127f2017-07-26 15:40:38 -050067 SYSTEMD_BUSNAME,
68 SYSTEMD_PATH,
69 SYSTEMD_INTERFACE,
70 "StartUnit");
71 method.append(ubimountServiceFile, "replace");
72 bus.call_noreply(method);
73
74 activationProgress->progress(10);
75}
76
77void Activation::finishActivation()
78{
79 activationProgress->progress(90);
Michael Tritz1cb127f2017-07-26 15:40:38 -050080
81 // Set Redundancy Priority before setting to Active
82 if (!redundancyPriority)
83 {
84 redundancyPriority = std::make_unique<RedundancyPriority>(
85 bus, path, *this, 0);
86 }
87
88 activationProgress->progress(100);
89
90 activationBlocksTransition.reset(nullptr);
91 activationProgress.reset(nullptr);
92
Saqib Khan1e0aa5c2017-08-31 11:04:17 -050093 ubiVolumesCreated = false;
Michael Tritz1cb127f2017-07-26 15:40:38 -050094 Activation::unsubscribeFromSystemdSignals();
Saqib Khan7f80e0b2017-10-22 11:29:07 -050095 // Remove version object from image manager
96 Activation::deleteImageManagerObject();
Gunnar Mills9741cd12017-08-28 15:09:00 -050097 // Create active association
98 parent.createActiveAssociation(path);
Michael Tritz1cb127f2017-07-26 15:40:38 -050099}
100
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500101auto Activation::activation(Activations value) ->
102 Activations
103{
Saqib Khan942df8a2017-06-01 14:09:27 -0500104
105 if (value != softwareServer::Activation::Activations::Active)
106 {
107 redundancyPriority.reset(nullptr);
108 }
109
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500110 if (value == softwareServer::Activation::Activations::Activating)
111 {
Saqib Khan2cbfa032017-08-17 14:52:37 -0500112 parent.freeSpace();
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500113 softwareServer::Activation::activation(value);
114
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500115 if (ubiVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500116 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500117 Activation::startActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500118 return softwareServer::Activation::activation(value);
119 }
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500120 else if (ubiVolumesCreated == true)
Michael Tritz9d25b602017-06-14 14:41:43 -0500121 {
122 // Only when the squashfs image is finished loading AND the RW
Michael Tritz1cb127f2017-07-26 15:40:38 -0500123 // volumes have been created do we proceed with activation. To
124 // verify that this happened, we check for the mount dirs PNOR_PRSV
125 // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
Michael Tritz9d25b602017-06-14 14:41:43 -0500126
Michael Tritz9d25b602017-06-14 14:41:43 -0500127 if ((fs::is_directory(PNOR_PRSV)) &&
128 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
129 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
130 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500131 Activation::finishActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500132 return softwareServer::Activation::activation(
133 softwareServer::Activation::Activations::Active);
134 }
135 else
136 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500137 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500138 activationProgress.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500139 return softwareServer::Activation::activation(
140 softwareServer::Activation::Activations::Failed);
141 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500142 }
Adriana Kobylak692b5552017-04-17 14:02:58 -0500143 }
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500144 else
145 {
146 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500147 activationProgress.reset(nullptr);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500148 }
Michael Tritz1cb127f2017-07-26 15:40:38 -0500149
150 return softwareServer::Activation::activation(value);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500151}
152
153auto Activation::requestedActivation(RequestedActivations value) ->
154 RequestedActivations
155{
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500156 ubiVolumesCreated = false;
Michael Tritz9d25b602017-06-14 14:41:43 -0500157
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500158 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
159 (softwareServer::Activation::requestedActivation() !=
160 softwareServer::Activation::RequestedActivations::Active))
161 {
162 if ((softwareServer::Activation::activation() ==
163 softwareServer::Activation::Activations::Ready) ||
164 (softwareServer::Activation::activation() ==
165 softwareServer::Activation::Activations::Failed))
166 {
167 Activation::activation(
168 softwareServer::Activation::Activations::Activating);
169
170 }
171 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500172 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500173}
174
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500175void Activation::deleteImageManagerObject()
176{
177 // Get the Delete object for <versionID> inside image_manager
178 auto method = this->bus.new_method_call(MAPPER_BUSNAME,
179 MAPPER_PATH,
180 MAPPER_INTERFACE,
181 "GetObject");
182
183 method.append(path);
184 method.append(std::vector<std::string>({
185 "xyz.openbmc_project.Object.Delete"}));
186 auto mapperResponseMsg = bus.call(method);
187 if (mapperResponseMsg.is_method_error())
188 {
189 log<level::ERR>("Error in Get Delete Object",
190 entry("VERSIONPATH=%s", path));
191 return;
192 }
193 std::map<std::string, std::vector<std::string>> mapperResponse;
194 mapperResponseMsg.read(mapperResponse);
195 if (mapperResponse.begin() == mapperResponse.end())
196 {
197 log<level::ERR>("ERROR in reading the mapper response",
198 entry("VERSIONPATH=%s", path));
199 return;
200 }
201
202 // Call the Delete object for <versionID> inside image_manager
203 method = this->bus.new_method_call((mapperResponse.begin()->first).c_str(),
204 path.c_str(),
205 "xyz.openbmc_project.Object.Delete",
206 "Delete");
207 mapperResponseMsg = bus.call(method);
208
209 //Check that the bus call didn't result in an error
210 if (mapperResponseMsg.is_method_error())
211 {
212 log<level::ERR>("Error in Deleting image from image manager",
213 entry("VERSIONPATH=%s", path));
214 return;
215 }
216}
217
Saqib Khan2021b4c2017-06-07 14:37:36 -0500218uint8_t RedundancyPriority::priority(uint8_t value)
219{
Saqib Khanb8e7f312017-08-12 10:24:10 -0500220 parent.parent.freePriority(value, parent.versionId);
Michael Tritz60bc20f2017-07-29 23:32:21 -0500221 storeToFile(parent.versionId, value);
Saqib Khan2021b4c2017-06-07 14:37:36 -0500222 return softwareServer::RedundancyPriority::priority(value);
223}
224
Michael Tritz9d25b602017-06-14 14:41:43 -0500225void Activation::unitStateChange(sdbusplus::message::message& msg)
226{
227 uint32_t newStateID {};
228 sdbusplus::message::object_path newStateObjPath;
229 std::string newStateUnit{};
230 std::string newStateResult{};
231
232 //Read the msg and populate each variable
233 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
234
Michael Tritz9d25b602017-06-14 14:41:43 -0500235 auto ubimountServiceFile =
236 "obmc-flash-bios-ubimount@" + versionId + ".service";
237
Michael Tritz9d25b602017-06-14 14:41:43 -0500238 if(newStateUnit == ubimountServiceFile && newStateResult == "done")
239 {
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500240 ubiVolumesCreated = true;
Michael Tritz1793b642017-06-28 18:35:58 -0500241 activationProgress->progress(activationProgress->progress() + 50);
Michael Tritz9d25b602017-06-14 14:41:43 -0500242 }
243
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500244 if(ubiVolumesCreated)
Michael Tritz9d25b602017-06-14 14:41:43 -0500245 {
246 Activation::activation(
247 softwareServer::Activation::Activations::Activating);
248 }
249
Saqib Khan1e0aa5c2017-08-31 11:04:17 -0500250 if((newStateUnit == ubimountServiceFile) &&
Michael Tritz9d25b602017-06-14 14:41:43 -0500251 (newStateResult == "failed" || newStateResult == "dependency"))
252 {
253 Activation::activation(softwareServer::Activation::Activations::Failed);
254 }
255
256 return;
257}
258
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500259} // namespace updater
260} // namespace software
261} // namespace openpower