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