1 #pragma once 2 3 #include "config.h" 4 5 #include "activation_listener.hpp" 6 #include "association_interface.hpp" 7 #include "types.hpp" 8 #include "version.hpp" 9 10 #include <queue> 11 #include <sdbusplus/server.hpp> 12 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 13 #include <xyz/openbmc_project/Common/FilePath/server.hpp> 14 #include <xyz/openbmc_project/Software/Activation/server.hpp> 15 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp> 16 #include <xyz/openbmc_project/Software/ActivationProgress/server.hpp> 17 #include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp> 18 19 class TestActivation; 20 21 namespace phosphor 22 { 23 namespace software 24 { 25 namespace updater 26 { 27 28 namespace sdbusRule = sdbusplus::bus::match::rules; 29 30 using ActivationBlocksTransitionInherit = 31 sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::Software:: 32 server::ActivationBlocksTransition>; 33 34 /** @class ActivationBlocksTransition 35 * @brief OpenBMC ActivationBlocksTransition implementation. 36 * @details A concrete implementation for 37 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API. 38 */ 39 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit 40 { 41 public: 42 /** @brief Constructs ActivationBlocksTransition. 43 * 44 * @param[in] bus - The Dbus bus object 45 * @param[in] path - The Dbus object path 46 */ 47 ActivationBlocksTransition(sdbusplus::bus_t& bus, const std::string& path) : 48 ActivationBlocksTransitionInherit(bus, path.c_str(), 49 action::emit_interface_added), 50 bus(bus) 51 { 52 enableRebootGuard(); 53 } 54 55 ~ActivationBlocksTransition() 56 { 57 disableRebootGuard(); 58 } 59 60 private: 61 sdbusplus::bus_t& bus; 62 63 /** @brief Enables a Guard that blocks any BMC reboot commands */ 64 void enableRebootGuard(); 65 66 /** @brief Disables any guard that was blocking the BMC reboot */ 67 void disableRebootGuard(); 68 }; 69 70 using ActivationProgressInherit = sdbusplus::server::object_t< 71 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>; 72 73 class ActivationProgress : public ActivationProgressInherit 74 { 75 public: 76 /** @brief Constructs ActivationProgress. 77 * 78 * @param[in] bus - The Dbus bus object 79 * @param[in] path - The Dbus object path 80 */ 81 ActivationProgress(sdbusplus::bus_t& bus, const std::string& path) : 82 ActivationProgressInherit(bus, path.c_str(), 83 action::emit_interface_added) 84 { 85 progress(0); 86 } 87 }; 88 89 using ActivationInherit = sdbusplus::server::object_t< 90 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, 91 sdbusplus::xyz::openbmc_project::Software::server::Activation, 92 sdbusplus::xyz::openbmc_project::Association::server::Definitions, 93 sdbusplus::xyz::openbmc_project::Common::server::FilePath>; 94 95 /** @class Activation 96 * @brief OpenBMC activation software management implementation. 97 * @details A concrete implementation for 98 * xyz.openbmc_project.Software.Activation DBus API. 99 */ 100 class Activation : public ActivationInherit 101 { 102 public: 103 friend class ::TestActivation; 104 using Status = Activations; 105 106 /** @brief Constructs Activation Software Manager 107 * 108 * @param[in] bus - The Dbus bus object 109 * @param[in] path - The Dbus object path 110 * @param[in] versionId - The software version id 111 * @param[in] extVersion - The extended version 112 * @param[in] activationStatus - The status of Activation 113 * @param[in] assocs - Association objects 114 * @param[in] filePath - The image filesystem path 115 */ 116 Activation(sdbusplus::bus_t& bus, const std::string& objPath, 117 const std::string& versionId, const std::string& extVersion, 118 Status activationStatus, const AssociationList& assocs, 119 const std::string& filePath, 120 AssociationInterface* associationInterface, 121 ActivationListener* activationListener) : 122 ActivationInherit(bus, objPath.c_str(), 123 ActivationInherit::action::defer_emit), 124 bus(bus), objPath(objPath), versionId(versionId), 125 systemdSignals( 126 bus, 127 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + 128 sdbusRule::path("/org/freedesktop/systemd1") + 129 sdbusRule::interface("org.freedesktop.systemd1.Manager"), 130 std::bind(&Activation::unitStateChange, this, 131 std::placeholders::_1)), 132 associationInterface(associationInterface), 133 activationListener(activationListener) 134 { 135 // Set Properties. 136 extendedVersion(extVersion); 137 activation(activationStatus); 138 associations(assocs); 139 path(filePath); 140 141 auto info = Version::getExtVersionInfo(extVersion); 142 manufacturer = info["manufacturer"]; 143 model = info["model"]; 144 145 // Emit deferred signal. 146 emit_object_added(); 147 } 148 149 /** @brief Overloaded Activation property setter function 150 * 151 * @param[in] value - One of Activation::Activations 152 * 153 * @return Success or exception thrown 154 */ 155 Status activation(Status value) override; 156 157 /** @brief Activation */ 158 using ActivationInherit::activation; 159 160 /** @brief Overloaded requestedActivation property setter function 161 * 162 * @param[in] value - One of Activation::RequestedActivations 163 * 164 * @return Success or exception thrown 165 */ 166 RequestedActivations 167 requestedActivation(RequestedActivations value) override; 168 169 /** @brief Get the object path */ 170 const std::string& getObjectPath() const 171 { 172 return objPath; 173 } 174 175 /** @brief Get the version ID */ 176 const std::string& getVersionId() const 177 { 178 return versionId; 179 } 180 181 private: 182 /** @brief Check if systemd state change is relevant to this object 183 * 184 * Instance specific interface to handle the detected systemd state 185 * change 186 * 187 * @param[in] msg - Data associated with subscribed signal 188 * 189 */ 190 void unitStateChange(sdbusplus::message_t& msg); 191 192 /** 193 * @brief Delete the version from Image Manager and the 194 * untar image from image upload dir. 195 */ 196 void deleteImageManagerObject(); 197 198 /** @brief Invoke the update service for the PSU 199 * 200 * @param[in] psuInventoryPath - The PSU inventory to be updated. 201 * 202 * @return true if the update starts, and false if it fails. 203 */ 204 bool doUpdate(const std::string& psuInventoryPath); 205 206 /** @brief Do PSU update one-by-one 207 * 208 * @return true if the update starts, and false if it fails. 209 */ 210 bool doUpdate(); 211 212 /** @brief Handle an update done event */ 213 void onUpdateDone(); 214 215 /** @brief Handle an update failure event */ 216 void onUpdateFailed(); 217 218 /** @brief Start PSU update */ 219 Status startActivation(); 220 221 /** @brief Finish PSU update */ 222 void finishActivation(); 223 224 /** @brief Check if the PSU is comaptible with this software*/ 225 bool isCompatible(const std::string& psuInventoryPath); 226 227 /** @brief Store the updated PSU image to persistent dir */ 228 void storeImage(); 229 230 /** @brief Construct the systemd service name 231 * 232 * @param[in] psuInventoryPath - The PSU inventory to be updated. 233 * 234 * @return The escaped string of systemd unit to do the PSU update. 235 */ 236 std::string getUpdateService(const std::string& psuInventoryPath); 237 238 /** @brief Persistent sdbusplus DBus bus connection */ 239 sdbusplus::bus_t& bus; 240 241 /** @brief Persistent DBus object path */ 242 std::string objPath; 243 244 /** @brief Version id */ 245 std::string versionId; 246 247 /** @brief Used to subscribe to dbus systemd signals */ 248 sdbusplus::bus::match_t systemdSignals; 249 250 /** @brief The queue of psu objects to be updated */ 251 std::queue<std::string> psuQueue; 252 253 /** @brief The progress step for each PSU update is done */ 254 uint32_t progressStep; 255 256 /** @brief The PSU update systemd unit */ 257 std::string psuUpdateUnit; 258 259 /** @brief The PSU Inventory path of the current updating PSU */ 260 std::string currentUpdatingPsu; 261 262 /** @brief Persistent ActivationBlocksTransition dbus object */ 263 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 264 265 /** @brief Persistent ActivationProgress dbus object */ 266 std::unique_ptr<ActivationProgress> activationProgress; 267 268 /** @brief The AssociationInterface pointer */ 269 AssociationInterface* associationInterface; 270 271 /** @brief The activationListener pointer */ 272 ActivationListener* activationListener; 273 274 /** @brief The PSU manufacturer of the software */ 275 std::string manufacturer; 276 277 /** @brief The PSU model of the software */ 278 std::string model; 279 }; 280 281 } // namespace updater 282 } // namespace software 283 } // namespace phosphor 284