1 #pragma once 2 3 #include "activation.hpp" 4 #include "item_updater_helper.hpp" 5 #include "msl_verify.hpp" 6 #include "update_manager.hpp" 7 #include "version.hpp" 8 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp" 9 10 #include <sdbusplus/async.hpp> 11 #include <sdbusplus/server.hpp> 12 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 13 #include <xyz/openbmc_project/Common/FactoryReset/server.hpp> 14 #include <xyz/openbmc_project/Control/FieldMode/server.hpp> 15 #include <xyz/openbmc_project/Software/MinimumVersion/server.hpp> 16 17 #include <string> 18 #include <vector> 19 20 namespace phosphor 21 { 22 namespace software 23 { 24 namespace updater 25 { 26 27 using ActivationIntf = 28 sdbusplus::xyz::openbmc_project::Software::server::Activation; 29 using ItemUpdaterInherit = sdbusplus::server::object_t< 30 sdbusplus::server::xyz::openbmc_project::common::FactoryReset, 31 sdbusplus::server::xyz::openbmc_project::control::FieldMode, 32 sdbusplus::server::xyz::openbmc_project::association::Definitions, 33 sdbusplus::server::xyz::openbmc_project::collection::DeleteAll>; 34 using MinimumVersionInherit = sdbusplus::server::object_t< 35 sdbusplus::server::xyz::openbmc_project::software::MinimumVersion>; 36 37 namespace MatchRules = sdbusplus::bus::match::rules; 38 using VersionClass = phosphor::software::manager::Version; 39 using AssociationList = 40 std::vector<std::tuple<std::string, std::string, std::string>>; 41 using UpdateManager = phosphor::software::update::Manager; 42 43 /** @class MinimumVersion 44 * @brief OpenBMC MinimumVersion implementation. 45 * @details A concrete implementation for 46 * xyz.openbmc_project.Software.MinimumVersion DBus API. 47 */ 48 class MinimumVersion : public MinimumVersionInherit 49 { 50 public: 51 /** @brief Constructs MinimumVersion 52 * 53 * @param[in] bus - The D-Bus bus object 54 * @param[in] path - The D-bus object path 55 */ MinimumVersion(sdbusplus::bus_t & bus,const std::string & path)56 MinimumVersion(sdbusplus::bus_t& bus, const std::string& path) : 57 MinimumVersionInherit(bus, path.c_str(), action::emit_interface_added) 58 {} 59 }; 60 61 /** @class ItemUpdater 62 * @brief Manages the activation of the BMC version items. 63 */ 64 class ItemUpdater : public ItemUpdaterInherit 65 { 66 public: 67 /* 68 * @brief Types of Activation status for image validation. 69 */ 70 enum class ActivationStatus 71 { 72 ready, 73 invalid, 74 active 75 }; 76 77 /** @brief Constructs ItemUpdater 78 * 79 * @param[in] bus - The D-Bus bus object 80 */ ItemUpdater(sdbusplus::async::context & ctx,const std::string & path,bool useUpdateDBusInterface=true)81 ItemUpdater(sdbusplus::async::context& ctx, const std::string& path, 82 bool useUpdateDBusInterface = true) : 83 ItemUpdaterInherit(ctx.get_bus(), path.c_str(), 84 ItemUpdaterInherit::action::defer_emit), 85 useUpdateDBusInterface(useUpdateDBusInterface), ctx(ctx), 86 bus(ctx.get_bus()), helper(bus) 87 { 88 if (!useUpdateDBusInterface) 89 { 90 versionMatch = std::make_unique<sdbusplus::bus::match_t>( 91 bus, 92 MatchRules::interfacesAdded() + 93 MatchRules::path("/xyz/openbmc_project/software"), 94 std::bind(std::mem_fn(&ItemUpdater::createActivation), this, 95 std::placeholders::_1)); 96 } 97 getRunningSlot(); 98 setBMCInventoryPath(); 99 processBMCImage(); 100 restoreFieldModeStatus(); 101 #ifdef HOST_BIOS_UPGRADE 102 createBIOSObject(); 103 #endif 104 emit_object_added(); 105 }; 106 107 /** @brief Save priority value to persistent storage (flash and optionally 108 * a U-Boot environment variable) 109 * 110 * @param[in] versionId - The Id of the version 111 * @param[in] value - The priority value 112 * @return None 113 */ 114 void savePriority(const std::string& versionId, uint8_t value); 115 116 /** @brief Sets the given priority free by incrementing 117 * any existing priority with the same value by 1 118 * 119 * @param[in] value - The priority that needs to be set free. 120 * @param[in] versionId - The Id of the version for which we 121 * are trying to free up the priority. 122 * @return None 123 */ 124 void freePriority(uint8_t value, const std::string& versionId); 125 126 /** 127 * @brief Create and populate the active BMC Version. 128 */ 129 void processBMCImage(); 130 131 /** 132 * @brief Verifies the image at filepath and creates the version and 133 * activation object. In case activation object already exists for the 134 * specified id, update the activation status based on image verification. 135 * @param[in] id - The unique identifier for the update. 136 * @param[in] path - The object path for the relevant objects. 137 * @param[in] version - The version of the image. 138 * @param[in] purpose - The purpose of the image. 139 * @param[in] extendedVersion The extended version of the image. 140 * @param[in] filePath - The file path where the image is located. 141 * @param[in] compatibleNames - The compatible name for the image. 142 * @param[out] Activations - Whether the image is ready to activate or not. 143 */ 144 ActivationIntf::Activations verifyAndCreateObjects( 145 std::string& id, std::string& path, std::string& version, 146 VersionClass::VersionPurpose purpose, std::string& extendedVersion, 147 std ::string& filePath, std::vector<std::string>& compatibleNames); 148 149 /** 150 * @brief Creates the activation object 151 * @param[in] id - The unique identifier for the update. 152 * @param[in] path - The object path for the activation object. 153 * @param[in] applyTime - The apply time for the image 154 */ 155 void createActivationWithApplyTime( 156 std::string& id, std::string& path, 157 ApplyTimeIntf::RequestedApplyTimes applyTime); 158 159 /** 160 * @brief Request the activation for the specified update. 161 * @param[in] id - The unique identifier for the update. 162 * @param[out] bool - status for the action. 163 */ 164 bool requestActivation(std::string& id); 165 166 /** 167 * @brief Change the activation status for the specified update. 168 * @param[in] id - The unique identifier for the update. 169 * @param[in] status - The activation status to set. 170 * @param[out] bool - status for the action. 171 */ 172 bool updateActivationStatus(std::string& id, 173 ActivationIntf::Activations status); 174 175 /** 176 * @brief Create the Update object 177 * @param[in] id - The unique identifier for the update. 178 * @param[in] path - The object path for the update object. 179 */ 180 void createUpdateObject(const std::string& id, const std::string& path); 181 182 /** 183 * @brief Erase specified entry D-Bus object 184 * if Action property is not set to Active 185 * 186 * @param[in] entryId - unique identifier of the entry 187 */ 188 void erase(std::string entryId); 189 190 /** 191 * @brief Deletes all versions except for the current one 192 */ 193 void deleteAll() override; 194 195 /** @brief Creates an active association to the 196 * newly active software image 197 * 198 * @param[in] path - The path to create the association to. 199 */ 200 void createActiveAssociation(const std::string& path); 201 202 /** @brief Removes the associations from the provided software image path 203 * 204 * @param[in] path - The path to remove the associations from. 205 */ 206 void removeAssociations(const std::string& path); 207 208 /** @brief Determine if the given priority is the lowest 209 * 210 * @param[in] value - The priority that needs to be checked. 211 * 212 * @return boolean corresponding to whether the given 213 * priority is lowest. 214 */ 215 bool isLowestPriority(uint8_t value); 216 217 /** 218 * @brief Updates the U-Boot variables to point to the requested 219 * versionId, so that the systems boots from this version on 220 * the next reboot. 221 * 222 * @param[in] versionId - The version to point the system to boot from. 223 */ 224 void updateUbootEnvVars(const std::string& versionId); 225 226 /** 227 * @brief Updates the uboot variables to point to BMC version with lowest 228 * priority, so that the system boots from this version on the 229 * next boot. 230 */ 231 void resetUbootEnvVars(); 232 233 /** @brief Brings the total number of active BMC versions to 234 * ACTIVE_BMC_MAX_ALLOWED -1. This function is intended to be 235 * run before activating a new BMC version. If this function 236 * needs to delete any BMC version(s) it will delete the 237 * version(s) with the highest priority, skipping the 238 * functional BMC version. 239 * 240 * @param[in] caller - The Activation object that called this function. 241 */ 242 void freeSpace(const Activation& caller); 243 244 /** @brief Creates a updateable association to the 245 * "running" BMC software image 246 * 247 * @param[in] path - The path to create the association. 248 */ 249 void createUpdateableAssociation(const std::string& path); 250 251 /** @brief Persistent map of Version D-Bus objects and their 252 * version id */ 253 std::map<std::string, std::unique_ptr<VersionClass>> versions; 254 255 /** @brief Vector of needed BMC images in the tarball*/ 256 std::vector<std::string> imageUpdateList; 257 258 /** @brief The slot of running BMC image */ 259 uint32_t runningImageSlot = 0; 260 261 /** @brief Flag to indicate if the update interface is used or not */ 262 bool useUpdateDBusInterface; 263 264 private: 265 /** @brief Callback function for Software.Version match. 266 * @details Creates an Activation D-Bus object. 267 * 268 * @param[in] msg - Data associated with subscribed signal 269 */ 270 void createActivation(sdbusplus::message_t& msg); 271 272 /** 273 * @brief Validates the presence of SquashFS image in the image dir. 274 * 275 * @param[in] filePath - The path to the image dir. 276 * @param[out] result - ActivationStatus Enum. 277 * ready if validation was successful. 278 * invalid if validation fail. 279 * active if image is the current version. 280 * 281 */ 282 ActivationStatus validateSquashFSImage(const std::string& filePath); 283 284 /** @brief BMC factory reset - marks the read-write partition for 285 * recreation upon reboot. */ 286 void reset() override; 287 288 /** 289 * @brief Enables field mode, if value=true. 290 * 291 * @param[in] value - If true, enables field mode. 292 * @param[out] result - Returns the current state of field mode. 293 * 294 */ 295 bool fieldModeEnabled(bool value) override; 296 297 /** @brief Sets the BMC inventory item path under 298 * /xyz/openbmc_project/inventory/system/chassis/. */ 299 void setBMCInventoryPath(); 300 301 /** @brief The path to the BMC inventory item. */ 302 std::string bmcInventoryPath; 303 304 /** @brief Restores field mode status on reboot. */ 305 void restoreFieldModeStatus(); 306 307 /** @brief Creates a functional association to the 308 * "running" BMC software image 309 * 310 * @param[in] path - The path to create the association to. 311 */ 312 void createFunctionalAssociation(const std::string& path); 313 314 /** @brief D-Bus context */ 315 sdbusplus::async::context& ctx; 316 317 /** @brief Persistent sdbusplus D-Bus bus connection. */ 318 sdbusplus::bus_t& bus; 319 320 /** @brief The helper of image updater. */ 321 Helper helper; 322 323 /** @brief Persistent map of Activation D-Bus objects and their 324 * version id */ 325 std::map<std::string, std::unique_ptr<Activation>> activations; 326 327 /** @brief sdbusplus signal match for Software.Version */ 328 std::unique_ptr<sdbusplus::bus::match_t> versionMatch; 329 330 /** @brief This entry's associations */ 331 AssociationList assocs; 332 333 /** @brief Clears read only partition for 334 * given Activation D-Bus object. 335 * 336 * @param[in] versionId - The version id. 337 */ 338 void removeReadOnlyPartition(const std::string& versionId); 339 340 /** @brief Copies U-Boot from the currently booted BMC chip to the 341 * alternate chip. 342 */ 343 void mirrorUbootToAlt(); 344 345 /** @brief Check the required image files 346 * 347 * @param[in] filePath - BMC tarball file path 348 * @param[in] imageList - Image filenames included in the BMC tarball 349 * @param[out] result - Boolean 350 * true if all image files are found in BMC tarball 351 * false if one of image files is missing 352 */ 353 static bool checkImage(const std::string& filePath, 354 const std::vector<std::string>& imageList); 355 356 /** @brief Persistent MinimumVersion D-Bus object */ 357 std::unique_ptr<MinimumVersion> minimumVersionObject; 358 359 /** @brief Persistent map of Update D-Bus objects and their SwIds */ 360 std::map<std::string, std::unique_ptr<UpdateManager>> updateManagers; 361 362 #ifdef HOST_BIOS_UPGRADE 363 /** @brief Create the BIOS object without knowing the version. 364 * 365 * The object is created only to provide the DBus access so that an 366 * external service could set the correct BIOS version. 367 * On BIOS code update, the version is updated accordingly. 368 */ 369 void createBIOSObject(); 370 371 /** @brief Persistent Activation D-Bus object for BIOS */ 372 std::unique_ptr<Activation> biosActivation; 373 374 public: 375 /** @brief Persistent Version D-Bus object for BIOS */ 376 std::unique_ptr<VersionClass> biosVersion; 377 #endif 378 379 /** @brief Get the slot number of running image */ 380 void getRunningSlot(); 381 }; 382 383 } // namespace updater 384 } // namespace software 385 } // namespace phosphor 386