xref: /openbmc/phosphor-bmc-code-mgmt/item_updater.hpp (revision bf2bb2b11c4d70811e8745c2f4c411896c744111)
1 #pragma once
2 
3 #include "activation.hpp"
4 #include "item_updater_helper.hpp"
5 #include "version.hpp"
6 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
7 
8 #include <sdbusplus/server.hpp>
9 #include <xyz/openbmc_project/Association/Definitions/server.hpp>
10 #include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
11 #include <xyz/openbmc_project/Control/FieldMode/server.hpp>
12 
13 #include <string>
14 #include <vector>
15 
16 namespace phosphor
17 {
18 namespace software
19 {
20 namespace updater
21 {
22 
23 using ItemUpdaterInherit = sdbusplus::server::object_t<
24     sdbusplus::xyz::openbmc_project::Common::server::FactoryReset,
25     sdbusplus::xyz::openbmc_project::Control::server::FieldMode,
26     sdbusplus::xyz::openbmc_project::Association::server::Definitions,
27     sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
28 
29 namespace MatchRules = sdbusplus::bus::match::rules;
30 using VersionClass = phosphor::software::manager::Version;
31 using AssociationList =
32     std::vector<std::tuple<std::string, std::string, std::string>>;
33 
34 /** @class ItemUpdater
35  *  @brief Manages the activation of the BMC version items.
36  */
37 class ItemUpdater : public ItemUpdaterInherit
38 {
39   public:
40     /*
41      * @brief Types of Activation status for image validation.
42      */
43     enum class ActivationStatus
44     {
45         ready,
46         invalid,
47         active
48     };
49 
50     /** @brief Constructs ItemUpdater
51      *
52      * @param[in] bus    - The D-Bus bus object
53      */
54     ItemUpdater(sdbusplus::bus_t& bus, const std::string& path) :
55         ItemUpdaterInherit(bus, path.c_str(),
56                            ItemUpdaterInherit::action::defer_emit),
57         bus(bus), helper(bus),
58         versionMatch(bus,
59                      MatchRules::interfacesAdded() +
60                          MatchRules::path("/xyz/openbmc_project/software"),
61                      std::bind(std::mem_fn(&ItemUpdater::createActivation),
62                                this, std::placeholders::_1))
63     {
64         getRunningSlot();
65         setBMCInventoryPath();
66         processBMCImage();
67         restoreFieldModeStatus();
68 #ifdef HOST_BIOS_UPGRADE
69         createBIOSObject();
70 #endif
71         emit_object_added();
72     };
73 
74     /** @brief Save priority value to persistent storage (flash and optionally
75      *  a U-Boot environment variable)
76      *
77      *  @param[in] versionId - The Id of the version
78      *  @param[in] value - The priority value
79      *  @return None
80      */
81     void savePriority(const std::string& versionId, uint8_t value);
82 
83     /** @brief Sets the given priority free by incrementing
84      *  any existing priority with the same value by 1
85      *
86      *  @param[in] value - The priority that needs to be set free.
87      *  @param[in] versionId - The Id of the version for which we
88      *                         are trying to free up the priority.
89      *  @return None
90      */
91     void freePriority(uint8_t value, const std::string& versionId);
92 
93     /**
94      * @brief Create and populate the active BMC Version.
95      */
96     void processBMCImage();
97 
98     /**
99      * @brief Erase specified entry D-Bus object
100      *        if Action property is not set to Active
101      *
102      * @param[in] entryId - unique identifier of the entry
103      */
104     void erase(std::string entryId);
105 
106     /**
107      * @brief Deletes all versions except for the current one
108      */
109     void deleteAll();
110 
111     /** @brief Creates an active association to the
112      *  newly active software image
113      *
114      * @param[in]  path - The path to create the association to.
115      */
116     void createActiveAssociation(const std::string& path);
117 
118     /** @brief Removes the associations from the provided software image path
119      *
120      * @param[in]  path - The path to remove the associations from.
121      */
122     void removeAssociations(const std::string& path);
123 
124     /** @brief Determine if the given priority is the lowest
125      *
126      *  @param[in] value - The priority that needs to be checked.
127      *
128      *  @return boolean corresponding to whether the given
129      *      priority is lowest.
130      */
131     bool isLowestPriority(uint8_t value);
132 
133     /**
134      * @brief Updates the U-Boot variables to point to the requested
135      *        versionId, so that the systems boots from this version on
136      *        the next reboot.
137      *
138      * @param[in] versionId - The version to point the system to boot from.
139      */
140     void updateUbootEnvVars(const std::string& versionId);
141 
142     /**
143      * @brief Updates the uboot variables to point to BMC version with lowest
144      *        priority, so that the system boots from this version on the
145      *        next boot.
146      */
147     void resetUbootEnvVars();
148 
149     /** @brief Brings the total number of active BMC versions to
150      *         ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be
151      *         run before activating a new BMC version. If this function
152      *         needs to delete any BMC version(s) it will delete the
153      *         version(s) with the highest priority, skipping the
154      *         functional BMC version.
155      *
156      * @param[in] caller - The Activation object that called this function.
157      */
158     void freeSpace(const Activation& caller);
159 
160     /** @brief Creates a updateable association to the
161      *  "running" BMC software image
162      *
163      * @param[in]  path - The path to create the association.
164      */
165     void createUpdateableAssociation(const std::string& path);
166 
167     /** @brief Persistent map of Version D-Bus objects and their
168      * version id */
169     std::map<std::string, std::unique_ptr<VersionClass>> versions;
170 
171     /** @brief Vector of needed BMC images in the tarball*/
172     std::vector<std::string> imageUpdateList;
173 
174     /** @breif The slot of running BMC image */
175     uint32_t runningImageSlot = 0;
176 
177   private:
178     /** @brief Callback function for Software.Version match.
179      *  @details Creates an Activation D-Bus object.
180      *
181      * @param[in]  msg       - Data associated with subscribed signal
182      */
183     void createActivation(sdbusplus::message_t& msg);
184 
185     /**
186      * @brief Validates the presence of SquashFS image in the image dir.
187      *
188      * @param[in]  filePath  - The path to the image dir.
189      * @param[out] result    - ActivationStatus Enum.
190      *                         ready if validation was successful.
191      *                         invalid if validation fail.
192      *                         active if image is the current version.
193      *
194      */
195     ActivationStatus validateSquashFSImage(const std::string& filePath);
196 
197     /** @brief BMC factory reset - marks the read-write partition for
198      * recreation upon reboot. */
199     void reset() override;
200 
201     /**
202      * @brief Enables field mode, if value=true.
203      *
204      * @param[in]  value  - If true, enables field mode.
205      * @param[out] result - Returns the current state of field mode.
206      *
207      */
208     bool fieldModeEnabled(bool value) override;
209 
210     /** @brief Sets the BMC inventory item path under
211      *  /xyz/openbmc_project/inventory/system/chassis/. */
212     void setBMCInventoryPath();
213 
214     /** @brief The path to the BMC inventory item. */
215     std::string bmcInventoryPath;
216 
217     /** @brief Restores field mode status on reboot. */
218     void restoreFieldModeStatus();
219 
220     /** @brief Creates a functional association to the
221      *  "running" BMC software image
222      *
223      * @param[in]  path - The path to create the association to.
224      */
225     void createFunctionalAssociation(const std::string& path);
226 
227     /** @brief Persistent sdbusplus D-Bus bus connection. */
228     sdbusplus::bus_t& bus;
229 
230     /** @brief The helper of image updater. */
231     Helper helper;
232 
233     /** @brief Persistent map of Activation D-Bus objects and their
234      * version id */
235     std::map<std::string, std::unique_ptr<Activation>> activations;
236 
237     /** @brief sdbusplus signal match for Software.Version */
238     sdbusplus::bus::match_t versionMatch;
239 
240     /** @brief This entry's associations */
241     AssociationList assocs = {};
242 
243     /** @brief Clears read only partition for
244      * given Activation D-Bus object.
245      *
246      * @param[in]  versionId - The version id.
247      */
248     void removeReadOnlyPartition(std::string versionId);
249 
250     /** @brief Copies U-Boot from the currently booted BMC chip to the
251      *  alternate chip.
252      */
253     void mirrorUbootToAlt();
254 
255     /** @brief Check the required image files
256      *
257      * @param[in] filePath - BMC tarball file path
258      * @param[in] imageList - Image filenames included in the BMC tarball
259      * @param[out] result - Boolean
260      *                      true if all image files are found in BMC tarball
261      *                      false if one of image files is missing
262      */
263     bool checkImage(const std::string& filePath,
264                     const std::vector<std::string>& imageList);
265 
266 #ifdef HOST_BIOS_UPGRADE
267     /** @brief Create the BIOS object without knowing the version.
268      *
269      *  The object is created only to provide the DBus access so that an
270      *  external service could set the correct BIOS version.
271      *  On BIOS code update, the version is updated accordingly.
272      */
273     void createBIOSObject();
274 
275     /** @brief Persistent Activation D-Bus object for BIOS */
276     std::unique_ptr<Activation> biosActivation;
277 
278   public:
279     /** @brief Persistent Version D-Bus object for BIOS */
280     std::unique_ptr<VersionClass> biosVersion;
281 #endif
282 
283     /** @brief Get the slot number of running image */
284     void getRunningSlot();
285 };
286 
287 } // namespace updater
288 } // namespace software
289 } // namespace phosphor
290