blob: 5b54571c02e4a0623f8fd76133e751f1061d59e6 [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
60 constexpr auto squashfsMountService =
61 "obmc-flash-bios-squashfsmount@";
62 auto squashfsMountServiceFile = std::string(squashfsMountService) +
63 versionId + ".service";
64 auto method = bus.new_method_call(
65 SYSTEMD_BUSNAME,
66 SYSTEMD_PATH,
67 SYSTEMD_INTERFACE,
68 "StartUnit");
69 method.append(squashfsMountServiceFile, "replace");
70 bus.call_noreply(method);
71
72 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
73 auto ubimountServiceFile = std::string(ubimountService) +
74 versionId + ".service";
75 method = bus.new_method_call(
76 SYSTEMD_BUSNAME,
77 SYSTEMD_PATH,
78 SYSTEMD_INTERFACE,
79 "StartUnit");
80 method.append(ubimountServiceFile, "replace");
81 bus.call_noreply(method);
82
83 activationProgress->progress(10);
84}
85
86void Activation::finishActivation()
87{
88 activationProgress->progress(90);
Michael Tritz1cb127f2017-07-26 15:40:38 -050089
90 // Set Redundancy Priority before setting to Active
91 if (!redundancyPriority)
92 {
93 redundancyPriority = std::make_unique<RedundancyPriority>(
94 bus, path, *this, 0);
95 }
96
97 activationProgress->progress(100);
98
99 activationBlocksTransition.reset(nullptr);
100 activationProgress.reset(nullptr);
101
102 squashfsLoaded = false;
103 rwVolumesCreated = false;
104 Activation::unsubscribeFromSystemdSignals();
Gunnar Mills9741cd12017-08-28 15:09:00 -0500105 // Create active association
106 parent.createActiveAssociation(path);
Michael Tritz1cb127f2017-07-26 15:40:38 -0500107}
108
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500109auto Activation::activation(Activations value) ->
110 Activations
111{
Saqib Khan942df8a2017-06-01 14:09:27 -0500112
113 if (value != softwareServer::Activation::Activations::Active)
114 {
115 redundancyPriority.reset(nullptr);
116 }
117
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500118 if (value == softwareServer::Activation::Activations::Activating)
119 {
Saqib Khan2cbfa032017-08-17 14:52:37 -0500120 parent.freeSpace();
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500121 softwareServer::Activation::activation(value);
122
Michael Tritz9d25b602017-06-14 14:41:43 -0500123 if (squashfsLoaded == false && rwVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500124 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500125 Activation::startActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500126 return softwareServer::Activation::activation(value);
127 }
128 else if (squashfsLoaded == true && rwVolumesCreated == true)
129 {
130 // Only when the squashfs image is finished loading AND the RW
Michael Tritz1cb127f2017-07-26 15:40:38 -0500131 // volumes have been created do we proceed with activation. To
132 // verify that this happened, we check for the mount dirs PNOR_PRSV
133 // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
Michael Tritz9d25b602017-06-14 14:41:43 -0500134
Michael Tritz9d25b602017-06-14 14:41:43 -0500135 if ((fs::is_directory(PNOR_PRSV)) &&
136 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
137 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
138 {
Michael Tritz1cb127f2017-07-26 15:40:38 -0500139 Activation::finishActivation();
Michael Tritz9d25b602017-06-14 14:41:43 -0500140 return softwareServer::Activation::activation(
141 softwareServer::Activation::Activations::Active);
142 }
143 else
144 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500145 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500146 activationProgress.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500147 return softwareServer::Activation::activation(
148 softwareServer::Activation::Activations::Failed);
149 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500150 }
Adriana Kobylak692b5552017-04-17 14:02:58 -0500151 }
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500152 else
153 {
154 activationBlocksTransition.reset(nullptr);
Michael Tritz1793b642017-06-28 18:35:58 -0500155 activationProgress.reset(nullptr);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500156 }
Michael Tritz1cb127f2017-07-26 15:40:38 -0500157
158 return softwareServer::Activation::activation(value);
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500159}
160
161auto Activation::requestedActivation(RequestedActivations value) ->
162 RequestedActivations
163{
Michael Tritz9d25b602017-06-14 14:41:43 -0500164 squashfsLoaded = false;
165 rwVolumesCreated = false;
166
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500167 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
168 (softwareServer::Activation::requestedActivation() !=
169 softwareServer::Activation::RequestedActivations::Active))
170 {
171 if ((softwareServer::Activation::activation() ==
172 softwareServer::Activation::Activations::Ready) ||
173 (softwareServer::Activation::activation() ==
174 softwareServer::Activation::Activations::Failed))
175 {
176 Activation::activation(
177 softwareServer::Activation::Activations::Activating);
178
179 }
180 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500181 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500182}
183
Saqib Khan2021b4c2017-06-07 14:37:36 -0500184uint8_t RedundancyPriority::priority(uint8_t value)
185{
Saqib Khanb8e7f312017-08-12 10:24:10 -0500186 parent.parent.freePriority(value, parent.versionId);
Michael Tritz60bc20f2017-07-29 23:32:21 -0500187 storeToFile(parent.versionId, value);
Saqib Khan2021b4c2017-06-07 14:37:36 -0500188 return softwareServer::RedundancyPriority::priority(value);
189}
190
Michael Tritz9d25b602017-06-14 14:41:43 -0500191void Activation::unitStateChange(sdbusplus::message::message& msg)
192{
193 uint32_t newStateID {};
194 sdbusplus::message::object_path newStateObjPath;
195 std::string newStateUnit{};
196 std::string newStateResult{};
197
198 //Read the msg and populate each variable
199 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
200
201 auto squashfsMountServiceFile =
202 "obmc-flash-bios-squashfsmount@" + versionId + ".service";
203
204 auto ubimountServiceFile =
205 "obmc-flash-bios-ubimount@" + versionId + ".service";
206
207 if(newStateUnit == squashfsMountServiceFile && newStateResult == "done")
208 {
Michael Tritz1793b642017-06-28 18:35:58 -0500209 squashfsLoaded = true;
210 activationProgress->progress(activationProgress->progress() + 20);
Michael Tritz9d25b602017-06-14 14:41:43 -0500211 }
212
213 if(newStateUnit == ubimountServiceFile && newStateResult == "done")
214 {
215 rwVolumesCreated = true;
Michael Tritz1793b642017-06-28 18:35:58 -0500216 activationProgress->progress(activationProgress->progress() + 50);
Michael Tritz9d25b602017-06-14 14:41:43 -0500217 }
218
219 if(squashfsLoaded && rwVolumesCreated)
220 {
221 Activation::activation(
222 softwareServer::Activation::Activations::Activating);
223 }
224
225 if((newStateUnit == squashfsMountServiceFile ||
226 newStateUnit == ubimountServiceFile) &&
227 (newStateResult == "failed" || newStateResult == "dependency"))
228 {
229 Activation::activation(softwareServer::Activation::Activations::Failed);
230 }
231
232 return;
233}
234
Leonel Gonzalez9c8adfa2017-07-12 11:08:40 -0500235void Activation::delete_()
236{
Gunnar Mills9741cd12017-08-28 15:09:00 -0500237 // Remove active association
238 parent.removeActiveAssociation(path);
239
Leonel Gonzalez9c8adfa2017-07-12 11:08:40 -0500240 parent.erase(versionId);
241}
242
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500243} // namespace updater
244} // namespace software
245} // namespace openpower