1 #pragma once 2 3 #include <sdbusplus/server.hpp> 4 #include <xyz/openbmc_project/Software/Activation/server.hpp> 5 #include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp> 6 #include "xyz/openbmc_project/Software/ExtendedVersion/server.hpp" 7 #include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp" 8 #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp" 9 #include "xyz/openbmc_project/Object/Delete/server.hpp" 10 #include "org/openbmc/Associations/server.hpp" 11 12 namespace openpower 13 { 14 namespace software 15 { 16 namespace updater 17 { 18 19 using AssociationList = 20 std::vector<std::tuple<std::string, std::string, std::string>>; 21 using ActivationInherit = sdbusplus::server::object::object< 22 sdbusplus::xyz::openbmc_project::Object::server::Delete, 23 sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, 24 sdbusplus::xyz::openbmc_project::Software::server::Activation, 25 sdbusplus::org::openbmc::server::Associations>; 26 using ActivationBlocksTransitionInherit = sdbusplus::server::object::object< 27 sdbusplus::xyz::openbmc_project::Software::server::ActivationBlocksTransition>; 28 using RedundancyPriorityInherit = sdbusplus::server::object::object< 29 sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>; 30 using ActivationProgressInherit = sdbusplus::server::object::object< 31 sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>; 32 33 namespace sdbusRule = sdbusplus::bus::match::rules; 34 35 class ItemUpdater; 36 class Activation; 37 class RedundancyPriority; 38 39 /** @class RedundancyPriority 40 * @brief OpenBMC RedundancyPriority implementation 41 * @details A concrete implementation for 42 * xyz.openbmc_project.Software.RedundancyPriority DBus API. 43 */ 44 class RedundancyPriority : public RedundancyPriorityInherit 45 { 46 public: 47 /** @brief Constructs RedundancyPriority. 48 * 49 * @param[in] bus - The Dbus bus object 50 * @param[in] path - The Dbus object path 51 * @param[in] parent - Parent object. 52 * @param[in] value - The redundancyPriority value 53 */ 54 RedundancyPriority(sdbusplus::bus::bus& bus, 55 const std::string& path, 56 Activation& parent, 57 uint8_t value) : 58 RedundancyPriorityInherit(bus, 59 path.c_str(), true), 60 parent(parent), 61 bus(bus), 62 path(path) 63 { 64 // Set Property 65 priority(value); 66 std::vector<std::string> interfaces({interface}); 67 bus.emit_interfaces_added(path.c_str(), interfaces); 68 } 69 70 ~RedundancyPriority() 71 { 72 std::vector<std::string> interfaces({interface}); 73 bus.emit_interfaces_removed(path.c_str(), interfaces); 74 } 75 76 /** @brief Overloaded Priority property set function 77 * 78 * @param[in] value - uint8_t 79 * 80 * @return Success or exception thrown 81 */ 82 uint8_t priority(uint8_t value) override; 83 84 /** @brief Priority property get function 85 * 86 * @returns uint8_t - The Priority value 87 */ 88 using RedundancyPriorityInherit::priority; 89 90 /** @brief Parent Object. */ 91 Activation& parent; 92 93 private: 94 // TODO Remove once openbmc/openbmc#1975 is resolved 95 static constexpr auto interface = 96 "xyz.openbmc_project.Software.RedundancyPriority"; 97 sdbusplus::bus::bus& bus; 98 std::string path; 99 }; 100 101 /** @class ActivationBlocksTransition 102 * @brief OpenBMC ActivationBlocksTransition implementation. 103 * @details A concrete implementation for 104 * xyz.openbmc_project.Software.ActivationBlocksTransition DBus API. 105 */ 106 class ActivationBlocksTransition : public ActivationBlocksTransitionInherit 107 { 108 public: 109 /** @brief Constructs ActivationBlocksTransition. 110 * 111 * @param[in] bus - The Dbus bus object 112 * @param[in] path - The Dbus object path 113 */ 114 ActivationBlocksTransition(sdbusplus::bus::bus& bus, 115 const std::string& path) : 116 ActivationBlocksTransitionInherit(bus, path.c_str(), true), 117 bus(bus), 118 path(path) 119 { 120 std::vector<std::string> interfaces({interface}); 121 bus.emit_interfaces_added(path.c_str(), interfaces); 122 } 123 124 ~ActivationBlocksTransition() 125 { 126 std::vector<std::string> interfaces({interface}); 127 bus.emit_interfaces_removed(path.c_str(), interfaces); 128 } 129 130 private: 131 // TODO Remove once openbmc/openbmc#1975 is resolved 132 static constexpr auto interface = 133 "xyz.openbmc_project.Software.ActivationBlocksTransition"; 134 sdbusplus::bus::bus& bus; 135 std::string path; 136 }; 137 138 class ActivationProgress : public ActivationProgressInherit 139 { 140 public: 141 /** @brief Constructs ActivationProgress. 142 * 143 * @param[in] bus - The Dbus bus object 144 * @param[in] path - The Dbus object path 145 */ 146 ActivationProgress(sdbusplus::bus::bus& bus, 147 const std::string& path) : 148 ActivationProgressInherit(bus, path.c_str(), true), 149 bus(bus), 150 path(path) 151 { 152 progress(0); 153 std::vector<std::string> interfaces({interface}); 154 bus.emit_interfaces_added(path.c_str(), interfaces); 155 } 156 157 ~ActivationProgress() 158 { 159 std::vector<std::string> interfaces({interface}); 160 bus.emit_interfaces_removed(path.c_str(), interfaces); 161 } 162 163 private: 164 // TODO Remove once openbmc/openbmc#1975 is resolved 165 static constexpr auto interface = 166 "xyz.openbmc_project.Software.ActivationProgress"; 167 sdbusplus::bus::bus& bus; 168 std::string path; 169 }; 170 171 /** @class Activation 172 * @brief OpenBMC activation software management implementation. 173 * @details A concrete implementation for 174 * xyz.openbmc_project.Software.Activation DBus API. 175 */ 176 class Activation : public ActivationInherit 177 { 178 public: 179 /** @brief Constructs Activation Software Manager 180 * 181 * @param[in] bus - The Dbus bus object 182 * @param[in] path - The Dbus object path 183 * @param[in] parent - Parent object. 184 * @param[in] versionId - The software version id 185 * @param[in] extVersion - The extended version 186 * @param[in] activationStatus - The status of Activation 187 * @param[in] assocs - Association objects 188 */ 189 Activation(sdbusplus::bus::bus& bus, const std::string& path, 190 ItemUpdater& parent, 191 std::string& versionId, 192 std::string& extVersion, 193 sdbusplus::xyz::openbmc_project::Software:: 194 server::Activation::Activations activationStatus, 195 AssociationList& assocs) : 196 ActivationInherit(bus, path.c_str(), true), 197 bus(bus), 198 path(path), 199 parent(parent), 200 versionId(versionId), 201 systemdSignals( 202 bus, 203 sdbusRule::type::signal() + 204 sdbusRule::member("JobRemoved") + 205 sdbusRule::path("/org/freedesktop/systemd1") + 206 sdbusRule::interface( 207 "org.freedesktop.systemd1.Manager"), 208 std::bind(std::mem_fn(&Activation::unitStateChange), 209 this, std::placeholders::_1)) 210 { 211 // Enable systemd signals 212 subscribeToSystemdSignals(); 213 // Set Properties. 214 extendedVersion(extVersion); 215 activation(activationStatus); 216 associations(assocs); 217 218 // Emit deferred signal. 219 emit_object_added(); 220 } 221 222 /** @brief Activation property get function 223 * 224 * @returns One of Activation::Activations 225 */ 226 using ActivationInherit::activation; 227 228 /** @brief Overloaded Activation property setter function 229 * 230 * @param[in] value - One of Activation::Activations 231 * 232 * @return Success or exception thrown 233 */ 234 Activations activation(Activations value) override; 235 236 /** @brief Overloaded requestedActivation property setter function 237 * 238 * @param[in] value - One of Activation::RequestedActivations 239 * 240 * @return Success or exception thrown 241 */ 242 RequestedActivations requestedActivation(RequestedActivations value) 243 override; 244 245 /** @brief Check if systemd state change is relevant to this object 246 * 247 * Instance specific interface to handle the detected systemd state 248 * change 249 * 250 * @param[in] msg - Data associated with subscribed signal 251 * 252 */ 253 void unitStateChange(sdbusplus::message::message& msg); 254 255 /** 256 * @brief subscribe to the systemd signals 257 * 258 * This object needs to capture when it's systemd targets complete 259 * so it can keep it's state updated 260 * 261 **/ 262 void subscribeToSystemdSignals(); 263 264 /** 265 * @brief unsubscribe from the systemd signals 266 * 267 * Once the activation process has completed successfully, we can 268 * safely unsubscribe from systemd signals. 269 * 270 **/ 271 void unsubscribeFromSystemdSignals(); 272 273 /** @brief Persistent sdbusplus DBus bus connection */ 274 sdbusplus::bus::bus& bus; 275 276 /** @brief Persistent DBus object path */ 277 std::string path; 278 279 /** @brief Parent Object. */ 280 ItemUpdater& parent; 281 282 /** @brief Version id */ 283 std::string versionId; 284 285 /** @brief Persistent ActivationBlocksTransition dbus object */ 286 std::unique_ptr<ActivationBlocksTransition> activationBlocksTransition; 287 288 /** @brief Persistent ActivationProgress dbus object */ 289 std::unique_ptr<ActivationProgress> activationProgress; 290 291 /** @brief Persistent RedundancyPriority dbus object */ 292 std::unique_ptr<RedundancyPriority> redundancyPriority; 293 294 /** @brief Used to subscribe to dbus systemd signals **/ 295 sdbusplus::bus::match_t systemdSignals; 296 297 /** @brief Tracks whether the read-only & read-write volumes have been 298 *created as part of the activation process. **/ 299 bool ubiVolumesCreated = false; 300 301 /** @brief activation status property get function 302 * 303 * @returns Activations - The activation value 304 */ 305 using ActivationInherit::activation; 306 307 /** @brief Deletes the d-bus object. 308 * 309 * 310 * */ 311 void delete_() override; 312 313 private: 314 /** @brief Member function for clarity & brevity at activation start */ 315 void startActivation(); 316 317 /** @brief Member function for clarity & brevity at activation end */ 318 void finishActivation(); 319 }; 320 321 } // namespace updater 322 } // namespace software 323 } // namespace openpower 324