1 *cab87e9cSJagpal Singh Gill #include "activation.hpp"
2 *cab87e9cSJagpal Singh Gill
3 *cab87e9cSJagpal Singh Gill #include "images.hpp"
4 *cab87e9cSJagpal Singh Gill #include "item_updater.hpp"
5 *cab87e9cSJagpal Singh Gill #include "msl_verify.hpp"
6 *cab87e9cSJagpal Singh Gill #include "serialize.hpp"
7 *cab87e9cSJagpal Singh Gill
8 *cab87e9cSJagpal Singh Gill #include <boost/asio/io_context.hpp>
9 *cab87e9cSJagpal Singh Gill #include <boost/asio/post.hpp>
10 *cab87e9cSJagpal Singh Gill #include <phosphor-logging/elog-errors.hpp>
11 *cab87e9cSJagpal Singh Gill #include <phosphor-logging/elog.hpp>
12 *cab87e9cSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
13 *cab87e9cSJagpal Singh Gill #include <sdbusplus/exception.hpp>
14 *cab87e9cSJagpal Singh Gill #include <xyz/openbmc_project/Common/error.hpp>
15 *cab87e9cSJagpal Singh Gill #include <xyz/openbmc_project/Software/Version/error.hpp>
16 *cab87e9cSJagpal Singh Gill
17 *cab87e9cSJagpal Singh Gill #ifdef WANT_SIGNATURE_VERIFY
18 *cab87e9cSJagpal Singh Gill #include "image_verify.hpp"
19 *cab87e9cSJagpal Singh Gill #endif
20 *cab87e9cSJagpal Singh Gill
21 *cab87e9cSJagpal Singh Gill extern boost::asio::io_context& getIOContext();
22 *cab87e9cSJagpal Singh Gill
23 *cab87e9cSJagpal Singh Gill namespace phosphor
24 *cab87e9cSJagpal Singh Gill {
25 *cab87e9cSJagpal Singh Gill namespace software
26 *cab87e9cSJagpal Singh Gill {
27 *cab87e9cSJagpal Singh Gill namespace updater
28 *cab87e9cSJagpal Singh Gill {
29 *cab87e9cSJagpal Singh Gill
30 *cab87e9cSJagpal Singh Gill namespace softwareServer = sdbusplus::server::xyz::openbmc_project::software;
31 *cab87e9cSJagpal Singh Gill
32 *cab87e9cSJagpal Singh Gill PHOSPHOR_LOG2_USING;
33 *cab87e9cSJagpal Singh Gill using namespace phosphor::logging;
34 *cab87e9cSJagpal Singh Gill using InternalFailure =
35 *cab87e9cSJagpal Singh Gill sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
36 *cab87e9cSJagpal Singh Gill
37 *cab87e9cSJagpal Singh Gill #ifdef WANT_SIGNATURE_VERIFY
38 *cab87e9cSJagpal Singh Gill namespace control = sdbusplus::server::xyz::openbmc_project::control;
39 *cab87e9cSJagpal Singh Gill #endif
40 *cab87e9cSJagpal Singh Gill
subscribeToSystemdSignals()41 *cab87e9cSJagpal Singh Gill void Activation::subscribeToSystemdSignals()
42 *cab87e9cSJagpal Singh Gill {
43 *cab87e9cSJagpal Singh Gill auto method = this->bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
44 *cab87e9cSJagpal Singh Gill SYSTEMD_INTERFACE, "Subscribe");
45 *cab87e9cSJagpal Singh Gill try
46 *cab87e9cSJagpal Singh Gill {
47 *cab87e9cSJagpal Singh Gill this->bus.call_noreply(method);
48 *cab87e9cSJagpal Singh Gill }
49 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
50 *cab87e9cSJagpal Singh Gill {
51 *cab87e9cSJagpal Singh Gill if (e.name() != nullptr &&
52 *cab87e9cSJagpal Singh Gill strcmp("org.freedesktop.systemd1.AlreadySubscribed", e.name()) == 0)
53 *cab87e9cSJagpal Singh Gill {
54 *cab87e9cSJagpal Singh Gill // If an Activation attempt fails, the Unsubscribe method is not
55 *cab87e9cSJagpal Singh Gill // called. This may lead to an AlreadySubscribed error if the
56 *cab87e9cSJagpal Singh Gill // Activation is re-attempted.
57 *cab87e9cSJagpal Singh Gill }
58 *cab87e9cSJagpal Singh Gill else
59 *cab87e9cSJagpal Singh Gill {
60 *cab87e9cSJagpal Singh Gill error("Error subscribing to systemd: {ERROR}", "ERROR", e);
61 *cab87e9cSJagpal Singh Gill }
62 *cab87e9cSJagpal Singh Gill }
63 *cab87e9cSJagpal Singh Gill
64 *cab87e9cSJagpal Singh Gill return;
65 *cab87e9cSJagpal Singh Gill }
66 *cab87e9cSJagpal Singh Gill
unsubscribeFromSystemdSignals()67 *cab87e9cSJagpal Singh Gill void Activation::unsubscribeFromSystemdSignals()
68 *cab87e9cSJagpal Singh Gill {
69 *cab87e9cSJagpal Singh Gill auto method = this->bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
70 *cab87e9cSJagpal Singh Gill SYSTEMD_INTERFACE, "Unsubscribe");
71 *cab87e9cSJagpal Singh Gill try
72 *cab87e9cSJagpal Singh Gill {
73 *cab87e9cSJagpal Singh Gill this->bus.call_noreply(method);
74 *cab87e9cSJagpal Singh Gill }
75 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
76 *cab87e9cSJagpal Singh Gill {
77 *cab87e9cSJagpal Singh Gill error("Error unsubscribing from systemd signals: {ERROR}", "ERROR", e);
78 *cab87e9cSJagpal Singh Gill }
79 *cab87e9cSJagpal Singh Gill
80 *cab87e9cSJagpal Singh Gill return;
81 *cab87e9cSJagpal Singh Gill }
82 *cab87e9cSJagpal Singh Gill
activation(Activations value)83 *cab87e9cSJagpal Singh Gill auto Activation::activation(Activations value) -> Activations
84 *cab87e9cSJagpal Singh Gill {
85 *cab87e9cSJagpal Singh Gill if ((value != softwareServer::Activation::Activations::Active) &&
86 *cab87e9cSJagpal Singh Gill (value != softwareServer::Activation::Activations::Activating))
87 *cab87e9cSJagpal Singh Gill {
88 *cab87e9cSJagpal Singh Gill redundancyPriority.reset(nullptr);
89 *cab87e9cSJagpal Singh Gill }
90 *cab87e9cSJagpal Singh Gill
91 *cab87e9cSJagpal Singh Gill if (value == softwareServer::Activation::Activations::Activating)
92 *cab87e9cSJagpal Singh Gill {
93 *cab87e9cSJagpal Singh Gill #ifdef WANT_SIGNATURE_VERIFY
94 *cab87e9cSJagpal Singh Gill fs::path uploadDir(IMG_UPLOAD_DIR);
95 *cab87e9cSJagpal Singh Gill if (!verifySignature(uploadDir / versionId, SIGNED_IMAGE_CONF_PATH))
96 *cab87e9cSJagpal Singh Gill {
97 *cab87e9cSJagpal Singh Gill using InvalidSignatureErr = sdbusplus::error::xyz::openbmc_project::
98 *cab87e9cSJagpal Singh Gill software::version::InvalidSignature;
99 *cab87e9cSJagpal Singh Gill report<InvalidSignatureErr>();
100 *cab87e9cSJagpal Singh Gill // Stop the activation process, if fieldMode is enabled.
101 *cab87e9cSJagpal Singh Gill if (parent.control::FieldMode::fieldModeEnabled())
102 *cab87e9cSJagpal Singh Gill {
103 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::activation(
104 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Failed);
105 *cab87e9cSJagpal Singh Gill }
106 *cab87e9cSJagpal Singh Gill }
107 *cab87e9cSJagpal Singh Gill #endif
108 *cab87e9cSJagpal Singh Gill
109 *cab87e9cSJagpal Singh Gill auto versionStr = parent.versions.find(versionId)->second->version();
110 *cab87e9cSJagpal Singh Gill
111 *cab87e9cSJagpal Singh Gill if (!minimum_ship_level::verify(versionStr))
112 *cab87e9cSJagpal Singh Gill {
113 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::activation(
114 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Failed);
115 *cab87e9cSJagpal Singh Gill }
116 *cab87e9cSJagpal Singh Gill
117 *cab87e9cSJagpal Singh Gill if (!activationProgress)
118 *cab87e9cSJagpal Singh Gill {
119 *cab87e9cSJagpal Singh Gill activationProgress =
120 *cab87e9cSJagpal Singh Gill std::make_unique<ActivationProgress>(bus, path);
121 *cab87e9cSJagpal Singh Gill }
122 *cab87e9cSJagpal Singh Gill
123 *cab87e9cSJagpal Singh Gill if (!activationBlocksTransition)
124 *cab87e9cSJagpal Singh Gill {
125 *cab87e9cSJagpal Singh Gill activationBlocksTransition =
126 *cab87e9cSJagpal Singh Gill std::make_unique<ActivationBlocksTransition>(bus, path);
127 *cab87e9cSJagpal Singh Gill }
128 *cab87e9cSJagpal Singh Gill
129 *cab87e9cSJagpal Singh Gill #ifdef HOST_BIOS_UPGRADE
130 *cab87e9cSJagpal Singh Gill auto purpose = parent.versions.find(versionId)->second->purpose();
131 *cab87e9cSJagpal Singh Gill if (purpose == VersionPurpose::Host)
132 *cab87e9cSJagpal Singh Gill {
133 *cab87e9cSJagpal Singh Gill // Enable systemd signals
134 *cab87e9cSJagpal Singh Gill subscribeToSystemdSignals();
135 *cab87e9cSJagpal Singh Gill
136 *cab87e9cSJagpal Singh Gill // Set initial progress
137 *cab87e9cSJagpal Singh Gill activationProgress->progress(20);
138 *cab87e9cSJagpal Singh Gill
139 *cab87e9cSJagpal Singh Gill // Initiate image writing to flash
140 *cab87e9cSJagpal Singh Gill flashWriteHost();
141 *cab87e9cSJagpal Singh Gill
142 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::activation(value);
143 *cab87e9cSJagpal Singh Gill }
144 *cab87e9cSJagpal Singh Gill #endif
145 *cab87e9cSJagpal Singh Gill
146 *cab87e9cSJagpal Singh Gill activationProgress->progress(10);
147 *cab87e9cSJagpal Singh Gill
148 *cab87e9cSJagpal Singh Gill parent.freeSpace(*this);
149 *cab87e9cSJagpal Singh Gill
150 *cab87e9cSJagpal Singh Gill // Enable systemd signals
151 *cab87e9cSJagpal Singh Gill Activation::subscribeToSystemdSignals();
152 *cab87e9cSJagpal Singh Gill
153 *cab87e9cSJagpal Singh Gill flashWrite();
154 *cab87e9cSJagpal Singh Gill
155 *cab87e9cSJagpal Singh Gill #if defined UBIFS_LAYOUT || defined MMC_LAYOUT
156 *cab87e9cSJagpal Singh Gill
157 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::activation(value);
158 *cab87e9cSJagpal Singh Gill
159 *cab87e9cSJagpal Singh Gill #else // STATIC_LAYOUT
160 *cab87e9cSJagpal Singh Gill
161 *cab87e9cSJagpal Singh Gill if (parent.runningImageSlot == 0)
162 *cab87e9cSJagpal Singh Gill {
163 *cab87e9cSJagpal Singh Gill // On primary, update it as before
164 *cab87e9cSJagpal Singh Gill onFlashWriteSuccess();
165 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::activation(
166 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Active);
167 *cab87e9cSJagpal Singh Gill }
168 *cab87e9cSJagpal Singh Gill // On secondary, wait for the service to complete
169 *cab87e9cSJagpal Singh Gill #endif
170 *cab87e9cSJagpal Singh Gill }
171 *cab87e9cSJagpal Singh Gill else
172 *cab87e9cSJagpal Singh Gill {
173 *cab87e9cSJagpal Singh Gill activationBlocksTransition.reset(nullptr);
174 *cab87e9cSJagpal Singh Gill }
175 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::activation(value);
176 *cab87e9cSJagpal Singh Gill }
177 *cab87e9cSJagpal Singh Gill
onFlashWriteSuccess()178 *cab87e9cSJagpal Singh Gill void Activation::onFlashWriteSuccess()
179 *cab87e9cSJagpal Singh Gill {
180 *cab87e9cSJagpal Singh Gill activationProgress->progress(100);
181 *cab87e9cSJagpal Singh Gill
182 *cab87e9cSJagpal Singh Gill activationBlocksTransition.reset(nullptr);
183 *cab87e9cSJagpal Singh Gill activationProgress.reset(nullptr);
184 *cab87e9cSJagpal Singh Gill
185 *cab87e9cSJagpal Singh Gill rwVolumeCreated = false;
186 *cab87e9cSJagpal Singh Gill roVolumeCreated = false;
187 *cab87e9cSJagpal Singh Gill ubootEnvVarsUpdated = false;
188 *cab87e9cSJagpal Singh Gill Activation::unsubscribeFromSystemdSignals();
189 *cab87e9cSJagpal Singh Gill
190 *cab87e9cSJagpal Singh Gill auto flashId = parent.versions.find(versionId)->second->path();
191 *cab87e9cSJagpal Singh Gill storePurpose(flashId, parent.versions.find(versionId)->second->purpose());
192 *cab87e9cSJagpal Singh Gill
193 *cab87e9cSJagpal Singh Gill if (!redundancyPriority)
194 *cab87e9cSJagpal Singh Gill {
195 *cab87e9cSJagpal Singh Gill redundancyPriority =
196 *cab87e9cSJagpal Singh Gill std::make_unique<RedundancyPriority>(bus, path, *this, 0);
197 *cab87e9cSJagpal Singh Gill }
198 *cab87e9cSJagpal Singh Gill
199 *cab87e9cSJagpal Singh Gill if (!parent.useUpdateDBusInterface)
200 *cab87e9cSJagpal Singh Gill {
201 *cab87e9cSJagpal Singh Gill // Remove version object from image manager
202 *cab87e9cSJagpal Singh Gill Activation::deleteImageManagerObject();
203 *cab87e9cSJagpal Singh Gill }
204 *cab87e9cSJagpal Singh Gill
205 *cab87e9cSJagpal Singh Gill // Create active association
206 *cab87e9cSJagpal Singh Gill parent.createActiveAssociation(path);
207 *cab87e9cSJagpal Singh Gill
208 *cab87e9cSJagpal Singh Gill // Create updateable association as this
209 *cab87e9cSJagpal Singh Gill // can be re-programmed.
210 *cab87e9cSJagpal Singh Gill parent.createUpdateableAssociation(path);
211 *cab87e9cSJagpal Singh Gill
212 *cab87e9cSJagpal Singh Gill if (Activation::checkApplyTimeImmediate())
213 *cab87e9cSJagpal Singh Gill {
214 *cab87e9cSJagpal Singh Gill info("Image Active and ApplyTime is immediate; rebooting BMC.");
215 *cab87e9cSJagpal Singh Gill Activation::rebootBmc();
216 *cab87e9cSJagpal Singh Gill }
217 *cab87e9cSJagpal Singh Gill else
218 *cab87e9cSJagpal Singh Gill {
219 *cab87e9cSJagpal Singh Gill info("BMC image ready; need reboot to get activated.");
220 *cab87e9cSJagpal Singh Gill }
221 *cab87e9cSJagpal Singh Gill
222 *cab87e9cSJagpal Singh Gill // Create Update Object for this version.
223 *cab87e9cSJagpal Singh Gill parent.createUpdateObject(versionId, path);
224 *cab87e9cSJagpal Singh Gill
225 *cab87e9cSJagpal Singh Gill activation(softwareServer::Activation::Activations::Active);
226 *cab87e9cSJagpal Singh Gill }
227 *cab87e9cSJagpal Singh Gill
deleteImageManagerObject()228 *cab87e9cSJagpal Singh Gill void Activation::deleteImageManagerObject()
229 *cab87e9cSJagpal Singh Gill {
230 *cab87e9cSJagpal Singh Gill // Call the Delete object for <versionID> inside image_manager if the object
231 *cab87e9cSJagpal Singh Gill // has not already been deleted due to a successful update or Delete call
232 *cab87e9cSJagpal Singh Gill const std::string interface = std::string{VERSION_IFACE};
233 *cab87e9cSJagpal Singh Gill auto method = this->bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
234 *cab87e9cSJagpal Singh Gill MAPPER_BUSNAME, "GetObject");
235 *cab87e9cSJagpal Singh Gill method.append(path.c_str());
236 *cab87e9cSJagpal Singh Gill method.append(std::vector<std::string>({interface}));
237 *cab87e9cSJagpal Singh Gill
238 *cab87e9cSJagpal Singh Gill std::map<std::string, std::vector<std::string>> response;
239 *cab87e9cSJagpal Singh Gill
240 *cab87e9cSJagpal Singh Gill try
241 *cab87e9cSJagpal Singh Gill {
242 *cab87e9cSJagpal Singh Gill auto reply = bus.call(method);
243 *cab87e9cSJagpal Singh Gill reply.read(response);
244 *cab87e9cSJagpal Singh Gill auto it = response.find(VERSION_IFACE);
245 *cab87e9cSJagpal Singh Gill if (it != response.end())
246 *cab87e9cSJagpal Singh Gill {
247 *cab87e9cSJagpal Singh Gill auto deleteMethod = this->bus.new_method_call(
248 *cab87e9cSJagpal Singh Gill VERSION_BUSNAME, path.c_str(),
249 *cab87e9cSJagpal Singh Gill "xyz.openbmc_project.Object.Delete", "Delete");
250 *cab87e9cSJagpal Singh Gill try
251 *cab87e9cSJagpal Singh Gill {
252 *cab87e9cSJagpal Singh Gill bus.call_noreply(deleteMethod);
253 *cab87e9cSJagpal Singh Gill }
254 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
255 *cab87e9cSJagpal Singh Gill {
256 *cab87e9cSJagpal Singh Gill error(
257 *cab87e9cSJagpal Singh Gill "Error deleting image ({PATH}) from image manager: {ERROR}",
258 *cab87e9cSJagpal Singh Gill "PATH", path, "ERROR", e);
259 *cab87e9cSJagpal Singh Gill return;
260 *cab87e9cSJagpal Singh Gill }
261 *cab87e9cSJagpal Singh Gill }
262 *cab87e9cSJagpal Singh Gill }
263 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
264 *cab87e9cSJagpal Singh Gill {
265 *cab87e9cSJagpal Singh Gill error("Error in mapper method call for ({PATH}, {INTERFACE}: {ERROR}",
266 *cab87e9cSJagpal Singh Gill "ERROR", e, "PATH", path, "INTERFACE", interface);
267 *cab87e9cSJagpal Singh Gill }
268 *cab87e9cSJagpal Singh Gill return;
269 *cab87e9cSJagpal Singh Gill }
270 *cab87e9cSJagpal Singh Gill
requestedActivation(RequestedActivations value)271 *cab87e9cSJagpal Singh Gill auto Activation::requestedActivation(RequestedActivations value)
272 *cab87e9cSJagpal Singh Gill -> RequestedActivations
273 *cab87e9cSJagpal Singh Gill {
274 *cab87e9cSJagpal Singh Gill rwVolumeCreated = false;
275 *cab87e9cSJagpal Singh Gill roVolumeCreated = false;
276 *cab87e9cSJagpal Singh Gill ubootEnvVarsUpdated = false;
277 *cab87e9cSJagpal Singh Gill
278 *cab87e9cSJagpal Singh Gill if ((value == softwareServer::Activation::RequestedActivations::Active) &&
279 *cab87e9cSJagpal Singh Gill (softwareServer::Activation::requestedActivation() !=
280 *cab87e9cSJagpal Singh Gill softwareServer::Activation::RequestedActivations::Active))
281 *cab87e9cSJagpal Singh Gill {
282 *cab87e9cSJagpal Singh Gill if ((softwareServer::Activation::activation() ==
283 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Ready) ||
284 *cab87e9cSJagpal Singh Gill (softwareServer::Activation::activation() ==
285 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Failed))
286 *cab87e9cSJagpal Singh Gill {
287 *cab87e9cSJagpal Singh Gill Activation::activation(
288 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Activating);
289 *cab87e9cSJagpal Singh Gill }
290 *cab87e9cSJagpal Singh Gill }
291 *cab87e9cSJagpal Singh Gill return softwareServer::Activation::requestedActivation(value);
292 *cab87e9cSJagpal Singh Gill }
293 *cab87e9cSJagpal Singh Gill
priority(uint8_t value)294 *cab87e9cSJagpal Singh Gill uint8_t RedundancyPriority::priority(uint8_t value)
295 *cab87e9cSJagpal Singh Gill {
296 *cab87e9cSJagpal Singh Gill // Set the priority value so that the freePriority() function can order
297 *cab87e9cSJagpal Singh Gill // the versions by priority.
298 *cab87e9cSJagpal Singh Gill auto newPriority = softwareServer::RedundancyPriority::priority(value);
299 *cab87e9cSJagpal Singh Gill parent.parent.savePriority(parent.versionId, value);
300 *cab87e9cSJagpal Singh Gill parent.parent.freePriority(value, parent.versionId);
301 *cab87e9cSJagpal Singh Gill return newPriority;
302 *cab87e9cSJagpal Singh Gill }
303 *cab87e9cSJagpal Singh Gill
sdbusPriority(uint8_t value)304 *cab87e9cSJagpal Singh Gill uint8_t RedundancyPriority::sdbusPriority(uint8_t value)
305 *cab87e9cSJagpal Singh Gill {
306 *cab87e9cSJagpal Singh Gill parent.parent.savePriority(parent.versionId, value);
307 *cab87e9cSJagpal Singh Gill return softwareServer::RedundancyPriority::priority(value);
308 *cab87e9cSJagpal Singh Gill }
309 *cab87e9cSJagpal Singh Gill
unitStateChange(sdbusplus::message_t & msg)310 *cab87e9cSJagpal Singh Gill void Activation::unitStateChange(sdbusplus::message_t& msg)
311 *cab87e9cSJagpal Singh Gill {
312 *cab87e9cSJagpal Singh Gill if (softwareServer::Activation::activation() !=
313 *cab87e9cSJagpal Singh Gill softwareServer::Activation::Activations::Activating)
314 *cab87e9cSJagpal Singh Gill {
315 *cab87e9cSJagpal Singh Gill return;
316 *cab87e9cSJagpal Singh Gill }
317 *cab87e9cSJagpal Singh Gill
318 *cab87e9cSJagpal Singh Gill #ifdef HOST_BIOS_UPGRADE
319 *cab87e9cSJagpal Singh Gill auto purpose = parent.versions.find(versionId)->second->purpose();
320 *cab87e9cSJagpal Singh Gill if (purpose == VersionPurpose::Host)
321 *cab87e9cSJagpal Singh Gill {
322 *cab87e9cSJagpal Singh Gill onStateChangesBios(msg);
323 *cab87e9cSJagpal Singh Gill return;
324 *cab87e9cSJagpal Singh Gill }
325 *cab87e9cSJagpal Singh Gill #endif
326 *cab87e9cSJagpal Singh Gill
327 *cab87e9cSJagpal Singh Gill onStateChanges(msg);
328 *cab87e9cSJagpal Singh Gill
329 *cab87e9cSJagpal Singh Gill return;
330 *cab87e9cSJagpal Singh Gill }
331 *cab87e9cSJagpal Singh Gill
332 *cab87e9cSJagpal Singh Gill #ifdef WANT_SIGNATURE_VERIFY
verifySignature(const fs::path & imageDir,const fs::path & confDir)333 *cab87e9cSJagpal Singh Gill bool Activation::verifySignature(const fs::path& imageDir,
334 *cab87e9cSJagpal Singh Gill const fs::path& confDir)
335 *cab87e9cSJagpal Singh Gill {
336 *cab87e9cSJagpal Singh Gill using Signature = phosphor::software::image::Signature;
337 *cab87e9cSJagpal Singh Gill
338 *cab87e9cSJagpal Singh Gill Signature signature(imageDir, confDir);
339 *cab87e9cSJagpal Singh Gill
340 *cab87e9cSJagpal Singh Gill return signature.verify();
341 *cab87e9cSJagpal Singh Gill }
342 *cab87e9cSJagpal Singh Gill #endif
343 *cab87e9cSJagpal Singh Gill
enableRebootGuard()344 *cab87e9cSJagpal Singh Gill void ActivationBlocksTransition::enableRebootGuard()
345 *cab87e9cSJagpal Singh Gill {
346 *cab87e9cSJagpal Singh Gill info("BMC image activating - BMC reboots are disabled.");
347 *cab87e9cSJagpal Singh Gill
348 *cab87e9cSJagpal Singh Gill auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
349 *cab87e9cSJagpal Singh Gill SYSTEMD_INTERFACE, "StartUnit");
350 *cab87e9cSJagpal Singh Gill method.append("reboot-guard-enable.service", "replace");
351 *cab87e9cSJagpal Singh Gill bus.call_noreply(method);
352 *cab87e9cSJagpal Singh Gill }
353 *cab87e9cSJagpal Singh Gill
disableRebootGuard()354 *cab87e9cSJagpal Singh Gill void ActivationBlocksTransition::disableRebootGuard()
355 *cab87e9cSJagpal Singh Gill {
356 *cab87e9cSJagpal Singh Gill info("BMC activation has ended - BMC reboots are re-enabled.");
357 *cab87e9cSJagpal Singh Gill
358 *cab87e9cSJagpal Singh Gill auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
359 *cab87e9cSJagpal Singh Gill SYSTEMD_INTERFACE, "StartUnit");
360 *cab87e9cSJagpal Singh Gill method.append("reboot-guard-disable.service", "replace");
361 *cab87e9cSJagpal Singh Gill bus.call_noreply(method);
362 *cab87e9cSJagpal Singh Gill }
363 *cab87e9cSJagpal Singh Gill
checkApplyTimeImmediate()364 *cab87e9cSJagpal Singh Gill bool Activation::checkApplyTimeImmediate()
365 *cab87e9cSJagpal Singh Gill {
366 *cab87e9cSJagpal Singh Gill if (parent.useUpdateDBusInterface)
367 *cab87e9cSJagpal Singh Gill {
368 *cab87e9cSJagpal Singh Gill return (applyTime == ApplyTimeIntf::RequestedApplyTimes::Immediate);
369 *cab87e9cSJagpal Singh Gill }
370 *cab87e9cSJagpal Singh Gill auto service = utils::getService(bus, applyTimeObjPath, applyTimeIntf);
371 *cab87e9cSJagpal Singh Gill if (service.empty())
372 *cab87e9cSJagpal Singh Gill {
373 *cab87e9cSJagpal Singh Gill info("Error getting the service name for BMC image ApplyTime. "
374 *cab87e9cSJagpal Singh Gill "The BMC needs to be manually rebooted to complete the image "
375 *cab87e9cSJagpal Singh Gill "activation if needed immediately.");
376 *cab87e9cSJagpal Singh Gill }
377 *cab87e9cSJagpal Singh Gill else
378 *cab87e9cSJagpal Singh Gill {
379 *cab87e9cSJagpal Singh Gill auto method = bus.new_method_call(service.c_str(), applyTimeObjPath,
380 *cab87e9cSJagpal Singh Gill dbusPropIntf, "Get");
381 *cab87e9cSJagpal Singh Gill method.append(applyTimeIntf, applyTimeProp);
382 *cab87e9cSJagpal Singh Gill
383 *cab87e9cSJagpal Singh Gill try
384 *cab87e9cSJagpal Singh Gill {
385 *cab87e9cSJagpal Singh Gill auto reply = bus.call(method);
386 *cab87e9cSJagpal Singh Gill
387 *cab87e9cSJagpal Singh Gill std::variant<std::string> result;
388 *cab87e9cSJagpal Singh Gill reply.read(result);
389 *cab87e9cSJagpal Singh Gill auto applyTime = std::get<std::string>(result);
390 *cab87e9cSJagpal Singh Gill if (applyTime == applyTimeImmediate)
391 *cab87e9cSJagpal Singh Gill {
392 *cab87e9cSJagpal Singh Gill return true;
393 *cab87e9cSJagpal Singh Gill }
394 *cab87e9cSJagpal Singh Gill }
395 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
396 *cab87e9cSJagpal Singh Gill {
397 *cab87e9cSJagpal Singh Gill error("Error in getting ApplyTime: {ERROR}", "ERROR", e);
398 *cab87e9cSJagpal Singh Gill }
399 *cab87e9cSJagpal Singh Gill }
400 *cab87e9cSJagpal Singh Gill return false;
401 *cab87e9cSJagpal Singh Gill }
402 *cab87e9cSJagpal Singh Gill
403 *cab87e9cSJagpal Singh Gill #ifdef HOST_BIOS_UPGRADE
flashWriteHost()404 *cab87e9cSJagpal Singh Gill void Activation::flashWriteHost()
405 *cab87e9cSJagpal Singh Gill {
406 *cab87e9cSJagpal Singh Gill auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
407 *cab87e9cSJagpal Singh Gill SYSTEMD_INTERFACE, "StartUnit");
408 *cab87e9cSJagpal Singh Gill auto biosServiceFile = "obmc-flash-host-bios@" + versionId + ".service";
409 *cab87e9cSJagpal Singh Gill method.append(biosServiceFile, "replace");
410 *cab87e9cSJagpal Singh Gill try
411 *cab87e9cSJagpal Singh Gill {
412 *cab87e9cSJagpal Singh Gill auto reply = bus.call(method);
413 *cab87e9cSJagpal Singh Gill }
414 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
415 *cab87e9cSJagpal Singh Gill {
416 *cab87e9cSJagpal Singh Gill error("Error in trying to upgrade Host Bios: {ERROR}", "ERROR", e);
417 *cab87e9cSJagpal Singh Gill report<InternalFailure>();
418 *cab87e9cSJagpal Singh Gill }
419 *cab87e9cSJagpal Singh Gill }
420 *cab87e9cSJagpal Singh Gill
onStateChangesBios(sdbusplus::message_t & msg)421 *cab87e9cSJagpal Singh Gill void Activation::onStateChangesBios(sdbusplus::message_t& msg)
422 *cab87e9cSJagpal Singh Gill {
423 *cab87e9cSJagpal Singh Gill uint32_t newStateID{};
424 *cab87e9cSJagpal Singh Gill sdbusplus::message::object_path newStateObjPath;
425 *cab87e9cSJagpal Singh Gill std::string newStateUnit{};
426 *cab87e9cSJagpal Singh Gill std::string newStateResult{};
427 *cab87e9cSJagpal Singh Gill
428 *cab87e9cSJagpal Singh Gill // Read the msg and populate each variable
429 *cab87e9cSJagpal Singh Gill msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
430 *cab87e9cSJagpal Singh Gill
431 *cab87e9cSJagpal Singh Gill auto biosServiceFile = "obmc-flash-host-bios@" + versionId + ".service";
432 *cab87e9cSJagpal Singh Gill
433 *cab87e9cSJagpal Singh Gill if (newStateUnit == biosServiceFile)
434 *cab87e9cSJagpal Singh Gill {
435 *cab87e9cSJagpal Singh Gill // unsubscribe to systemd signals
436 *cab87e9cSJagpal Singh Gill unsubscribeFromSystemdSignals();
437 *cab87e9cSJagpal Singh Gill
438 *cab87e9cSJagpal Singh Gill if (newStateResult == "done")
439 *cab87e9cSJagpal Singh Gill {
440 *cab87e9cSJagpal Singh Gill // Set activation progress to 100
441 *cab87e9cSJagpal Singh Gill activationProgress->progress(100);
442 *cab87e9cSJagpal Singh Gill
443 *cab87e9cSJagpal Singh Gill // Set Activation value to active
444 *cab87e9cSJagpal Singh Gill activation(softwareServer::Activation::Activations::Active);
445 *cab87e9cSJagpal Singh Gill
446 *cab87e9cSJagpal Singh Gill info("Bios upgrade completed successfully.");
447 *cab87e9cSJagpal Singh Gill parent.biosVersion->version(
448 *cab87e9cSJagpal Singh Gill parent.versions.find(versionId)->second->version());
449 *cab87e9cSJagpal Singh Gill
450 *cab87e9cSJagpal Singh Gill // Delete the uploaded activation
451 *cab87e9cSJagpal Singh Gill boost::asio::post(getIOContext(), [this]() {
452 *cab87e9cSJagpal Singh Gill this->parent.erase(this->versionId);
453 *cab87e9cSJagpal Singh Gill });
454 *cab87e9cSJagpal Singh Gill }
455 *cab87e9cSJagpal Singh Gill else if (newStateResult == "failed")
456 *cab87e9cSJagpal Singh Gill {
457 *cab87e9cSJagpal Singh Gill // Set Activation value to Failed
458 *cab87e9cSJagpal Singh Gill activation(softwareServer::Activation::Activations::Failed);
459 *cab87e9cSJagpal Singh Gill
460 *cab87e9cSJagpal Singh Gill error("Bios upgrade failed.");
461 *cab87e9cSJagpal Singh Gill }
462 *cab87e9cSJagpal Singh Gill }
463 *cab87e9cSJagpal Singh Gill
464 *cab87e9cSJagpal Singh Gill return;
465 *cab87e9cSJagpal Singh Gill }
466 *cab87e9cSJagpal Singh Gill
467 *cab87e9cSJagpal Singh Gill #endif
468 *cab87e9cSJagpal Singh Gill
rebootBmc()469 *cab87e9cSJagpal Singh Gill void Activation::rebootBmc()
470 *cab87e9cSJagpal Singh Gill {
471 *cab87e9cSJagpal Singh Gill auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
472 *cab87e9cSJagpal Singh Gill SYSTEMD_INTERFACE, "StartUnit");
473 *cab87e9cSJagpal Singh Gill method.append("force-reboot.service", "replace");
474 *cab87e9cSJagpal Singh Gill try
475 *cab87e9cSJagpal Singh Gill {
476 *cab87e9cSJagpal Singh Gill auto reply = bus.call(method);
477 *cab87e9cSJagpal Singh Gill }
478 *cab87e9cSJagpal Singh Gill catch (const sdbusplus::exception_t& e)
479 *cab87e9cSJagpal Singh Gill {
480 *cab87e9cSJagpal Singh Gill alert("Error in trying to reboot the BMC. The BMC needs to be manually "
481 *cab87e9cSJagpal Singh Gill "rebooted to complete the image activation. {ERROR}",
482 *cab87e9cSJagpal Singh Gill "ERROR", e);
483 *cab87e9cSJagpal Singh Gill report<InternalFailure>();
484 *cab87e9cSJagpal Singh Gill }
485 *cab87e9cSJagpal Singh Gill }
486 *cab87e9cSJagpal Singh Gill
487 *cab87e9cSJagpal Singh Gill } // namespace updater
488 *cab87e9cSJagpal Singh Gill } // namespace software
489 *cab87e9cSJagpal Singh Gill } // namespace phosphor
490