xref: /openbmc/phosphor-bmc-code-mgmt/bmc/activation.cpp (revision cab87e9cdeeb3e166d6d577511f6be4dc7721aca)
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