blob: 9a19008f06e8e0fed3b3f9026e37c4f94a45a3c8 [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"
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05005
6namespace openpower
7{
8namespace software
9{
10namespace updater
11{
12
Adriana Kobylak55f9e832017-05-14 16:13:00 -050013namespace fs = std::experimental::filesystem;
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050014namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
15
Michael Tritz9d25b602017-06-14 14:41:43 -050016constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
17constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
18
19void Activation::subscribeToSystemdSignals()
20{
21 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
22 SYSTEMD_OBJ_PATH,
23 SYSTEMD_INTERFACE,
24 "Subscribe");
25 this->bus.call_noreply(method);
26
27 return;
28}
29
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -050030auto Activation::activation(Activations value) ->
31 Activations
32{
Saqib Khan942df8a2017-06-01 14:09:27 -050033
34 if (value != softwareServer::Activation::Activations::Active)
35 {
36 redundancyPriority.reset(nullptr);
37 }
38
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050039 if (value == softwareServer::Activation::Activations::Activating)
40 {
Adriana Kobylak2fdb9312017-05-14 19:08:26 -050041 softwareServer::Activation::activation(value);
42
Michael Tritz9d25b602017-06-14 14:41:43 -050043 if (squashfsLoaded == false && rwVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050044 {
Michael Tritz9d25b602017-06-14 14:41:43 -050045 // If the squashfs image has not yet been loaded to pnor and the
46 // RW volumes have not yet been created, we need to start the
47 // service files for each of those actions.
Saqib Khan1e9b7162017-04-18 10:21:59 -050048
Michael Tritz9d25b602017-06-14 14:41:43 -050049 if (!activationBlocksTransition)
Adriana Kobylak55f9e832017-05-14 16:13:00 -050050 {
Michael Tritz9d25b602017-06-14 14:41:43 -050051 activationBlocksTransition =
52 std::make_unique<ActivationBlocksTransition>(
Saqib Khan942df8a2017-06-01 14:09:27 -050053 bus,
54 path);
55 }
56
Michael Tritz9d25b602017-06-14 14:41:43 -050057 constexpr auto squashfsMountService =
58 "obmc-flash-bios-squashfsmount@";
59 auto squashfsMountServiceFile = std::string(squashfsMountService) +
60 versionId + ".service";
61 auto method = bus.new_method_call(
62 SYSTEMD_BUSNAME,
63 SYSTEMD_PATH,
64 SYSTEMD_INTERFACE,
65 "StartUnit");
66 method.append(squashfsMountServiceFile, "replace");
67 bus.call_noreply(method);
68
69 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
70 auto ubimountServiceFile = std::string(ubimountService) +
71 versionId +
72 ".service";
73 method = bus.new_method_call(
74 SYSTEMD_BUSNAME,
75 SYSTEMD_PATH,
76 SYSTEMD_INTERFACE,
77 "StartUnit");
78 method.append(ubimountServiceFile, "replace");
79 bus.call_noreply(method);
80
81 return softwareServer::Activation::activation(value);
82 }
83 else if (squashfsLoaded == true && rwVolumesCreated == true)
84 {
85 // Only when the squashfs image is finished loading AND the RW
86 // volumes have been created do we proceed with activation.
87
88 // The ubimount service files attemps to create the RW and Preserved
89 // UBI volumes. If the service fails, the mount dirs PNOR_PRSV
90 // and PNOR_RW_PREFIX_<versionid> won't be present. Check for the
91 // existence of those directories to validate the service file was
92 // successful, also for the existence of the RO directory where the
93 // image is supposed to reside.
94 if ((fs::is_directory(PNOR_PRSV)) &&
95 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
96 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
97 {
98 if (!fs::is_directory(PNOR_ACTIVE_PATH))
99 {
100 fs::create_directories(PNOR_ACTIVE_PATH);
101 }
102
103 // If the RW or RO active links exist, remove them and create new
104 // ones pointing to the active version.
105 if (fs::is_symlink(PNOR_RO_ACTIVE_PATH))
106 {
107 fs::remove(PNOR_RO_ACTIVE_PATH);
108 }
109 fs::create_directory_symlink(PNOR_RO_PREFIX + versionId,
110 PNOR_RO_ACTIVE_PATH);
111 if (fs::is_symlink(PNOR_RW_ACTIVE_PATH))
112 {
113 fs::remove(PNOR_RW_ACTIVE_PATH);
114 }
115 fs::create_directory_symlink(PNOR_RW_PREFIX + versionId,
116 PNOR_RW_ACTIVE_PATH);
117
118 // There is only one preserved directory as it is not tied to a
119 // version, so just create the link if it doesn't exist already.
120 if (!fs::is_symlink(PNOR_PRSV_ACTIVE_PATH))
121 {
122 fs::create_directory_symlink(PNOR_PRSV,
123 PNOR_PRSV_ACTIVE_PATH);
124 }
125
126 // Set Redundancy Priority before setting to Active
127 if (!redundancyPriority)
128 {
129 redundancyPriority =
130 std::make_unique<RedundancyPriority>(
131 bus,
Saqib Khan81bac882017-06-08 12:17:01 -0500132 path,
133 *this,
134 0);
Michael Tritz9d25b602017-06-14 14:41:43 -0500135 }
Saqib Khancb9df4e2017-06-26 11:06:07 -0500136 activationBlocksTransition.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500137 return softwareServer::Activation::activation(
138 softwareServer::Activation::Activations::Active);
139 }
140 else
141 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500142 activationBlocksTransition.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500143 return softwareServer::Activation::activation(
144 softwareServer::Activation::Activations::Failed);
145 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500146 }
147 else
148 {
Michael Tritz9d25b602017-06-14 14:41:43 -0500149 // If either the squashfs image has not yet been loaded or the RW
150 // volumes have not yet been created, the activation process is
151 // ongoing, so we return "Activating" status.
152 return softwareServer::Activation::activation(value);
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500153 }
Adriana Kobylak692b5552017-04-17 14:02:58 -0500154 }
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500155 else
156 {
157 activationBlocksTransition.reset(nullptr);
158 return softwareServer::Activation::activation(value);
159 }
160}
161
162auto Activation::requestedActivation(RequestedActivations value) ->
163 RequestedActivations
164{
Michael Tritz9d25b602017-06-14 14:41:43 -0500165 squashfsLoaded = false;
166 rwVolumesCreated = false;
167
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500168 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
169 (softwareServer::Activation::requestedActivation() !=
170 softwareServer::Activation::RequestedActivations::Active))
171 {
172 if ((softwareServer::Activation::activation() ==
173 softwareServer::Activation::Activations::Ready) ||
174 (softwareServer::Activation::activation() ==
175 softwareServer::Activation::Activations::Failed))
176 {
177 Activation::activation(
178 softwareServer::Activation::Activations::Activating);
179
180 }
181 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500182 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500183}
184
Saqib Khan2021b4c2017-06-07 14:37:36 -0500185uint8_t RedundancyPriority::priority(uint8_t value)
186{
Saqib Khan81bac882017-06-08 12:17:01 -0500187 parent.parent.freePriority(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 {
209 squashfsLoaded = true;
210 }
211
212 if(newStateUnit == ubimountServiceFile && newStateResult == "done")
213 {
214 rwVolumesCreated = true;
215 }
216
217 if(squashfsLoaded && rwVolumesCreated)
218 {
219 Activation::activation(
220 softwareServer::Activation::Activations::Activating);
221 }
222
223 if((newStateUnit == squashfsMountServiceFile ||
224 newStateUnit == ubimountServiceFile) &&
225 (newStateResult == "failed" || newStateResult == "dependency"))
226 {
227 Activation::activation(softwareServer::Activation::Activations::Failed);
228 }
229
230 return;
231}
232
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500233} // namespace updater
234} // namespace software
235} // namespace openpower