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