blob: ad538e9680ebf1a22aeb5d121249e1cbd383e8ee [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"
Saqib Khan705f1bf2017-06-09 23:58:38 -05006#include "version.hpp"
Gunnar Millsb0ce9962018-09-07 13:39:10 -05007#include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
8
9#include <sdbusplus/server.hpp>
John Wang85c356f2019-09-11 16:20:13 +080010#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Michael Tritz37a59042017-07-12 13:44:53 -050011#include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
Michael Tritz0129d922017-08-10 19:33:46 -050012#include <xyz/openbmc_project/Control/FieldMode/server.hpp>
Adriana Kobylak30352a62024-04-09 09:25:36 -050013#include <xyz/openbmc_project/Software/MinimumVersion/server.hpp>
Gunnar Millsec1b41c2017-05-02 12:20:36 -050014
Adriana Kobylak58aa7502020-06-08 11:12:11 -050015#include <string>
Bright Cheng8e9ccfe2019-11-18 16:18:44 +080016#include <vector>
Adriana Kobylak58aa7502020-06-08 11:12:11 -050017
Gunnar Millsec1b41c2017-05-02 12:20:36 -050018namespace phosphor
19{
20namespace software
21{
22namespace updater
23{
24
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -050025using ItemUpdaterInherit = sdbusplus::server::object_t<
Patrick Williams1e9a5f12023-08-23 16:53:06 -050026 sdbusplus::server::xyz::openbmc_project::common::FactoryReset,
27 sdbusplus::server::xyz::openbmc_project::control::FieldMode,
28 sdbusplus::server::xyz::openbmc_project::association::Definitions,
29 sdbusplus::server::xyz::openbmc_project::collection::DeleteAll>;
Adriana Kobylak30352a62024-04-09 09:25:36 -050030using MinimumVersionInherit = sdbusplus::server::object_t<
31 sdbusplus::server::xyz::openbmc_project::software::MinimumVersion>;
Michael Tritz37a59042017-07-12 13:44:53 -050032
Patrick Williamse75d10f2017-05-30 16:56:32 -050033namespace MatchRules = sdbusplus::bus::match::rules;
Gunnar Mills48442912017-10-06 13:34:07 -050034using VersionClass = phosphor::software::manager::Version;
Gunnar Millsded875d2017-08-28 16:44:52 -050035using AssociationList =
Adriana Kobylak2285fe02018-02-27 15:36:59 -060036 std::vector<std::tuple<std::string, std::string, std::string>>;
Gunnar Millsded875d2017-08-28 16:44:52 -050037
Adriana Kobylak30352a62024-04-09 09:25:36 -050038/** @class MinimumVersion
39 * @brief OpenBMC MinimumVersion implementation.
40 * @details A concrete implementation for
41 * xyz.openbmc_project.Software.MinimumVersion DBus API.
42 */
43class MinimumVersion : public MinimumVersionInherit
44{
45 public:
46 /** @brief Constructs MinimumVersion
47 *
48 * @param[in] bus - The D-Bus bus object
49 * @param[in] path - The D-bus object path
50 */
51 MinimumVersion(sdbusplus::bus_t& bus, const std::string& path) :
52 MinimumVersionInherit(bus, path.c_str(), action::emit_interface_added)
53 {}
54};
55
Gunnar Millsec1b41c2017-05-02 12:20:36 -050056/** @class ItemUpdater
57 * @brief Manages the activation of the BMC version items.
58 */
Michael Tritz37a59042017-07-12 13:44:53 -050059class ItemUpdater : public ItemUpdaterInherit
Gunnar Millsec1b41c2017-05-02 12:20:36 -050060{
Adriana Kobylak2285fe02018-02-27 15:36:59 -060061 public:
62 /*
63 * @brief Types of Activation status for image validation.
64 */
65 enum class ActivationStatus
66 {
67 ready,
68 invalid,
69 active
70 };
Saqib Khan35e83f32017-05-22 11:37:32 -050071
Adriana Kobylak2285fe02018-02-27 15:36:59 -060072 /** @brief Constructs ItemUpdater
73 *
74 * @param[in] bus - The D-Bus bus object
75 */
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -050076 ItemUpdater(sdbusplus::bus_t& bus, const std::string& path) :
Patrick Williams35aa9a82022-04-05 15:55:30 -050077 ItemUpdaterInherit(bus, path.c_str(),
78 ItemUpdaterInherit::action::defer_emit),
79 bus(bus), helper(bus),
Adriana Kobylak2285fe02018-02-27 15:36:59 -060080 versionMatch(bus,
81 MatchRules::interfacesAdded() +
82 MatchRules::path("/xyz/openbmc_project/software"),
83 std::bind(std::mem_fn(&ItemUpdater::createActivation),
84 this, std::placeholders::_1))
85 {
Lei YU531fbc22021-12-10 20:03:18 +080086 getRunningSlot();
Adriana Kobylak2285fe02018-02-27 15:36:59 -060087 setBMCInventoryPath();
88 processBMCImage();
89 restoreFieldModeStatus();
Lei YU6e9fb1d2021-02-19 18:01:40 +080090#ifdef HOST_BIOS_UPGRADE
91 createBIOSObject();
92#endif
Adriana Kobylak30352a62024-04-09 09:25:36 -050093
94 if (minimum_ship_level::enabled())
95 {
96 minimumVersionObject = std::make_unique<MinimumVersion>(bus, path);
97 minimumVersionObject->minimumVersion(
98 minimum_ship_level::getMinimumVersion());
99 }
100
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600101 emit_object_added();
102 };
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500103
Adriana Kobylakbbcb7be2018-07-17 15:47:34 -0500104 /** @brief Save priority value to persistent storage (flash and optionally
105 * a U-Boot environment variable)
106 *
107 * @param[in] versionId - The Id of the version
108 * @param[in] value - The priority value
109 * @return None
110 */
111 void savePriority(const std::string& versionId, uint8_t value);
112
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600113 /** @brief Sets the given priority free by incrementing
114 * any existing priority with the same value by 1
115 *
116 * @param[in] value - The priority that needs to be set free.
117 * @param[in] versionId - The Id of the version for which we
118 * are trying to free up the priority.
119 * @return None
120 */
121 void freePriority(uint8_t value, const std::string& versionId);
Saqib Khan4c1aec02017-07-06 11:46:13 -0500122
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600123 /**
124 * @brief Create and populate the active BMC Version.
125 */
126 void processBMCImage();
Saqib Khanba239882017-05-26 08:41:54 -0500127
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600128 /**
129 * @brief Erase specified entry D-Bus object
130 * if Action property is not set to Active
131 *
132 * @param[in] entryId - unique identifier of the entry
133 */
134 void erase(std::string entryId);
Leonel Gonzalez3526ef72017-07-07 14:38:25 -0500135
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600136 /**
137 * @brief Deletes all versions except for the current one
138 */
Pavithra Barithaya36cc1c82024-06-22 00:41:28 -0500139 void deleteAll() override;
Gunnar Millsded875d2017-08-28 16:44:52 -0500140
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600141 /** @brief Creates an active association to the
142 * newly active software image
143 *
144 * @param[in] path - The path to create the association to.
145 */
146 void createActiveAssociation(const std::string& path);
Gunnar Millsded875d2017-08-28 16:44:52 -0500147
Adriana Kobylak991af7e2018-12-10 13:08:38 -0600148 /** @brief Removes the associations from the provided software image path
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600149 *
Adriana Kobylak991af7e2018-12-10 13:08:38 -0600150 * @param[in] path - The path to remove the associations from.
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600151 */
Adriana Kobylak991af7e2018-12-10 13:08:38 -0600152 void removeAssociations(const std::string& path);
Gunnar Millsded875d2017-08-28 16:44:52 -0500153
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600154 /** @brief Determine if the given priority is the lowest
155 *
156 * @param[in] value - The priority that needs to be checked.
157 *
158 * @return boolean corresponding to whether the given
159 * priority is lowest.
160 */
161 bool isLowestPriority(uint8_t value);
Saqib Khanb9da6632017-09-13 09:48:37 -0500162
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600163 /**
164 * @brief Updates the U-Boot variables to point to the requested
165 * versionId, so that the systems boots from this version on
166 * the next reboot.
167 *
168 * @param[in] versionId - The version to point the system to boot from.
169 */
170 void updateUbootEnvVars(const std::string& versionId);
Adriana Kobylakb77551c2017-10-27 12:46:23 -0500171
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600172 /**
173 * @brief Updates the uboot variables to point to BMC version with lowest
174 * priority, so that the system boots from this version on the
175 * next boot.
176 */
177 void resetUbootEnvVars();
Saqib Khan49446ae2017-10-02 10:54:20 -0500178
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600179 /** @brief Brings the total number of active BMC versions to
180 * ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be
181 * run before activating a new BMC version. If this function
182 * needs to delete any BMC version(s) it will delete the
183 * version(s) with the highest priority, skipping the
184 * functional BMC version.
Adriana Kobylaka6963592018-09-07 14:13:29 -0500185 *
186 * @param[in] caller - The Activation object that called this function.
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600187 */
Lei YU0cd6d842021-12-27 11:56:02 +0800188 void freeSpace(const Activation& caller);
Adriana Kobylak204e1e72018-01-24 16:00:05 -0600189
AppaRao Puli1bb6dcb2020-03-27 20:51:57 +0530190 /** @brief Creates a updateable association to the
191 * "running" BMC software image
192 *
193 * @param[in] path - The path to create the association.
194 */
195 void createUpdateableAssociation(const std::string& path);
196
Adriana Kobylakec4eec32019-11-13 14:28:35 -0600197 /** @brief Persistent map of Version D-Bus objects and their
198 * version id */
199 std::map<std::string, std::unique_ptr<VersionClass>> versions;
200
Bright Cheng8e9ccfe2019-11-18 16:18:44 +0800201 /** @brief Vector of needed BMC images in the tarball*/
202 std::vector<std::string> imageUpdateList;
203
Manojkiran Eda19dd56b2024-06-17 14:29:52 +0530204 /** @brief The slot of running BMC image */
Lei YU531fbc22021-12-10 20:03:18 +0800205 uint32_t runningImageSlot = 0;
206
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600207 private:
208 /** @brief Callback function for Software.Version match.
209 * @details Creates an Activation D-Bus object.
210 *
211 * @param[in] msg - Data associated with subscribed signal
212 */
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -0500213 void createActivation(sdbusplus::message_t& msg);
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500214
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600215 /**
216 * @brief Validates the presence of SquashFS image in the image dir.
217 *
218 * @param[in] filePath - The path to the image dir.
219 * @param[out] result - ActivationStatus Enum.
220 * ready if validation was successful.
221 * invalid if validation fail.
222 * active if image is the current version.
223 *
224 */
225 ActivationStatus validateSquashFSImage(const std::string& filePath);
Saqib Khan35e83f32017-05-22 11:37:32 -0500226
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600227 /** @brief BMC factory reset - marks the read-write partition for
228 * recreation upon reboot. */
229 void reset() override;
Michael Tritz37a59042017-07-12 13:44:53 -0500230
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600231 /**
232 * @brief Enables field mode, if value=true.
233 *
234 * @param[in] value - If true, enables field mode.
235 * @param[out] result - Returns the current state of field mode.
236 *
237 */
238 bool fieldModeEnabled(bool value) override;
Michael Tritz0129d922017-08-10 19:33:46 -0500239
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600240 /** @brief Sets the BMC inventory item path under
241 * /xyz/openbmc_project/inventory/system/chassis/. */
242 void setBMCInventoryPath();
Gunnar Millsb60add12017-08-24 16:41:42 -0500243
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600244 /** @brief The path to the BMC inventory item. */
245 std::string bmcInventoryPath;
Gunnar Millsb60add12017-08-24 16:41:42 -0500246
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600247 /** @brief Restores field mode status on reboot. */
248 void restoreFieldModeStatus();
Michael Tritz0129d922017-08-10 19:33:46 -0500249
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600250 /** @brief Creates a functional association to the
251 * "running" BMC software image
252 *
253 * @param[in] path - The path to create the association to.
254 */
255 void createFunctionalAssociation(const std::string& path);
Gunnar Mills88e8a322017-09-13 11:09:28 -0500256
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600257 /** @brief Persistent sdbusplus D-Bus bus connection. */
Patrick Williamsbf2bb2b2022-07-22 19:26:52 -0500258 sdbusplus::bus_t& bus;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500259
Lei YU56aaf452018-06-21 16:09:44 +0800260 /** @brief The helper of image updater. */
261 Helper helper;
262
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600263 /** @brief Persistent map of Activation D-Bus objects and their
264 * version id */
265 std::map<std::string, std::unique_ptr<Activation>> activations;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500266
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600267 /** @brief sdbusplus signal match for Software.Version */
268 sdbusplus::bus::match_t versionMatch;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500269
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600270 /** @brief This entry's associations */
271 AssociationList assocs = {};
Gunnar Millsded875d2017-08-28 16:44:52 -0500272
Adriana Kobylak2285fe02018-02-27 15:36:59 -0600273 /** @brief Clears read only partition for
274 * given Activation D-Bus object.
275 *
276 * @param[in] versionId - The version id.
277 */
Pavithra Barithaya6d178522024-06-24 04:17:29 -0500278 void removeReadOnlyPartition(const std::string& versionId);
Eddie Jameseaa1ee02018-03-01 10:09:10 -0600279
280 /** @brief Copies U-Boot from the currently booted BMC chip to the
281 * alternate chip.
282 */
283 void mirrorUbootToAlt();
Bright Cheng8e9ccfe2019-11-18 16:18:44 +0800284
285 /** @brief Check the required image files
286 *
287 * @param[in] filePath - BMC tarball file path
288 * @param[in] imageList - Image filenames included in the BMC tarball
289 * @param[out] result - Boolean
290 * true if all image files are found in BMC tarball
291 * false if one of image files is missing
292 */
Pavithra Barithayac5f6e7e2024-06-24 09:50:21 -0500293 static bool checkImage(const std::string& filePath,
294 const std::vector<std::string>& imageList);
Lei YU6e9fb1d2021-02-19 18:01:40 +0800295
Adriana Kobylak30352a62024-04-09 09:25:36 -0500296 /** @brief Persistent MinimumVersion D-Bus object */
297 std::unique_ptr<MinimumVersion> minimumVersionObject;
298
Lei YU6e9fb1d2021-02-19 18:01:40 +0800299#ifdef HOST_BIOS_UPGRADE
300 /** @brief Create the BIOS object without knowing the version.
301 *
302 * The object is created only to provide the DBus access so that an
303 * external service could set the correct BIOS version.
304 * On BIOS code update, the version is updated accordingly.
305 */
306 void createBIOSObject();
307
308 /** @brief Persistent Activation D-Bus object for BIOS */
309 std::unique_ptr<Activation> biosActivation;
310
Lei YU16aa28a2021-05-07 10:17:30 +0800311 public:
Lei YU6e9fb1d2021-02-19 18:01:40 +0800312 /** @brief Persistent Version D-Bus object for BIOS */
313 std::unique_ptr<VersionClass> biosVersion;
314#endif
Lei YU531fbc22021-12-10 20:03:18 +0800315
316 /** @brief Get the slot number of running image */
317 void getRunningSlot();
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500318};
319
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500320} // namespace updater
321} // namespace software
322} // namespace phosphor