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