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