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