1 #pragma once
2 
3 #include <sdbusplus/server.hpp>
4 #include "activation.hpp"
5 #include "version.hpp"
6 #include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
7 #include <xyz/openbmc_project/Control/FieldMode/server.hpp>
8 #include "org/openbmc/Associations/server.hpp"
9 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
10 
11 namespace phosphor
12 {
13 namespace software
14 {
15 namespace updater
16 {
17 
18 using ItemUpdaterInherit = sdbusplus::server::object::object<
19         sdbusplus::xyz::openbmc_project::Common::server::FactoryReset,
20         sdbusplus::xyz::openbmc_project::Control::server::FieldMode,
21         sdbusplus::org::openbmc::server::Associations,
22         sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
23 
24 namespace MatchRules = sdbusplus::bus::match::rules;
25 using VersionClass = phosphor::software::manager::Version;
26 using AssociationList =
27         std::vector<std::tuple<std::string, std::string, std::string>>;
28 
29 /** @class ItemUpdater
30  *  @brief Manages the activation of the BMC version items.
31  */
32 class ItemUpdater : public ItemUpdaterInherit
33 {
34     public:
35         /*
36          * @brief Types of Activation status for image validation.
37          */
38         enum class ActivationStatus
39         {
40             ready,
41             invalid,
42             active
43         };
44 
45         /** @brief Constructs ItemUpdater
46          *
47          * @param[in] bus    - The D-Bus bus object
48          */
49         ItemUpdater(sdbusplus::bus::bus& bus, const std::string& path) :
50                     ItemUpdaterInherit(bus, path.c_str(), false),
51                     bus(bus),
52                     versionMatch(
53                             bus,
54                             MatchRules::interfacesAdded() +
55                             MatchRules::path("/xyz/openbmc_project/software"),
56                             std::bind(
57                                     std::mem_fn(&ItemUpdater::createActivation),
58                                     this,
59                                     std::placeholders::_1))
60         {
61             setBMCInventoryPath();
62             processBMCImage();
63             restoreFieldModeStatus();
64             emit_object_added();
65         };
66 
67         /** @brief Sets the given priority free by incrementing
68          *  any existing priority with the same value by 1
69          *
70          *  @param[in] value - The priority that needs to be set free.
71          *  @param[in] versionId - The Id of the version for which we
72          *                         are trying to free up the priority.
73          *  @return None
74          */
75         void freePriority(uint8_t value, const std::string& versionId);
76 
77         /**
78          * @brief Create and populate the active BMC Version.
79          */
80         void processBMCImage();
81 
82         /**
83          * @brief Erase specified entry D-Bus object
84          *        if Action property is not set to Active
85          *
86          * @param[in] entryId - unique identifier of the entry
87          */
88         void erase(std::string entryId);
89 
90         /**
91          * @brief Deletes all versions except for the current one
92          */
93         void deleteAll();
94 
95         /** @brief Creates an active association to the
96          *  newly active software image
97          *
98          * @param[in]  path - The path to create the association to.
99          */
100         void createActiveAssociation(const std::string& path);
101 
102         /** @brief Removes an active association to the software image
103          *
104          * @param[in]  path - The path to remove the association from.
105          */
106         void removeActiveAssociation(const std::string& path);
107 
108         /** @brief Determine if the given priority is the lowest
109          *
110          *  @param[in] value - The priority that needs to be checked.
111          *
112          *  @return boolean corresponding to whether the given
113          *      priority is lowest.
114          */
115         bool isLowestPriority(uint8_t value);
116 
117         /**
118          * @brief Updates the U-Boot variables to point to the requested
119          *        versionId, so that the systems boots from this version on
120          *        the next reboot.
121          *
122          * @param[in] versionId - The version to point the system to boot from.
123          */
124         void updateUbootEnvVars(const std::string& versionId);
125 
126         /**
127          * @brief Updates the uboot variables to point to BMC version with lowest
128          *        priority, so that the system boots from this version on the
129          *        next boot.
130          */
131         void resetUbootEnvVars();
132 
133         /** @brief Brings the total number of active BMC versions to
134          *         ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be
135          *         run before activating a new BMC version. If this function
136          *         needs to delete any BMC version(s) it will delete the
137          *         version(s) with the highest priority, skipping the
138          *         functional BMC version.
139          */
140         void freeSpace();
141 
142     private:
143         /** @brief Callback function for Software.Version match.
144          *  @details Creates an Activation D-Bus object.
145          *
146          * @param[in]  msg       - Data associated with subscribed signal
147          */
148         void createActivation(sdbusplus::message::message& msg);
149 
150         /**
151          * @brief Validates the presence of SquashFS image in the image dir.
152          *
153          * @param[in]  filePath  - The path to the image dir.
154          * @param[out] result    - ActivationStatus Enum.
155          *                         ready if validation was successful.
156          *                         invalid if validation fail.
157          *                         active if image is the current version.
158          *
159          */
160         ActivationStatus validateSquashFSImage(const std::string& filePath);
161 
162         /** @brief BMC factory reset - marks the read-write partition for
163           * recreation upon reboot. */
164         void reset() override;
165 
166         /**
167          * @brief Enables field mode, if value=true.
168          *
169          * @param[in]  value  - If true, enables field mode.
170          * @param[out] result - Returns the current state of field mode.
171          *
172          */
173         bool fieldModeEnabled(bool value) override;
174 
175         /** @brief Sets the BMC inventory item path under
176          *  /xyz/openbmc_project/inventory/system/chassis/. */
177         void setBMCInventoryPath();
178 
179         /** @brief The path to the BMC inventory item. */
180         std::string bmcInventoryPath;
181 
182         /** @brief Restores field mode status on reboot. */
183         void restoreFieldModeStatus();
184 
185         /** @brief Creates a functional association to the
186          *  "running" BMC software image
187          *
188          * @param[in]  path - The path to create the association to.
189          */
190         void createFunctionalAssociation(const std::string& path);
191 
192         /** @brief Persistent sdbusplus D-Bus bus connection. */
193         sdbusplus::bus::bus& bus;
194 
195         /** @brief Persistent map of Activation D-Bus objects and their
196           * version id */
197         std::map<std::string, std::unique_ptr<Activation>> activations;
198 
199         /** @brief Persistent map of Version D-Bus objects and their
200           * version id */
201         std::map<std::string, std::unique_ptr<VersionClass>> versions;
202 
203         /** @brief sdbusplus signal match for Software.Version */
204         sdbusplus::bus::match_t versionMatch;
205 
206         /** @brief This entry's associations */
207         AssociationList assocs = {};
208 
209         /** @brief Clears read only partition for
210          * given Activation D-Bus object.
211          *
212          * @param[in]  versionId - The version id.
213          */
214         void removeReadOnlyPartition(std::string versionId);
215 };
216 
217 } // namespace updater
218 } // namespace software
219 } // namespace phosphor
220