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& operator=(const ActivationBlocksTransition&) = 47 delete; 48 ActivationBlocksTransition(ActivationBlocksTransition&&) = delete; 49 ActivationBlocksTransition& operator=(ActivationBlocksTransition&&) = 50 delete; 51 52 /** @brief Constructs ActivationBlocksTransition. 53 * 54 * @param[in] bus - The Dbus bus object 55 * @param[in] path - The Dbus object path 56 */ ActivationBlocksTransition(sdbusplus::bus_t & bus,const std::string & path)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 ~ActivationBlocksTransition()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 */ ActivationProgress(sdbusplus::bus_t & bus,const std::string & path)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 */ Activation(sdbusplus::bus_t & bus,const std::string & objPath,const std::string & versionId,const std::string & extVersion,Status activationStatus,const AssociationList & assocs,const std::string & filePath,AssociationInterface * associationInterface,ActivationListener * activationListener)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 // Emit deferred signal. 152 emit_object_added(); 153 } 154 155 /** @brief Overloaded Activation property setter function 156 * 157 * @param[in] value - One of Activation::Activations 158 * 159 * @return Success or exception thrown 160 */ 161 Status activation(Status value) override; 162 163 /** @brief Activation */ 164 using ActivationInherit::activation; 165 166 /** @brief Overloaded requestedActivation property setter function 167 * 168 * @param[in] value - One of Activation::RequestedActivations 169 * 170 * @return Success or exception thrown 171 */ 172 RequestedActivations requestedActivation( 173 RequestedActivations value) override; 174 175 /** @brief Overloaded ExtendedVersion property setter function 176 * 177 * @param[in] value - Extended version value 178 * 179 * @return New value of property 180 */ 181 std::string extendedVersion(std::string value) override; 182 183 /** @brief Get the object path */ getObjectPath() const184 const std::string& getObjectPath() const 185 { 186 return objPath; 187 } 188 189 /** @brief Get the version ID */ getVersionId() const190 const std::string& getVersionId() const 191 { 192 return versionId; 193 } 194 195 private: 196 /** @brief Check if systemd state change is relevant to this object 197 * 198 * Instance specific interface to handle the detected systemd state 199 * change 200 * 201 * @param[in] msg - Data associated with subscribed signal 202 * 203 */ 204 void unitStateChange(sdbusplus::message_t& msg); 205 206 /** 207 * @brief Delete the version from Image Manager and the 208 * untar image from image upload dir. 209 */ 210 void deleteImageManagerObject(); 211 212 /** @brief Invoke the update service for the PSU 213 * 214 * @param[in] psuInventoryPath - The PSU inventory to be updated. 215 * 216 * @return true if the update starts, and false if it fails. 217 */ 218 bool doUpdate(const std::string& psuInventoryPath); 219 220 /** @brief Do PSU update one-by-one 221 * 222 * @return true if the update starts, and false if it fails. 223 */ 224 bool doUpdate(); 225 226 /** @brief Handle an update done event */ 227 void onUpdateDone(); 228 229 /** @brief Handle an update failure event */ 230 void onUpdateFailed(); 231 232 /** @brief Start PSU update */ 233 Status startActivation(); 234 235 /** @brief Finish PSU update */ 236 void finishActivation(); 237 238 /** @brief Check if the PSU is present */ 239 bool isPresent(const std::string& psuInventoryPath); 240 241 /** @brief Check if the PSU is compatible with this software*/ 242 bool isCompatible(const std::string& psuInventoryPath); 243 244 /** @brief Store the updated PSU image to persistent dir */ 245 void storeImage(); 246 247 /** @brief Construct the systemd service name 248 * 249 * @details Throws an exception if an error occurs 250 * 251 * @param[in] psuInventoryPath - The PSU inventory to be updated. 252 * 253 * @return The escaped string of systemd unit to do the PSU update. 254 */ 255 std::string getUpdateService(const std::string& psuInventoryPath); 256 257 /** @brief Persistent sdbusplus DBus bus connection */ 258 sdbusplus::bus_t& bus; 259 260 /** @brief Persistent DBus object path */ 261 std::string objPath; 262 263 /** @brief Version id */ 264 std::string versionId; 265 266 /** @brief Used to subscribe to dbus systemd signals */ 267 sdbusplus::bus::match_t systemdSignals; 268 269 /** @brief The queue of psu objects to be updated */ 270 std::queue<std::string> psuQueue; 271 272 /** @brief The progress step for each PSU update is done */ 273 uint32_t progressStep; 274 275 /** @brief The PSU update systemd unit */ 276 std::string psuUpdateUnit; 277 278 /** @brief The PSU Inventory path of the current updating PSU */ 279 std::string currentUpdatingPsu; 280 281 /** @brief Persistent ActivationBlocksTransition dbus object */ 282 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 283 284 /** @brief Persistent ActivationProgress dbus object */ 285 std::unique_ptr<ActivationProgress> activationProgress; 286 287 /** @brief The AssociationInterface pointer */ 288 AssociationInterface* associationInterface; 289 290 /** @brief The activationListener pointer */ 291 ActivationListener* activationListener; 292 293 /** @brief The PSU manufacturer of the software */ 294 std::string manufacturer; 295 296 /** @brief The PSU model of the software */ 297 std::string model; 298 299 /** @brief Indicates whether to automatically activate again after current 300 * request finishes */ 301 bool shouldActivateAgain{false}; 302 }; 303 304 } // namespace updater 305 } // namespace software 306 } // namespace phosphor 307