diff options
author | Michael Tritz <mtritz@us.ibm.com> | 2017-10-06 16:52:01 -0500 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-11-28 01:45:12 +0000 |
commit | 5b75651b350476455d3c2b6f948a273b1438a790 (patch) | |
tree | 9c107158d2afd46e7ee1d0a1ca74185e5a2e3910 | |
parent | 795d984d7113a237939d2d9c1cdbf71146a04144 (diff) | |
download | openpower-pnor-code-mgmt-5b75651b350476455d3c2b6f948a273b1438a790.tar.gz openpower-pnor-code-mgmt-5b75651b350476455d3c2b6f948a273b1438a790.zip |
Host updater: Remove the Object.Delete interface from functional version
This commit enhances the host updater by dynamically removing the
Object.Delete interface from a host activation that is currently
running. Once the host isn't running anymore, the interface is re-added
so that the activation may be deleted.
Additionally, isVersionFunctional() from the parent updater is exposed,
since this function is needed to determine whether a given activation
is currently running on the host.
Add the Delete interface to all interfaces when the item updater starts
up, because the chassis state would be off initially, and in the case
where it automatically powers on because the BMC rebooted while the host
was on, the chassis property signal would cause the Delete interface to
be removed.
Change-Id: I4afcc1ebe2e8a3ce212b426749295e79b68cac62
Signed-off-by: Michael Tritz <mtritz@us.ibm.com>
-rwxr-xr-x | activation.cpp | 38 | ||||
-rwxr-xr-x | activation.hpp | 86 | ||||
-rwxr-xr-x | configure.ac | 9 | ||||
-rw-r--r-- | item_updater.cpp | 18 | ||||
-rwxr-xr-x | item_updater.hpp | 16 |
5 files changed, 142 insertions, 25 deletions
diff --git a/activation.cpp b/activation.cpp index f7cfd1a0b..cd973b5c0 100755 --- a/activation.cpp +++ b/activation.cpp @@ -208,12 +208,44 @@ void Activation::unitStateChange(sdbusplus::message::message& msg) return; } -void Activation::delete_() +void Activation::updateDeleteInterface(sdbusplus::message::message& msg) +{ + std::string interface, chassisState; + std::map<std::string, sdbusplus::message::variant<std::string>> properties; + + msg.read(interface, properties); + + for (const auto& p : properties) + { + if (p.first == "CurrentPowerState") + { + chassisState = p.second.get<std::string>(); + } + } + + if ((parent.isVersionFunctional(this->versionId)) && + (chassisState != CHASSIS_STATE_OFF)) + { + if (deleteObject) + { + deleteObject.reset(nullptr); + } + } + else + { + if (!deleteObject) + { + deleteObject = std::make_unique<Delete>(bus, path, *this); + } + } +} + +void Delete::delete_() { // Remove active association - parent.removeActiveAssociation(path); + parent.parent.removeActiveAssociation(parent.path); - parent.erase(versionId); + parent.parent.erase(parent.versionId); } } // namespace updater diff --git a/activation.hpp b/activation.hpp index 3fcb6220a..286c85dda 100755 --- a/activation.hpp +++ b/activation.hpp @@ -8,6 +8,7 @@ #include "xyz/openbmc_project/Software/ActivationProgress/server.hpp" #include "xyz/openbmc_project/Object/Delete/server.hpp" #include "org/openbmc/Associations/server.hpp" +#include "config.h" namespace openpower { @@ -19,7 +20,6 @@ namespace updater using AssociationList = std::vector<std::tuple<std::string, std::string, std::string>>; using ActivationInherit = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Object::server::Delete, sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, sdbusplus::xyz::openbmc_project::Software::server::Activation, sdbusplus::org::openbmc::server::Associations>; @@ -29,6 +29,8 @@ using RedundancyPriorityInherit = sdbusplus::server::object::object< sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>; using ActivationProgressInherit = sdbusplus::server::object::object< sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>; +using DeleteInherit = sdbusplus::server::object::object< + sdbusplus::xyz::openbmc_project::Object::server::Delete>; namespace sdbusRule = sdbusplus::bus::match::rules; @@ -168,6 +170,53 @@ class ActivationProgress : public ActivationProgressInherit std::string path; }; +/** @class ActivationDelete + * @brief OpenBMC Delete implementation. + * @details A concrete implementation for xyz.openbmc_project.Object.Delete + * D-Bus API. + */ +class Delete : public DeleteInherit +{ + public: + /** @brief Constructs Delete. + * + * @param[in] bus - The D-Bus bus object + * @param[in] path - The D-Bus object path + * @param[in] parent - Parent object. + */ + Delete(sdbusplus::bus::bus& bus, + const std::string& path, + Activation& parent) : + DeleteInherit(bus, path.c_str(), true), + parent(parent), + bus(bus), + path(path) + { + std::vector<std::string> interfaces({interface}); + bus.emit_interfaces_added(path.c_str(), interfaces); + } + + ~Delete() + { + std::vector<std::string> interfaces({interface}); + bus.emit_interfaces_removed(path.c_str(), interfaces); + } + + /** + * @brief delete the D-Bus object. + */ + void delete_() override; + + /** @brief Parent Object. */ + Activation& parent; + + private: + static constexpr auto interface = + "xyz.openbmc_project.Object.Delete"; + sdbusplus::bus::bus& bus; + std::string path; +}; + /** @class Activation * @brief OpenBMC activation software management implementation. * @details A concrete implementation for @@ -206,7 +255,17 @@ class Activation : public ActivationInherit sdbusRule::interface( "org.freedesktop.systemd1.Manager"), std::bind(std::mem_fn(&Activation::unitStateChange), - this, std::placeholders::_1)) + this, std::placeholders::_1)), + chassisStateSignals( + bus, + sdbusRule::type::signal() + + sdbusRule::member("PropertiesChanged") + + sdbusRule::path(CHASSIS_STATE_PATH) + + sdbusRule::argN(0, CHASSIS_STATE_OBJ) + + sdbusRule::interface(SYSTEMD_PROPERTY_INTERFACE), + std::bind(std::mem_fn( + &Activation::updateDeleteInterface), this, + std::placeholders::_1)) { // Enable systemd signals subscribeToSystemdSignals(); @@ -252,6 +311,17 @@ class Activation : public ActivationInherit */ void unitStateChange(sdbusplus::message::message& msg); + /** @brief Update the Object.Delete interface for this activation + * + * Update the delete interface based on whether or not this activation + * is currently functional. A functional activation will have no + * Object.Delete, while a non-functional activation will have one. + * + * @param[in] msg - Data associated with subscribed signal + * + */ + void updateDeleteInterface(sdbusplus::message::message& msg); + /** * @brief subscribe to the systemd signals * @@ -291,9 +361,15 @@ class Activation : public ActivationInherit /** @brief Persistent RedundancyPriority dbus object */ std::unique_ptr<RedundancyPriority> redundancyPriority; + /** @brief Persistent Delete dbus object */ + std::unique_ptr<Delete> deleteObject; + /** @brief Used to subscribe to dbus systemd signals **/ sdbusplus::bus::match_t systemdSignals; + /** @brief Used to subscribe to chassis power state changes **/ + sdbusplus::bus::match_t chassisStateSignals; + /** @brief Tracks whether the read-only & read-write volumes have been *created as part of the activation process. **/ bool ubiVolumesCreated = false; @@ -304,12 +380,6 @@ class Activation : public ActivationInherit */ using ActivationInherit::activation; - /** @brief Deletes the d-bus object. - * - * - * */ - void delete_() override; - private: /** @brief Member function for clarity & brevity at activation start */ void startActivation(); diff --git a/configure.ac b/configure.ac index 4996623b0..96cde53ce 100755 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,13 @@ AC_ARG_VAR(MANIFEST_FILE, [The path to the MANIFEST file]) AS_IF([test "x$MANIFEST_FILE" == "x"], [MANIFEST_FILE="MANIFEST"]) AC_DEFINE_UNQUOTED([MANIFEST_FILE], ["$MANIFEST_FILE"], [The path to the MANIFEST file]) +AC_DEFINE(CHASSIS_STATE_PATH, "/xyz/openbmc_project/state/chassis0", + [The chassis state path.]) +AC_DEFINE(CHASSIS_STATE_OBJ, "xyz.openbmc_project.State.Chassis", + [The chassis state interface.]) +AC_DEFINE(CHASSIS_STATE_OFF, "xyz.openbmc_project.State.Chassis.PowerState.Off", + [The chassis state off property value.]) + AC_DEFINE(MAPPER_BUSNAME, "xyz.openbmc_project.ObjectMapper", [The object mapper busname.]) AC_DEFINE(MAPPER_PATH, "/xyz/openbmc_project/object_mapper", @@ -89,6 +96,8 @@ AC_DEFINE(SYSTEMD_PATH, "/org/freedesktop/systemd1", [systemd path.]) AC_DEFINE(SYSTEMD_INTERFACE, "org.freedesktop.systemd1.Manager", [systemd interface.]) +AC_DEFINE(SYSTEMD_PROPERTY_INTERFACE, "org.freedesktop.DBus.Properties", + [systemd properties interface.]) AC_DEFINE(PNOR_TOC_FILE, "pnor.toc", [The name of the PNOR table of contents file]) diff --git a/item_updater.cpp b/item_updater.cpp index 6b9ec1c67..60ea7cea9 100644 --- a/item_updater.cpp +++ b/item_updater.cpp @@ -26,11 +26,6 @@ using namespace sdbusplus::xyz::openbmc_project::Common::Error; using namespace phosphor::logging; constexpr auto squashFSImage = "pnor.xz.squashfs"; -constexpr auto CHASSIS_STATE_PATH = "/xyz/openbmc_project/state/chassis0"; -constexpr auto CHASSIS_STATE_OBJ = "xyz.openbmc_project.State.Chassis"; -constexpr auto CHASSIS_STATE_OFF = - "xyz.openbmc_project.State.Chassis.PowerState.Off"; -constexpr auto SYSTEMD_PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"; // TODO: Change paths once openbmc/openbmc#1663 is completed. constexpr auto MBOXD_INTERFACE = "org.openbmc.mboxd"; @@ -135,6 +130,12 @@ void ItemUpdater::createActivation(sdbusplus::message::message& m) extendedVersion, activationState, associations))); + + activations.find(versionId)->second->deleteObject = + std::make_unique<Delete>(bus, + path, + *activations.find(versionId)->second); + versions.insert(std::make_pair( versionId, std::make_unique<Version>( @@ -221,6 +222,11 @@ void ItemUpdater::processPNORImage() activationState, associations))); + activations.find(id)->second->deleteObject = + std::make_unique<Delete>(bus, + path, + *activations.find(id)->second); + // If Active, create RedundancyPriority instance for this version. if (activationState == server::Activation::Activations::Active) { @@ -361,7 +367,7 @@ void ItemUpdater::reset() return; } -bool ItemUpdater::isVersionFunctional(std::string versionId) +bool ItemUpdater::isVersionFunctional(const std::string& versionId) { if (!fs::exists(PNOR_RO_ACTIVE_PATH)) { diff --git a/item_updater.hpp b/item_updater.hpp index 893e8b9c5..e0c4450b0 100755 --- a/item_updater.hpp +++ b/item_updater.hpp @@ -172,6 +172,14 @@ class ItemUpdater : public ItemUpdaterInherit /** @brief Persistent GardReset dbus object */ std::unique_ptr<GardReset> gardReset; + /** @brief Check whether the provided image id is the functional one + * + * @param[in] - versionId - The id of the image to check. + * + * @return - Returns true if this version is currently functional. + */ + static bool isVersionFunctional(const std::string& versionId); + private: /** @brief Callback function for Software.Version match. * @details Creates an Activation D-Bus object. @@ -227,14 +235,6 @@ class ItemUpdater : public ItemUpdaterInherit * Activation D-Bus object */ void reset() override; - /** @brief Check whether the provided image id is the functional one - * - * @param[in] - versionId - The id of the image to check. - * - * @return - Returns true if this version is currently functional. - */ - static bool isVersionFunctional(std::string versionId); - /** @brief Check whether the host is running * * @return - Returns true if the Chassis is powered on. |