blob: 3b28c731aee0e6fe2fc620060bbf22ed72400e5f [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"
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -05004
5namespace openpower
6{
7namespace software
8{
9namespace updater
10{
11
Adriana Kobylak55f9e832017-05-14 16:13:00 -050012namespace fs = std::experimental::filesystem;
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050013namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
14
Michael Tritz9d25b602017-06-14 14:41:43 -050015constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
16constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
17
18void Activation::subscribeToSystemdSignals()
19{
20 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
21 SYSTEMD_OBJ_PATH,
22 SYSTEMD_INTERFACE,
23 "Subscribe");
24 this->bus.call_noreply(method);
25
26 return;
27}
28
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -050029auto Activation::activation(Activations value) ->
30 Activations
31{
Saqib Khan942df8a2017-06-01 14:09:27 -050032
33 if (value != softwareServer::Activation::Activations::Active)
34 {
35 redundancyPriority.reset(nullptr);
36 }
37
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050038 if (value == softwareServer::Activation::Activations::Activating)
39 {
Adriana Kobylak2fdb9312017-05-14 19:08:26 -050040 softwareServer::Activation::activation(value);
41
Michael Tritz9d25b602017-06-14 14:41:43 -050042 if (squashfsLoaded == false && rwVolumesCreated == false)
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -050043 {
Michael Tritz9d25b602017-06-14 14:41:43 -050044 // If 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.
Saqib Khan1e9b7162017-04-18 10:21:59 -050047
Michael Tritz9d25b602017-06-14 14:41:43 -050048 if (!activationBlocksTransition)
Adriana Kobylak55f9e832017-05-14 16:13:00 -050049 {
Michael Tritz9d25b602017-06-14 14:41:43 -050050 activationBlocksTransition =
51 std::make_unique<ActivationBlocksTransition>(
Saqib Khan942df8a2017-06-01 14:09:27 -050052 bus,
53 path);
54 }
55
Michael Tritz9d25b602017-06-14 14:41:43 -050056 constexpr auto squashfsMountService =
57 "obmc-flash-bios-squashfsmount@";
58 auto squashfsMountServiceFile = std::string(squashfsMountService) +
59 versionId + ".service";
60 auto method = bus.new_method_call(
61 SYSTEMD_BUSNAME,
62 SYSTEMD_PATH,
63 SYSTEMD_INTERFACE,
64 "StartUnit");
65 method.append(squashfsMountServiceFile, "replace");
66 bus.call_noreply(method);
67
68 constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
69 auto ubimountServiceFile = std::string(ubimountService) +
70 versionId +
71 ".service";
72 method = bus.new_method_call(
73 SYSTEMD_BUSNAME,
74 SYSTEMD_PATH,
75 SYSTEMD_INTERFACE,
76 "StartUnit");
77 method.append(ubimountServiceFile, "replace");
78 bus.call_noreply(method);
79
80 return softwareServer::Activation::activation(value);
81 }
82 else if (squashfsLoaded == true && rwVolumesCreated == true)
83 {
84 // Only when the squashfs image is finished loading AND the RW
85 // volumes have been created do we proceed with activation.
86
87 // The ubimount service files attemps to create the RW and Preserved
88 // UBI volumes. If the service fails, the mount dirs PNOR_PRSV
89 // and PNOR_RW_PREFIX_<versionid> won't be present. Check for the
90 // existence of those directories to validate the service file was
91 // successful, also for the existence of the RO directory where the
92 // image is supposed to reside.
93 if ((fs::is_directory(PNOR_PRSV)) &&
94 (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
95 (fs::is_directory(PNOR_RO_PREFIX + versionId)))
96 {
97 if (!fs::is_directory(PNOR_ACTIVE_PATH))
98 {
99 fs::create_directories(PNOR_ACTIVE_PATH);
100 }
101
102 // If the RW or RO active links exist, remove them and create new
103 // ones pointing to the active version.
104 if (fs::is_symlink(PNOR_RO_ACTIVE_PATH))
105 {
106 fs::remove(PNOR_RO_ACTIVE_PATH);
107 }
108 fs::create_directory_symlink(PNOR_RO_PREFIX + versionId,
109 PNOR_RO_ACTIVE_PATH);
110 if (fs::is_symlink(PNOR_RW_ACTIVE_PATH))
111 {
112 fs::remove(PNOR_RW_ACTIVE_PATH);
113 }
114 fs::create_directory_symlink(PNOR_RW_PREFIX + versionId,
115 PNOR_RW_ACTIVE_PATH);
116
117 // There is only one preserved directory as it is not tied to a
118 // version, so just create the link if it doesn't exist already.
119 if (!fs::is_symlink(PNOR_PRSV_ACTIVE_PATH))
120 {
121 fs::create_directory_symlink(PNOR_PRSV,
122 PNOR_PRSV_ACTIVE_PATH);
123 }
124
125 // Set Redundancy Priority before setting to Active
126 if (!redundancyPriority)
127 {
128 redundancyPriority =
129 std::make_unique<RedundancyPriority>(
130 bus,
131 path);
132 }
Saqib Khancb9df4e2017-06-26 11:06:07 -0500133 activationBlocksTransition.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500134 return softwareServer::Activation::activation(
135 softwareServer::Activation::Activations::Active);
136 }
137 else
138 {
Saqib Khancb9df4e2017-06-26 11:06:07 -0500139 activationBlocksTransition.reset(nullptr);
Michael Tritz9d25b602017-06-14 14:41:43 -0500140 return softwareServer::Activation::activation(
141 softwareServer::Activation::Activations::Failed);
142 }
Adriana Kobylak55f9e832017-05-14 16:13:00 -0500143 }
144 else
145 {
Michael Tritz9d25b602017-06-14 14:41:43 -0500146 // If either the squashfs image has not yet been loaded or the RW
147 // volumes have not yet been created, the activation process is
148 // ongoing, so we return "Activating" status.
149 return softwareServer::Activation::activation(value);
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);
155 return softwareServer::Activation::activation(value);
156 }
157}
158
159auto Activation::requestedActivation(RequestedActivations value) ->
160 RequestedActivations
161{
Michael Tritz9d25b602017-06-14 14:41:43 -0500162 squashfsLoaded = false;
163 rwVolumesCreated = false;
164
Adriana Kobylak2fdb9312017-05-14 19:08:26 -0500165 if ((value == softwareServer::Activation::RequestedActivations::Active) &&
166 (softwareServer::Activation::requestedActivation() !=
167 softwareServer::Activation::RequestedActivations::Active))
168 {
169 if ((softwareServer::Activation::activation() ==
170 softwareServer::Activation::Activations::Ready) ||
171 (softwareServer::Activation::activation() ==
172 softwareServer::Activation::Activations::Failed))
173 {
174 Activation::activation(
175 softwareServer::Activation::Activations::Activating);
176
177 }
178 }
Adriana Kobylak99c8c0e2017-04-17 13:39:11 -0500179 return softwareServer::Activation::requestedActivation(value);
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500180}
181
Saqib Khan2021b4c2017-06-07 14:37:36 -0500182uint8_t RedundancyPriority::priority(uint8_t value)
183{
184 return softwareServer::RedundancyPriority::priority(value);
185}
186
Michael Tritz9d25b602017-06-14 14:41:43 -0500187void Activation::unitStateChange(sdbusplus::message::message& msg)
188{
189 uint32_t newStateID {};
190 sdbusplus::message::object_path newStateObjPath;
191 std::string newStateUnit{};
192 std::string newStateResult{};
193
194 //Read the msg and populate each variable
195 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
196
197 auto squashfsMountServiceFile =
198 "obmc-flash-bios-squashfsmount@" + versionId + ".service";
199
200 auto ubimountServiceFile =
201 "obmc-flash-bios-ubimount@" + versionId + ".service";
202
203 if(newStateUnit == squashfsMountServiceFile && newStateResult == "done")
204 {
205 squashfsLoaded = true;
206 }
207
208 if(newStateUnit == ubimountServiceFile && newStateResult == "done")
209 {
210 rwVolumesCreated = true;
211 }
212
213 if(squashfsLoaded && rwVolumesCreated)
214 {
215 Activation::activation(
216 softwareServer::Activation::Activations::Activating);
217 }
218
219 if((newStateUnit == squashfsMountServiceFile ||
220 newStateUnit == ubimountServiceFile) &&
221 (newStateResult == "failed" || newStateResult == "dependency"))
222 {
223 Activation::activation(softwareServer::Activation::Activations::Failed);
224 }
225
226 return;
227}
228
Adriana Kobylakbefe5ce2017-04-05 15:57:44 -0500229} // namespace updater
230} // namespace software
231} // namespace openpower