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