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 emit_object_added(); 94 }; 95 96 /** @brief Save priority value to persistent storage (flash and optionally 97 * a U-Boot environment variable) 98 * 99 * @param[in] versionId - The Id of the version 100 * @param[in] value - The priority value 101 * @return None 102 */ 103 void savePriority(const std::string& versionId, uint8_t value); 104 105 /** @brief Sets the given priority free by incrementing 106 * any existing priority with the same value by 1 107 * 108 * @param[in] value - The priority that needs to be set free. 109 * @param[in] versionId - The Id of the version for which we 110 * are trying to free up the priority. 111 * @return None 112 */ 113 void freePriority(uint8_t value, const std::string& versionId); 114 115 /** 116 * @brief Create and populate the active BMC Version. 117 */ 118 void processBMCImage(); 119 120 /** 121 * @brief Erase specified entry D-Bus object 122 * if Action property is not set to Active 123 * 124 * @param[in] entryId - unique identifier of the entry 125 */ 126 void erase(std::string entryId); 127 128 /** 129 * @brief Deletes all versions except for the current one 130 */ 131 void deleteAll() override; 132 133 /** @brief Creates an active association to the 134 * newly active software image 135 * 136 * @param[in] path - The path to create the association to. 137 */ 138 void createActiveAssociation(const std::string& path); 139 140 /** @brief Removes the associations from the provided software image path 141 * 142 * @param[in] path - The path to remove the associations from. 143 */ 144 void removeAssociations(const std::string& path); 145 146 /** @brief Determine if the given priority is the lowest 147 * 148 * @param[in] value - The priority that needs to be checked. 149 * 150 * @return boolean corresponding to whether the given 151 * priority is lowest. 152 */ 153 bool isLowestPriority(uint8_t value); 154 155 /** 156 * @brief Updates the U-Boot variables to point to the requested 157 * versionId, so that the systems boots from this version on 158 * the next reboot. 159 * 160 * @param[in] versionId - The version to point the system to boot from. 161 */ 162 void updateUbootEnvVars(const std::string& versionId); 163 164 /** 165 * @brief Updates the uboot variables to point to BMC version with lowest 166 * priority, so that the system boots from this version on the 167 * next boot. 168 */ 169 void resetUbootEnvVars(); 170 171 /** @brief Brings the total number of active BMC versions to 172 * ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be 173 * run before activating a new BMC version. If this function 174 * needs to delete any BMC version(s) it will delete the 175 * version(s) with the highest priority, skipping the 176 * functional BMC version. 177 * 178 * @param[in] caller - The Activation object that called this function. 179 */ 180 void freeSpace(const Activation& caller); 181 182 /** @brief Creates a updateable association to the 183 * "running" BMC software image 184 * 185 * @param[in] path - The path to create the association. 186 */ 187 void createUpdateableAssociation(const std::string& path); 188 189 /** @brief Persistent map of Version D-Bus objects and their 190 * version id */ 191 std::map<std::string, std::unique_ptr<VersionClass>> versions; 192 193 /** @brief Vector of needed BMC images in the tarball*/ 194 std::vector<std::string> imageUpdateList; 195 196 /** @brief The slot of running BMC image */ 197 uint32_t runningImageSlot = 0; 198 199 private: 200 /** @brief Callback function for Software.Version match. 201 * @details Creates an Activation D-Bus object. 202 * 203 * @param[in] msg - Data associated with subscribed signal 204 */ 205 void createActivation(sdbusplus::message_t& msg); 206 207 /** 208 * @brief Validates the presence of SquashFS image in the image dir. 209 * 210 * @param[in] filePath - The path to the image dir. 211 * @param[out] result - ActivationStatus Enum. 212 * ready if validation was successful. 213 * invalid if validation fail. 214 * active if image is the current version. 215 * 216 */ 217 ActivationStatus validateSquashFSImage(const std::string& filePath); 218 219 /** @brief BMC factory reset - marks the read-write partition for 220 * recreation upon reboot. */ 221 void reset() override; 222 223 /** 224 * @brief Enables field mode, if value=true. 225 * 226 * @param[in] value - If true, enables field mode. 227 * @param[out] result - Returns the current state of field mode. 228 * 229 */ 230 bool fieldModeEnabled(bool value) override; 231 232 /** @brief Sets the BMC inventory item path under 233 * /xyz/openbmc_project/inventory/system/chassis/. */ 234 void setBMCInventoryPath(); 235 236 /** @brief The path to the BMC inventory item. */ 237 std::string bmcInventoryPath; 238 239 /** @brief Restores field mode status on reboot. */ 240 void restoreFieldModeStatus(); 241 242 /** @brief Creates a functional association to the 243 * "running" BMC software image 244 * 245 * @param[in] path - The path to create the association to. 246 */ 247 void createFunctionalAssociation(const std::string& path); 248 249 /** @brief Persistent sdbusplus D-Bus bus connection. */ 250 sdbusplus::bus_t& bus; 251 252 /** @brief The helper of image updater. */ 253 Helper helper; 254 255 /** @brief Persistent map of Activation D-Bus objects and their 256 * version id */ 257 std::map<std::string, std::unique_ptr<Activation>> activations; 258 259 /** @brief sdbusplus signal match for Software.Version */ 260 sdbusplus::bus::match_t versionMatch; 261 262 /** @brief This entry's associations */ 263 AssociationList assocs; 264 265 /** @brief Clears read only partition for 266 * given Activation D-Bus object. 267 * 268 * @param[in] versionId - The version id. 269 */ 270 void removeReadOnlyPartition(const std::string& versionId); 271 272 /** @brief Copies U-Boot from the currently booted BMC chip to the 273 * alternate chip. 274 */ 275 void mirrorUbootToAlt(); 276 277 /** @brief Check the required image files 278 * 279 * @param[in] filePath - BMC tarball file path 280 * @param[in] imageList - Image filenames included in the BMC tarball 281 * @param[out] result - Boolean 282 * true if all image files are found in BMC tarball 283 * false if one of image files is missing 284 */ 285 static bool checkImage(const std::string& filePath, 286 const std::vector<std::string>& imageList); 287 288 /** @brief Persistent MinimumVersion D-Bus object */ 289 std::unique_ptr<MinimumVersion> minimumVersionObject; 290 291 #ifdef HOST_BIOS_UPGRADE 292 /** @brief Create the BIOS object without knowing the version. 293 * 294 * The object is created only to provide the DBus access so that an 295 * external service could set the correct BIOS version. 296 * On BIOS code update, the version is updated accordingly. 297 */ 298 void createBIOSObject(); 299 300 /** @brief Persistent Activation D-Bus object for BIOS */ 301 std::unique_ptr<Activation> biosActivation; 302 303 public: 304 /** @brief Persistent Version D-Bus object for BIOS */ 305 std::unique_ptr<VersionClass> biosVersion; 306 #endif 307 308 /** @brief Get the slot number of running image */ 309 void getRunningSlot(); 310 }; 311 312 } // namespace updater 313 } // namespace software 314 } // namespace phosphor 315