1 #pragma once 2 3 #include "activation.hpp" 4 #include "item_updater_helper.hpp" 5 #include "msl_verify.hpp" 6 #include "version.hpp" 7 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp" 8 9 #include <sdbusplus/server.hpp> 10 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 11 #include <xyz/openbmc_project/Common/FactoryReset/server.hpp> 12 #include <xyz/openbmc_project/Control/FieldMode/server.hpp> 13 #include <xyz/openbmc_project/Software/MinimumVersion/server.hpp> 14 15 #include <string> 16 #include <vector> 17 18 namespace phosphor 19 { 20 namespace software 21 { 22 namespace updater 23 { 24 25 using ItemUpdaterInherit = sdbusplus::server::object_t< 26 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>; 30 using MinimumVersionInherit = sdbusplus::server::object_t< 31 sdbusplus::server::xyz::openbmc_project::software::MinimumVersion>; 32 33 namespace MatchRules = sdbusplus::bus::match::rules; 34 using VersionClass = phosphor::software::manager::Version; 35 using AssociationList = 36 std::vector<std::tuple<std::string, std::string, std::string>>; 37 38 /** @class MinimumVersion 39 * @brief OpenBMC MinimumVersion implementation. 40 * @details A concrete implementation for 41 * xyz.openbmc_project.Software.MinimumVersion DBus API. 42 */ 43 class 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 56 /** @class ItemUpdater 57 * @brief Manages the activation of the BMC version items. 58 */ 59 class ItemUpdater : public ItemUpdaterInherit 60 { 61 public: 62 /* 63 * @brief Types of Activation status for image validation. 64 */ 65 enum class ActivationStatus 66 { 67 ready, 68 invalid, 69 active 70 }; 71 72 /** @brief Constructs ItemUpdater 73 * 74 * @param[in] bus - The D-Bus bus object 75 */ 76 ItemUpdater(sdbusplus::bus_t& bus, const std::string& path) : 77 ItemUpdaterInherit(bus, path.c_str(), 78 ItemUpdaterInherit::action::defer_emit), 79 bus(bus), helper(bus), 80 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 { 86 getRunningSlot(); 87 setBMCInventoryPath(); 88 processBMCImage(); 89 restoreFieldModeStatus(); 90 #ifdef HOST_BIOS_UPGRADE 91 createBIOSObject(); 92 #endif 93 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 101 emit_object_added(); 102 }; 103 104 /** @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 113 /** @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); 122 123 /** 124 * @brief Create and populate the active BMC Version. 125 */ 126 void processBMCImage(); 127 128 /** 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); 135 136 /** 137 * @brief Deletes all versions except for the current one 138 */ 139 void deleteAll(); 140 141 /** @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); 147 148 /** @brief Removes the associations from the provided software image path 149 * 150 * @param[in] path - The path to remove the associations from. 151 */ 152 void removeAssociations(const std::string& path); 153 154 /** @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); 162 163 /** 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); 171 172 /** 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(); 178 179 /** @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. 185 * 186 * @param[in] caller - The Activation object that called this function. 187 */ 188 void freeSpace(const Activation& caller); 189 190 /** @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 197 /** @brief Persistent map of Version D-Bus objects and their 198 * version id */ 199 std::map<std::string, std::unique_ptr<VersionClass>> versions; 200 201 /** @brief Vector of needed BMC images in the tarball*/ 202 std::vector<std::string> imageUpdateList; 203 204 /** @breif The slot of running BMC image */ 205 uint32_t runningImageSlot = 0; 206 207 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 */ 213 void createActivation(sdbusplus::message_t& msg); 214 215 /** 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); 226 227 /** @brief BMC factory reset - marks the read-write partition for 228 * recreation upon reboot. */ 229 void reset() override; 230 231 /** 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; 239 240 /** @brief Sets the BMC inventory item path under 241 * /xyz/openbmc_project/inventory/system/chassis/. */ 242 void setBMCInventoryPath(); 243 244 /** @brief The path to the BMC inventory item. */ 245 std::string bmcInventoryPath; 246 247 /** @brief Restores field mode status on reboot. */ 248 void restoreFieldModeStatus(); 249 250 /** @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); 256 257 /** @brief Persistent sdbusplus D-Bus bus connection. */ 258 sdbusplus::bus_t& bus; 259 260 /** @brief The helper of image updater. */ 261 Helper helper; 262 263 /** @brief Persistent map of Activation D-Bus objects and their 264 * version id */ 265 std::map<std::string, std::unique_ptr<Activation>> activations; 266 267 /** @brief sdbusplus signal match for Software.Version */ 268 sdbusplus::bus::match_t versionMatch; 269 270 /** @brief This entry's associations */ 271 AssociationList assocs = {}; 272 273 /** @brief Clears read only partition for 274 * given Activation D-Bus object. 275 * 276 * @param[in] versionId - The version id. 277 */ 278 void removeReadOnlyPartition(std::string versionId); 279 280 /** @brief Copies U-Boot from the currently booted BMC chip to the 281 * alternate chip. 282 */ 283 void mirrorUbootToAlt(); 284 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 */ 293 bool checkImage(const std::string& filePath, 294 const std::vector<std::string>& imageList); 295 296 /** @brief Persistent MinimumVersion D-Bus object */ 297 std::unique_ptr<MinimumVersion> minimumVersionObject; 298 299 #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 311 public: 312 /** @brief Persistent Version D-Bus object for BIOS */ 313 std::unique_ptr<VersionClass> biosVersion; 314 #endif 315 316 /** @brief Get the slot number of running image */ 317 void getRunningSlot(); 318 }; 319 320 } // namespace updater 321 } // namespace software 322 } // namespace phosphor 323