1 #pragma once 2 3 #include "config.h" 4 5 #include "flash.hpp" 6 #include "utils.hpp" 7 #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp" 8 #include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp" 9 10 #include <sdbusplus/server.hpp> 11 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 12 #include <xyz/openbmc_project/Software/Activation/server.hpp> 13 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp> 14 #include <xyz/openbmc_project/Software/ApplyTime/common.hpp> 15 16 #ifdef WANT_SIGNATURE_VERIFY 17 #include <filesystem> 18 #endif 19 20 namespace phosphor 21 { 22 namespace software 23 { 24 namespace updater 25 { 26 27 #ifdef WANT_SIGNATURE_VERIFY 28 namespace fs = std::filesystem; 29 #endif 30 31 using AssociationList = 32 std::vector<std::tuple<std::string, std::string, std::string>>; 33 using ActivationInherit = sdbusplus::server::object_t< 34 sdbusplus::server::xyz::openbmc_project::software::Activation, 35 sdbusplus::server::xyz::openbmc_project::association::Definitions>; 36 using ActivationBlocksTransitionInherit = 37 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 38 software::ActivationBlocksTransition>; 39 using RedundancyPriorityInherit = sdbusplus::server::object_t< 40 sdbusplus::server::xyz::openbmc_project::software::RedundancyPriority>; 41 using ActivationProgressInherit = sdbusplus::server::object_t< 42 sdbusplus::server::xyz::openbmc_project::software::ActivationProgress>; 43 using ApplyTimeIntf = 44 sdbusplus::common::xyz::openbmc_project::software::ApplyTime; 45 46 constexpr auto applyTimeImmediate = 47 "xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.Immediate"; 48 constexpr auto applyTimeIntf = "xyz.openbmc_project.Software.ApplyTime"; 49 constexpr auto dbusPropIntf = "org.freedesktop.DBus.Properties"; 50 constexpr auto applyTimeObjPath = "/xyz/openbmc_project/software/apply_time"; 51 constexpr auto applyTimeProp = "RequestedApplyTime"; 52 53 namespace sdbusRule = sdbusplus::bus::match::rules; 54 55 class ItemUpdater; 56 class Activation; 57 class RedundancyPriority; 58 59 /** @class RedundancyPriority 60 * @brief OpenBMC RedundancyPriority implementation 61 * @details A concrete implementation for 62 * xyz.openbmc_project.Software.RedundancyPriority DBus API. 63 */ 64 class RedundancyPriority : public RedundancyPriorityInherit 65 { 66 public: 67 /** @brief Constructs RedundancyPriority. 68 * 69 * @param[in] bus - The Dbus bus object 70 * @param[in] path - The Dbus object path 71 * @param[in] parent - Parent object. 72 * @param[in] value - The redundancyPriority value 73 * @param[in] freePriority - Call freePriorioty, default to true 74 */ RedundancyPriority(sdbusplus::bus_t & bus,const std::string & path,Activation & parent,uint8_t value,bool freePriority=true)75 RedundancyPriority(sdbusplus::bus_t& bus, const std::string& path, 76 Activation& parent, uint8_t value, 77 bool freePriority = true) : 78 RedundancyPriorityInherit(bus, path.c_str(), 79 action::emit_interface_added), 80 parent(parent) 81 { 82 // Set Property 83 if (freePriority) 84 { 85 priority(value); 86 } 87 else 88 { 89 sdbusPriority(value); 90 } 91 } 92 93 /** @brief Overridden Priority property set function, calls freePriority 94 * to bump the duplicated priority values. 95 * 96 * @param[in] value - uint8_t 97 * 98 * @return Success or exception thrown 99 */ 100 uint8_t priority(uint8_t value) override; 101 102 /** @brief Non-Overriden Priority property set function 103 * 104 * @param[in] value - uint8_t 105 * 106 * @return Success or exception thrown 107 */ 108 uint8_t sdbusPriority(uint8_t value); 109 110 /** @brief Priority property get function 111 * 112 * @returns uint8_t - The Priority value 113 */ 114 using RedundancyPriorityInherit::priority; 115 116 /** @brief Parent Object. */ 117 Activation& parent; 118 }; 119 120 /** @class ActivationBlocksTransition 121 * @brief OpenBMC ActivationBlocksTransition implementation. 122 * @details A concrete implementation for 123 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API. 124 */ 125 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit 126 { 127 public: 128 /** @brief Constructs ActivationBlocksTransition. 129 * 130 * @param[in] bus - The Dbus bus object 131 * @param[in] path - The Dbus object path 132 */ ActivationBlocksTransition(sdbusplus::bus_t & bus,const std::string & path)133 ActivationBlocksTransition(sdbusplus::bus_t& bus, const std::string& path) : 134 ActivationBlocksTransitionInherit(bus, path.c_str(), 135 action::emit_interface_added), 136 bus(bus) 137 { 138 enableRebootGuard(); 139 } 140 ~ActivationBlocksTransition()141 ~ActivationBlocksTransition() override 142 { 143 disableRebootGuard(); 144 } 145 146 ActivationBlocksTransition(const ActivationBlocksTransition&) = delete; 147 ActivationBlocksTransition& 148 operator=(const ActivationBlocksTransition&) = delete; 149 ActivationBlocksTransition(ActivationBlocksTransition&&) = delete; 150 ActivationBlocksTransition& 151 operator=(ActivationBlocksTransition&&) = delete; 152 153 private: 154 sdbusplus::bus_t& bus; 155 156 /** @brief Enables a Guard that blocks any BMC reboot commands */ 157 void enableRebootGuard(); 158 159 /** @brief Disables any guard that was blocking the BMC reboot */ 160 void disableRebootGuard(); 161 }; 162 163 class ActivationProgress : public ActivationProgressInherit 164 { 165 public: 166 /** @brief Constructs ActivationProgress. 167 * 168 * @param[in] bus - The Dbus bus object 169 * @param[in] path - The Dbus object path 170 */ ActivationProgress(sdbusplus::bus_t & bus,const std::string & path)171 ActivationProgress(sdbusplus::bus_t& bus, const std::string& path) : 172 ActivationProgressInherit(bus, path.c_str(), 173 action::emit_interface_added) 174 { 175 progress(0); 176 } 177 }; 178 179 /** @class Activation 180 * @brief OpenBMC activation software management implementation. 181 * @details A concrete implementation for 182 * xyz.openbmc_project.Software.Activation DBus API. 183 */ 184 class Activation : public ActivationInherit, public Flash 185 { 186 public: 187 /** @brief Constructs Activation Software Manager 188 * 189 * @param[in] bus - The Dbus bus object 190 * @param[in] path - The Dbus object path 191 * @param[in] parent - Parent object. 192 * @param[in] versionId - The software version id 193 * @param[in] activationStatus - The status of Activation 194 * @param[in] assocs - Association objects 195 */ Activation(sdbusplus::bus_t & bus,const std::string & path,ItemUpdater & parent,std::string & versionId,sdbusplus::server::xyz::openbmc_project::software::Activation::Activations activationStatus,AssociationList & assocs)196 Activation(sdbusplus::bus_t& bus, const std::string& path, 197 ItemUpdater& parent, std::string& versionId, 198 sdbusplus::server::xyz::openbmc_project::software::Activation:: 199 Activations activationStatus, 200 AssociationList& assocs) : 201 ActivationInherit(bus, path.c_str(), 202 ActivationInherit::action::defer_emit), 203 bus(bus), path(path), parent(parent), versionId(versionId), 204 systemdSignals( 205 bus, 206 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 207 sdbusRule::path("/org/freedesktop/systemd1") + 208 sdbusRule::interface("org.freedesktop.systemd1.Manager"), 209 std::bind(std::mem_fn(&Activation::unitStateChange), this, 210 std::placeholders::_1)) 211 { 212 // Set Properties. 213 activation(activationStatus); 214 associations(assocs); 215 216 // Emit deferred signal. 217 emit_object_added(); 218 } 219 220 /** @brief Overloaded Activation property setter function 221 * 222 * @param[in] value - One of Activation::Activations 223 * 224 * @return Success or exception thrown 225 */ 226 Activations activation(Activations value) override; 227 228 /** @brief Activation */ 229 using ActivationInherit::activation; 230 231 /** @brief Overloaded requestedActivation property setter function 232 * 233 * @param[in] value - One of Activation::RequestedActivations 234 * 235 * @return Success or exception thrown 236 */ 237 RequestedActivations 238 requestedActivation(RequestedActivations value) override; 239 240 /** @brief Overloaded write flash function */ 241 void flashWrite() override; 242 243 /** 244 * @brief Handle the success of the flashWrite() function 245 * 246 * @details Perform anything that is necessary to mark the activation 247 * successful after the image has been written to flash. Sets the Activation 248 * value to Active. 249 */ 250 void onFlashWriteSuccess(); 251 252 #ifdef HOST_BIOS_UPGRADE 253 /* @brief write to Host flash function */ 254 void flashWriteHost(); 255 256 /** @brief Function that acts on Bios upgrade service file state changes */ 257 void onStateChangesBios(sdbusplus::message_t& /*msg*/); 258 #endif 259 260 /** @brief Overloaded function that acts on service file state changes */ 261 void onStateChanges(sdbusplus::message_t& /*msg*/) override; 262 263 /** @brief Check if systemd state change is relevant to this object 264 * 265 * Instance specific interface to handle the detected systemd state 266 * change 267 * 268 * @param[in] msg - Data associated with subscribed signal 269 * 270 */ 271 void unitStateChange(sdbusplus::message_t& msg); 272 273 /** 274 * @brief subscribe to the systemd signals 275 * 276 * This object needs to capture when it's systemd targets complete 277 * so it can keep it's state updated 278 * 279 */ 280 void subscribeToSystemdSignals(); 281 282 /** 283 * @brief unsubscribe from the systemd signals 284 * 285 * systemd signals are only of interest during the activation process. 286 * Once complete, we want to unsubscribe to avoid unnecessary calls of 287 * unitStateChange(). 288 * 289 */ 290 void unsubscribeFromSystemdSignals(); 291 292 /** 293 * @brief Deletes the version from Image Manager and the 294 * untar image from image upload dir. 295 */ 296 void deleteImageManagerObject(); 297 298 /** 299 * @brief Determine the configured image apply time value 300 * 301 * @return true if the image apply time value is immediate 302 **/ 303 bool checkApplyTimeImmediate(); 304 305 /** 306 * @brief Reboot the BMC. Called when ApplyTime is immediate. 307 * 308 * @return none 309 **/ 310 void rebootBmc(); 311 312 /** @brief Persistent sdbusplus DBus bus connection */ 313 sdbusplus::bus_t& bus; 314 315 /** @brief Persistent DBus object path */ 316 std::string path; 317 318 /** @brief Parent Object. */ 319 ItemUpdater& parent; 320 321 /** @brief Version id */ 322 std::string versionId; 323 324 /** @brief Persistent ActivationBlocksTransition dbus object */ 325 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 326 327 /** @brief Persistent RedundancyPriority dbus object */ 328 std::unique_ptr<RedundancyPriority> redundancyPriority; 329 330 /** @brief Persistent ActivationProgress dbus object */ 331 std::unique_ptr<ActivationProgress> activationProgress; 332 333 /** @brief Apply time */ 334 ApplyTimeIntf::RequestedApplyTimes applyTime; 335 336 /** @brief Used to subscribe to dbus systemd signals **/ 337 sdbusplus::bus::match_t systemdSignals; 338 339 /** @brief Tracks whether the read-write volume has been created as 340 * part of the activation process. **/ 341 bool rwVolumeCreated = false; 342 343 /** @brief Tracks whether the read-only volume has been created as 344 * part of the activation process. **/ 345 bool roVolumeCreated = false; 346 347 /** @brief Tracks if the service that updates the U-Boot environment 348 * variables has completed. **/ 349 bool ubootEnvVarsUpdated = false; 350 351 #ifdef WANT_SIGNATURE_VERIFY 352 private: 353 /** @brief Verify signature of the images. 354 * 355 * @param[in] imageDir - The path of images to verify 356 * @param[in] confDir - The path of configs for verification 357 * 358 * @return true if verification successful and false otherwise 359 */ 360 static bool verifySignature(const fs::path& imageDir, 361 const fs::path& confDir); 362 363 /** @brief Called when image verification fails. */ 364 void onVerifyFailed(); 365 #endif 366 }; 367 368 } // namespace updater 369 } // namespace software 370 } // namespace phosphor 371