summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Tritz <mtritz@us.ibm.com>2017-10-06 16:52:01 -0500
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2017-11-28 01:45:12 +0000
commit5b75651b350476455d3c2b6f948a273b1438a790 (patch)
tree9c107158d2afd46e7ee1d0a1ca74185e5a2e3910
parent795d984d7113a237939d2d9c1cdbf71146a04144 (diff)
downloadopenpower-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-xactivation.cpp38
-rwxr-xr-xactivation.hpp86
-rwxr-xr-xconfigure.ac9
-rw-r--r--item_updater.cpp18
-rwxr-xr-xitem_updater.hpp16
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.
OpenPOWER on IntegriCloud