blob: 6274abe95e943d304811854c40d02a6e34e47df7 [file] [log] [blame]
Gunnar Millsec1b41c2017-05-02 12:20:36 -05001#pragma once
2
Gunnar Millsec1b41c2017-05-02 12:20:36 -05003#include "activation.hpp"
Lei YU56aaf452018-06-21 16:09:44 +08004#include "item_updater_helper.hpp"
Adriana Kobylak30352a62024-04-09 09:25:36 -05005#include "msl_verify.hpp"
Jagpal Singh Gill6d131aa2024-04-07 23:56:48 -07006#include "update_manager.hpp"
Saqib Khan705f1bf2017-06-09 23:58:38 -05007#include "version.hpp"
Gunnar Millsb0ce9962018-09-07 13:39:10 -05008#include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
9
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -070010#include <sdbusplus/async.hpp>
Gunnar Millsb0ce9962018-09-07 13:39:10 -050011#include <sdbusplus/server.hpp>
John Wang85c356f2019-09-11 16:20:13 +080012#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Michael Tritz37a59042017-07-12 13:44:53 -050013#include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
Michael Tritz0129d922017-08-10 19:33:46 -050014#include <xyz/openbmc_project/Control/FieldMode/server.hpp>
Adriana Kobylak30352a62024-04-09 09:25:36 -050015#include <xyz/openbmc_project/Software/MinimumVersion/server.hpp>
Gunnar Millsec1b41c2017-05-02 12:20:36 -050016
Adriana Kobylak58aa7502020-06-08 11:12:11 -050017#include <string>
Bright Cheng8e9ccfe2019-11-18 16:18:44 +080018#include <vector>
Adriana Kobylak58aa7502020-06-08 11:12:11 -050019
Gunnar Millsec1b41c2017-05-02 12:20:36 -050020namespace phosphor
21{
22namespace software
23{
24namespace updater
25{
26
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -070027using ActivationIntf =
28 sdbusplus::xyz::openbmc_project::Software::server::Activation;
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -050029using ItemUpdaterInherit = sdbusplus::server::object_t<
Patrick Williams1e9a5f12023-08-23 16:53:06 -050030 sdbusplus::server::xyz::openbmc_project::common::FactoryReset,
31 sdbusplus::server::xyz::openbmc_project::control::FieldMode,
32 sdbusplus::server::xyz::openbmc_project::association::Definitions,
33 sdbusplus::server::xyz::openbmc_project::collection::DeleteAll>;
Adriana Kobylak30352a62024-04-09 09:25:36 -050034using MinimumVersionInherit = sdbusplus::server::object_t<
35 sdbusplus::server::xyz::openbmc_project::software::MinimumVersion>;
Michael Tritz37a59042017-07-12 13:44:53 -050036
Patrick Williamse75d10f2017-05-30 16:56:32 -050037namespace MatchRules = sdbusplus::bus::match::rules;
Gunnar Mills48442912017-10-06 13:34:07 -050038using VersionClass = phosphor::software::manager::Version;
Gunnar Millsded875d2017-08-28 16:44:52 -050039using AssociationList =
Adriana Kobylak2285fe02018-02-27 15:36:59 -060040 std::vector<std::tuple<std::string, std::string, std::string>>;
Jagpal Singh Gill6d131aa2024-04-07 23:56:48 -070041using UpdateManager = phosphor::software::update::Manager;
Gunnar Millsded875d2017-08-28 16:44:52 -050042
Adriana Kobylak30352a62024-04-09 09:25:36 -050043/** @class MinimumVersion
44 * @brief OpenBMC MinimumVersion implementation.
45 * @details A concrete implementation for
46 * xyz.openbmc_project.Software.MinimumVersion DBus API.
47 */
48class MinimumVersion : public MinimumVersionInherit
49{
50 public:
51 /** @brief Constructs MinimumVersion
52 *
53 * @param[in] bus - The D-Bus bus object
54 * @param[in] path - The D-bus object path
55 */
56 MinimumVersion(sdbusplus::bus_t& bus, const std::string& path) :
57 MinimumVersionInherit(bus, path.c_str(), action::emit_interface_added)
58 {}
59};
60
Gunnar Millsec1b41c2017-05-02 12:20:36 -050061/** @class ItemUpdater
62 * @brief Manages the activation of the BMC version items.
63 */
Michael Tritz37a59042017-07-12 13:44:53 -050064class ItemUpdater : public ItemUpdaterInherit
Gunnar Millsec1b41c2017-05-02 12:20:36 -050065{
Adriana Kobylak2285fe02018-02-27 15:36:59 -060066 public:
67 /*
68 * @brief Types of Activation status for image validation.
69 */
70 enum class ActivationStatus
71 {
72 ready,
73 invalid,
74 active
75 };
Saqib Khan35e83f32017-05-22 11:37:32 -050076
Jagpal Singh Gilldd003f52024-08-13 15:45:50 -070077 /** @brief Types of Updater. */
78 enum class UpdaterType
79 {
80 BMC,
81 BIOS,
82 ALL
83 };
84
Adriana Kobylak2285fe02018-02-27 15:36:59 -060085 /** @brief Constructs ItemUpdater
86 *
87 * @param[in] bus - The D-Bus bus object
88 */
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -070089 ItemUpdater(sdbusplus::async::context& ctx, const std::string& path,
Jagpal Singh Gilldd003f52024-08-13 15:45:50 -070090 UpdaterType type = UpdaterType::ALL,
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -070091 bool useUpdateDBusInterface = true) :
92 ItemUpdaterInherit(ctx.get_bus(), path.c_str(),
Patrick Williams35aa9a82022-04-05 15:55:30 -050093 ItemUpdaterInherit::action::defer_emit),
Jagpal Singh Gill46f2a392024-11-04 18:02:28 -080094 type(type), useUpdateDBusInterface(useUpdateDBusInterface), ctx(ctx),
Jagpal Singh Gill6d131aa2024-04-07 23:56:48 -070095 bus(ctx.get_bus()), helper(bus)
Adriana Kobylak2285fe02018-02-27 15:36:59 -060096 {
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -070097 if (!useUpdateDBusInterface)
98 {
99 versionMatch = std::make_unique<sdbusplus::bus::match_t>(
100 bus,
101 MatchRules::interfacesAdded() +
102 MatchRules::path("/xyz/openbmc_project/software"),
103 std::bind(std::mem_fn(&ItemUpdater::createActivation), this,
104 std::placeholders::_1));
105 }
Lei YU531fbc22021-12-10 20:03:18 +0800106 getRunningSlot();
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600107 setBMCInventoryPath();
Jagpal Singh Gilldd003f52024-08-13 15:45:50 -0700108 if (type == UpdaterType::BMC || type == UpdaterType::ALL)
109 {
110 processBMCImage();
111 }
112 if (type == UpdaterType::BIOS || type == UpdaterType::ALL)
113 {
Lei YU6e9fb1d2021-02-19 18:01:40 +0800114#ifdef HOST_BIOS_UPGRADE
Jagpal Singh Gilldd003f52024-08-13 15:45:50 -0700115 createBIOSObject();
Lei YU6e9fb1d2021-02-19 18:01:40 +0800116#endif
Jagpal Singh Gilldd003f52024-08-13 15:45:50 -0700117 }
118 restoreFieldModeStatus();
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600119 emit_object_added();
120 };
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500121
Adriana Kobylakbbcb7be2018-07-17 15:47:34 -0500122 /** @brief Save priority value to persistent storage (flash and optionally
123 * a U-Boot environment variable)
124 *
125 * @param[in] versionId - The Id of the version
126 * @param[in] value - The priority value
127 * @return None
128 */
129 void savePriority(const std::string& versionId, uint8_t value);
130
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600131 /** @brief Sets the given priority free by incrementing
132 * any existing priority with the same value by 1
133 *
134 * @param[in] value - The priority that needs to be set free.
135 * @param[in] versionId - The Id of the version for which we
136 * are trying to free up the priority.
137 * @return None
138 */
139 void freePriority(uint8_t value, const std::string& versionId);
Saqib Khan4c1aec02017-07-06 11:46:13 -0500140
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600141 /**
142 * @brief Create and populate the active BMC Version.
143 */
144 void processBMCImage();
Saqib Khanba239882017-05-26 08:41:54 -0500145
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600146 /**
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -0700147 * @brief Verifies the image at filepath and creates the version and
148 * activation object. In case activation object already exists for the
149 * specified id, update the activation status based on image verification.
150 * @param[in] id - The unique identifier for the update.
151 * @param[in] path - The object path for the relevant objects.
152 * @param[in] version - The version of the image.
153 * @param[in] purpose - The purpose of the image.
154 * @param[in] extendedVersion The extended version of the image.
155 * @param[in] filePath - The file path where the image is located.
156 * @param[in] compatibleNames - The compatible name for the image.
157 * @param[out] Activations - Whether the image is ready to activate or not.
158 */
159 ActivationIntf::Activations verifyAndCreateObjects(
160 std::string& id, std::string& path, std::string& version,
161 VersionClass::VersionPurpose purpose, std::string& extendedVersion,
162 std ::string& filePath, std::vector<std::string>& compatibleNames);
163
164 /**
165 * @brief Creates the activation object
166 * @param[in] id - The unique identifier for the update.
167 * @param[in] path - The object path for the activation object.
168 * @param[in] applyTime - The apply time for the image
169 */
170 void createActivationWithApplyTime(
171 std::string& id, std::string& path,
172 ApplyTimeIntf::RequestedApplyTimes applyTime);
173
174 /**
175 * @brief Request the activation for the specified update.
176 * @param[in] id - The unique identifier for the update.
177 * @param[out] bool - status for the action.
178 */
179 bool requestActivation(std::string& id);
180
181 /**
182 * @brief Change the activation status for the specified update.
183 * @param[in] id - The unique identifier for the update.
184 * @param[in] status - The activation status to set.
185 * @param[out] bool - status for the action.
186 */
187 bool updateActivationStatus(std::string& id,
188 ActivationIntf::Activations status);
189
190 /**
Jagpal Singh Gill6d131aa2024-04-07 23:56:48 -0700191 * @brief Create the Update object
192 * @param[in] id - The unique identifier for the update.
193 * @param[in] path - The object path for the update object.
194 */
195 void createUpdateObject(const std::string& id, const std::string& path);
196
197 /**
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600198 * @brief Erase specified entry D-Bus object
199 * if Action property is not set to Active
200 *
201 * @param[in] entryId - unique identifier of the entry
202 */
203 void erase(std::string entryId);
Leonel Gonzalez3526ef72017-07-07 14:38:25 -0500204
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600205 /**
206 * @brief Deletes all versions except for the current one
207 */
Pavithra Barithaya36cc1c82024-06-22 00:41:28 -0500208 void deleteAll() override;
Gunnar Millsded875d2017-08-28 16:44:52 -0500209
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600210 /** @brief Creates an active association to the
211 * newly active software image
212 *
213 * @param[in] path - The path to create the association to.
214 */
215 void createActiveAssociation(const std::string& path);
Gunnar Millsded875d2017-08-28 16:44:52 -0500216
Adriana Kobylak991af7e2018-12-10 13:08:38 -0600217 /** @brief Removes the associations from the provided software image path
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600218 *
Adriana Kobylak991af7e2018-12-10 13:08:38 -0600219 * @param[in] path - The path to remove the associations from.
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600220 */
Adriana Kobylak991af7e2018-12-10 13:08:38 -0600221 void removeAssociations(const std::string& path);
Gunnar Millsded875d2017-08-28 16:44:52 -0500222
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600223 /** @brief Determine if the given priority is the lowest
224 *
225 * @param[in] value - The priority that needs to be checked.
226 *
227 * @return boolean corresponding to whether the given
228 * priority is lowest.
229 */
230 bool isLowestPriority(uint8_t value);
Saqib Khanb9da6632017-09-13 09:48:37 -0500231
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600232 /**
233 * @brief Updates the U-Boot variables to point to the requested
234 * versionId, so that the systems boots from this version on
235 * the next reboot.
236 *
237 * @param[in] versionId - The version to point the system to boot from.
238 */
239 void updateUbootEnvVars(const std::string& versionId);
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500240
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600241 /**
242 * @brief Updates the uboot variables to point to BMC version with lowest
243 * priority, so that the system boots from this version on the
244 * next boot.
245 */
246 void resetUbootEnvVars();
Saqib Khan49446ae2017-10-02 10:54:20 -0500247
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600248 /** @brief Brings the total number of active BMC versions to
249 * ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be
250 * run before activating a new BMC version. If this function
251 * needs to delete any BMC version(s) it will delete the
252 * version(s) with the highest priority, skipping the
253 * functional BMC version.
Adriana Kobylaka6963592018-09-07 14:13:29 -0500254 *
255 * @param[in] caller - The Activation object that called this function.
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600256 */
Lei YU0cd6d842021-12-27 11:56:02 +0800257 void freeSpace(const Activation& caller);
Adriana Kobylak204e1e72018-01-24 16:00:05 -0600258
AppaRao Puli1bb6dcb2020-03-27 20:51:57 +0530259 /** @brief Creates a updateable association to the
260 * "running" BMC software image
261 *
262 * @param[in] path - The path to create the association.
263 */
264 void createUpdateableAssociation(const std::string& path);
265
Adriana Kobylakec4eec32019-11-13 14:28:35 -0600266 /** @brief Persistent map of Version D-Bus objects and their
267 * version id */
268 std::map<std::string, std::unique_ptr<VersionClass>> versions;
269
Bright Cheng8e9ccfe2019-11-18 16:18:44 +0800270 /** @brief Vector of needed BMC images in the tarball*/
271 std::vector<std::string> imageUpdateList;
272
Manojkiran Eda19dd56b2024-06-17 14:29:52 +0530273 /** @brief The slot of running BMC image */
Lei YU531fbc22021-12-10 20:03:18 +0800274 uint32_t runningImageSlot = 0;
275
Jagpal Singh Gill46f2a392024-11-04 18:02:28 -0800276 /** @brief The type of updater. */
277 UpdaterType type;
278
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -0700279 /** @brief Flag to indicate if the update interface is used or not */
280 bool useUpdateDBusInterface;
281
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600282 private:
283 /** @brief Callback function for Software.Version match.
284 * @details Creates an Activation D-Bus object.
285 *
286 * @param[in] msg - Data associated with subscribed signal
287 */
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -0500288 void createActivation(sdbusplus::message_t& msg);
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500289
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600290 /**
291 * @brief Validates the presence of SquashFS image in the image dir.
292 *
293 * @param[in] filePath - The path to the image dir.
294 * @param[out] result - ActivationStatus Enum.
295 * ready if validation was successful.
296 * invalid if validation fail.
297 * active if image is the current version.
298 *
299 */
300 ActivationStatus validateSquashFSImage(const std::string& filePath);
Saqib Khan35e83f32017-05-22 11:37:32 -0500301
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600302 /** @brief BMC factory reset - marks the read-write partition for
303 * recreation upon reboot. */
304 void reset() override;
Michael Tritz37a59042017-07-12 13:44:53 -0500305
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600306 /**
307 * @brief Enables field mode, if value=true.
308 *
309 * @param[in] value - If true, enables field mode.
310 * @param[out] result - Returns the current state of field mode.
311 *
312 */
313 bool fieldModeEnabled(bool value) override;
Michael Tritz0129d922017-08-10 19:33:46 -0500314
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600315 /** @brief Sets the BMC inventory item path under
316 * /xyz/openbmc_project/inventory/system/chassis/. */
317 void setBMCInventoryPath();
Gunnar Millsb60add12017-08-24 16:41:42 -0500318
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600319 /** @brief The path to the BMC inventory item. */
320 std::string bmcInventoryPath;
Gunnar Millsb60add12017-08-24 16:41:42 -0500321
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600322 /** @brief Restores field mode status on reboot. */
323 void restoreFieldModeStatus();
Michael Tritz0129d922017-08-10 19:33:46 -0500324
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600325 /** @brief Creates a functional association to the
326 * "running" BMC software image
327 *
328 * @param[in] path - The path to create the association to.
329 */
330 void createFunctionalAssociation(const std::string& path);
Gunnar Mills88e8a322017-09-13 11:09:28 -0500331
Jagpal Singh Gill6d131aa2024-04-07 23:56:48 -0700332 /** @brief D-Bus context */
333 sdbusplus::async::context& ctx;
334
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600335 /** @brief Persistent sdbusplus D-Bus bus connection. */
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -0500336 sdbusplus::bus_t& bus;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500337
Lei YU56aaf452018-06-21 16:09:44 +0800338 /** @brief The helper of image updater. */
339 Helper helper;
340
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600341 /** @brief Persistent map of Activation D-Bus objects and their
342 * version id */
343 std::map<std::string, std::unique_ptr<Activation>> activations;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500344
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600345 /** @brief sdbusplus signal match for Software.Version */
Jagpal Singh Gillbb024eb2024-04-07 23:34:00 -0700346 std::unique_ptr<sdbusplus::bus::match_t> versionMatch;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500347
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600348 /** @brief This entry's associations */
Patrick Williamsfc33ba82024-08-16 15:19:54 -0400349 AssociationList assocs;
Gunnar Millsded875d2017-08-28 16:44:52 -0500350
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600351 /** @brief Clears read only partition for
352 * given Activation D-Bus object.
353 *
354 * @param[in] versionId - The version id.
355 */
Pavithra Barithaya6d178522024-06-24 04:17:29 -0500356 void removeReadOnlyPartition(const std::string& versionId);
Eddie Jameseaa1ee02018-03-01 10:09:10 -0600357
358 /** @brief Copies U-Boot from the currently booted BMC chip to the
359 * alternate chip.
360 */
361 void mirrorUbootToAlt();
Bright Cheng8e9ccfe2019-11-18 16:18:44 +0800362
363 /** @brief Check the required image files
364 *
365 * @param[in] filePath - BMC tarball file path
366 * @param[in] imageList - Image filenames included in the BMC tarball
367 * @param[out] result - Boolean
368 * true if all image files are found in BMC tarball
369 * false if one of image files is missing
370 */
Pavithra Barithayac5f6e7e2024-06-24 09:50:21 -0500371 static bool checkImage(const std::string& filePath,
372 const std::vector<std::string>& imageList);
Lei YU6e9fb1d2021-02-19 18:01:40 +0800373
Adriana Kobylak30352a62024-04-09 09:25:36 -0500374 /** @brief Persistent MinimumVersion D-Bus object */
375 std::unique_ptr<MinimumVersion> minimumVersionObject;
376
Jagpal Singh Gill6d131aa2024-04-07 23:56:48 -0700377 /** @brief Persistent map of Update D-Bus objects and their SwIds */
378 std::map<std::string, std::unique_ptr<UpdateManager>> updateManagers;
379
Lei YU6e9fb1d2021-02-19 18:01:40 +0800380#ifdef HOST_BIOS_UPGRADE
381 /** @brief Create the BIOS object without knowing the version.
382 *
383 * The object is created only to provide the DBus access so that an
384 * external service could set the correct BIOS version.
385 * On BIOS code update, the version is updated accordingly.
386 */
387 void createBIOSObject();
388
389 /** @brief Persistent Activation D-Bus object for BIOS */
390 std::unique_ptr<Activation> biosActivation;
391
Lei YU16aa28a2021-05-07 10:17:30 +0800392 public:
Lei YU6e9fb1d2021-02-19 18:01:40 +0800393 /** @brief Persistent Version D-Bus object for BIOS */
394 std::unique_ptr<VersionClass> biosVersion;
395#endif
Lei YU531fbc22021-12-10 20:03:18 +0800396
397 /** @brief Get the slot number of running image */
398 void getRunningSlot();
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500399};
400
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500401} // namespace updater
402} // namespace software
403} // namespace phosphor