Refactor: Split Activation into common and ubi
Activations has a few functions coupled with ubi, split them into
ubi/activation_ubi
* Keep common code in activation.
* Make start/finishActivation() pure virtual.
* Move ubi specific code into ubi.
* Move ubiVolumnCreated into ubi.
* Make validateSignature() not inline, otherwise it gets compile error.
Tested: On the last commit of the patch series, run code update and
factory reset on Witherspoon and all work fine.
Change-Id: I7c8a0de6b0be4b1e9814ea75fd802a014b4aacfc
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/activation.cpp b/activation.cpp
index 52427f0..1660572 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -78,129 +78,9 @@
return;
}
-void Activation::startActivation()
-{
- // Since the squashfs image has not yet been loaded to pnor and the
- // RW volumes have not yet been created, we need to start the
- // service files for each of those actions.
-
- if (!activationProgress)
- {
- activationProgress = std::make_unique<ActivationProgress>(bus, path);
- }
-
- if (!activationBlocksTransition)
- {
- activationBlocksTransition =
- std::make_unique<ActivationBlocksTransition>(bus, path);
- }
-
- constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
- auto ubimountServiceFile =
- std::string(ubimountService) + versionId + ".service";
- auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
- SYSTEMD_INTERFACE, "StartUnit");
- method.append(ubimountServiceFile, "replace");
- bus.call_noreply(method);
-
- activationProgress->progress(10);
-}
-
-void Activation::finishActivation()
-{
- activationProgress->progress(90);
-
- // Set Redundancy Priority before setting to Active
- if (!redundancyPriority)
- {
- redundancyPriority =
- std::make_unique<RedundancyPriority>(bus, path, *this, 0);
- }
-
- activationProgress->progress(100);
-
- activationBlocksTransition.reset(nullptr);
- activationProgress.reset(nullptr);
-
- ubiVolumesCreated = false;
- Activation::unsubscribeFromSystemdSignals();
- // Remove version object from image manager
- Activation::deleteImageManagerObject();
- // Create active association
- parent.createActiveAssociation(path);
-}
-
-auto Activation::activation(Activations value) -> Activations
-{
-
- if (value != softwareServer::Activation::Activations::Active)
- {
- redundancyPriority.reset(nullptr);
- }
-
- if (value == softwareServer::Activation::Activations::Activating)
- {
- parent.freeSpace();
- softwareServer::Activation::activation(value);
-
- if (ubiVolumesCreated == false)
- {
- // Enable systemd signals
- Activation::subscribeToSystemdSignals();
-
-#ifdef WANT_SIGNATURE_VERIFY
- // Validate the signed image.
- if (!validateSignature())
- {
- // Cleanup
- activationBlocksTransition.reset(nullptr);
- activationProgress.reset(nullptr);
-
- return softwareServer::Activation::activation(
- softwareServer::Activation::Activations::Failed);
- }
-#endif
- Activation::startActivation();
- return softwareServer::Activation::activation(value);
- }
- else if (ubiVolumesCreated == true)
- {
- // Only when the squashfs image is finished loading AND the RW
- // volumes have been created do we proceed with activation. To
- // verify that this happened, we check for the mount dirs PNOR_PRSV
- // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
-
- if ((fs::is_directory(PNOR_PRSV)) &&
- (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
- (fs::is_directory(PNOR_RO_PREFIX + versionId)))
- {
- Activation::finishActivation();
- return softwareServer::Activation::activation(
- softwareServer::Activation::Activations::Active);
- }
- else
- {
- activationBlocksTransition.reset(nullptr);
- activationProgress.reset(nullptr);
- return softwareServer::Activation::activation(
- softwareServer::Activation::Activations::Failed);
- }
- }
- }
- else
- {
- activationBlocksTransition.reset(nullptr);
- activationProgress.reset(nullptr);
- }
-
- return softwareServer::Activation::activation(value);
-}
-
auto Activation::requestedActivation(RequestedActivations value)
-> RequestedActivations
{
- ubiVolumesCreated = false;
-
if ((value == softwareServer::Activation::RequestedActivations::Active) &&
(softwareServer::Activation::requestedActivation() !=
softwareServer::Activation::RequestedActivations::Active))
@@ -294,46 +174,11 @@
uint8_t RedundancyPriority::priority(uint8_t value)
{
parent.parent.freePriority(value, parent.versionId);
- storeToFile(parent.versionId, value);
return softwareServer::RedundancyPriority::priority(value);
}
-void Activation::unitStateChange(sdbusplus::message::message& msg)
-{
- uint32_t newStateID{};
- sdbusplus::message::object_path newStateObjPath;
- std::string newStateUnit{};
- std::string newStateResult{};
-
- // Read the msg and populate each variable
- msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
-
- auto ubimountServiceFile =
- "obmc-flash-bios-ubimount@" + versionId + ".service";
-
- if (newStateUnit == ubimountServiceFile && newStateResult == "done")
- {
- ubiVolumesCreated = true;
- activationProgress->progress(activationProgress->progress() + 50);
- }
-
- if (ubiVolumesCreated)
- {
- Activation::activation(
- softwareServer::Activation::Activations::Activating);
- }
-
- if ((newStateUnit == ubimountServiceFile) &&
- (newStateResult == "failed" || newStateResult == "dependency"))
- {
- Activation::activation(softwareServer::Activation::Activations::Failed);
- }
-
- return;
-}
-
#ifdef WANT_SIGNATURE_VERIFY
-inline bool Activation::validateSignature()
+bool Activation::validateSignature()
{
using Signature = openpower::software::image::Signature;
fs::path imageDir(IMG_DIR);
diff --git a/activation.hpp b/activation.hpp
index 2fc08d7..7e8eec5 100644
--- a/activation.hpp
+++ b/activation.hpp
@@ -64,7 +64,7 @@
bus.emit_interfaces_added(path.c_str(), interfaces);
}
- ~RedundancyPriority()
+ virtual ~RedundancyPriority()
{
std::vector<std::string> interfaces({interface});
bus.emit_interfaces_removed(path.c_str(), interfaces);
@@ -203,6 +203,7 @@
// Emit deferred signal.
emit_object_added();
}
+ virtual ~Activation() = default;
/** @brief Activation property get function
*
@@ -210,14 +211,6 @@
*/
using ActivationInherit::activation;
- /** @brief Overloaded Activation property setter function
- *
- * @param[in] value - One of Activation::Activations
- *
- * @return Success or exception thrown
- */
- Activations activation(Activations value) override;
-
/** @brief Overloaded requestedActivation property setter function
*
* @param[in] value - One of Activation::RequestedActivations
@@ -227,16 +220,6 @@
RequestedActivations
requestedActivation(RequestedActivations value) override;
- /** @brief Check if systemd state change is relevant to this object
- *
- * Instance specific interface to handle the detected systemd state
- * change
- *
- * @param[in] msg - Data associated with subscribed signal
- *
- */
- void unitStateChange(sdbusplus::message::message& msg);
-
/**
* @brief subscribe to the systemd signals
*
@@ -279,17 +262,23 @@
/** @brief Used to subscribe to dbus systemd signals **/
sdbusplus::bus::match_t systemdSignals;
- /** @brief Tracks whether the read-only & read-write volumes have been
- *created as part of the activation process. **/
- bool ubiVolumesCreated = false;
-
/** @brief activation status property get function
*
* @returns Activations - The activation value
*/
using ActivationInherit::activation;
- private:
+ protected:
+ /** @brief Check if systemd state change is relevant to this object
+ *
+ * Instance specific interface to handle the detected systemd state
+ * change
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ *
+ */
+ virtual void unitStateChange(sdbusplus::message::message& msg) = 0;
+
/**
* @brief Deletes the version from Image Manager and the
* untar image from image upload dir.
@@ -297,10 +286,10 @@
void deleteImageManagerObject();
/** @brief Member function for clarity & brevity at activation start */
- void startActivation();
+ virtual void startActivation() = 0;
/** @brief Member function for clarity & brevity at activation end */
- void finishActivation();
+ virtual void finishActivation() = 0;
#ifdef WANT_SIGNATURE_VERIFY
/**
@@ -315,7 +304,7 @@
* false for unsuccessful signature validation or
* any internal failure during the mapper call.
*/
- inline bool validateSignature();
+ bool validateSignature();
/**
* @brief Gets the fieldModeEnabled property value.
diff --git a/ubi/Makefile.am.include b/ubi/Makefile.am.include
index a836661..c75293d 100644
--- a/ubi/Makefile.am.include
+++ b/ubi/Makefile.am.include
@@ -1,3 +1,4 @@
openpower_update_manager_SOURCES += \
+ %reldir%/activation_ubi.cpp \
%reldir%/item_updater_ubi.cpp \
%reldir%/watch.cpp
diff --git a/ubi/activation_ubi.cpp b/ubi/activation_ubi.cpp
new file mode 100644
index 0000000..9ce7085
--- /dev/null
+++ b/ubi/activation_ubi.cpp
@@ -0,0 +1,183 @@
+#include "activation_ubi.hpp"
+
+#include "item_updater.hpp"
+#include "serialize.hpp"
+
+#include <experimental/filesystem>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+namespace fs = std::experimental::filesystem;
+namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
+
+uint8_t RedundancyPriorityUbi::priority(uint8_t value)
+{
+ storeToFile(parent.versionId, value);
+ return RedundancyPriority::priority(value);
+}
+
+auto ActivationUbi::activation(Activations value) -> Activations
+{
+
+ if (value != softwareServer::Activation::Activations::Active)
+ {
+ redundancyPriority.reset(nullptr);
+ }
+
+ if (value == softwareServer::Activation::Activations::Activating)
+ {
+ parent.freeSpace();
+ softwareServer::Activation::activation(value);
+
+ if (ubiVolumesCreated == false)
+ {
+ // Enable systemd signals
+ subscribeToSystemdSignals();
+
+#ifdef WANT_SIGNATURE_VERIFY
+ // Validate the signed image.
+ if (!validateSignature())
+ {
+ // Cleanup
+ activationBlocksTransition.reset(nullptr);
+ activationProgress.reset(nullptr);
+
+ return softwareServer::Activation::activation(
+ softwareServer::Activation::Activations::Failed);
+ }
+#endif
+ startActivation();
+ return softwareServer::Activation::activation(value);
+ }
+ else if (ubiVolumesCreated == true)
+ {
+ // Only when the squashfs image is finished loading AND the RW
+ // volumes have been created do we proceed with activation. To
+ // verify that this happened, we check for the mount dirs PNOR_PRSV
+ // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
+
+ if ((fs::is_directory(PNOR_PRSV)) &&
+ (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
+ (fs::is_directory(PNOR_RO_PREFIX + versionId)))
+ {
+ finishActivation();
+ return softwareServer::Activation::activation(
+ softwareServer::Activation::Activations::Active);
+ }
+ else
+ {
+ activationBlocksTransition.reset(nullptr);
+ activationProgress.reset(nullptr);
+ return softwareServer::Activation::activation(
+ softwareServer::Activation::Activations::Failed);
+ }
+ }
+ }
+ else
+ {
+ activationBlocksTransition.reset(nullptr);
+ activationProgress.reset(nullptr);
+ }
+
+ return softwareServer::Activation::activation(value);
+}
+
+auto ActivationUbi::requestedActivation(RequestedActivations value)
+ -> RequestedActivations
+{
+ ubiVolumesCreated = false;
+ return Activation::requestedActivation(value);
+}
+
+void ActivationUbi::startActivation()
+{
+ // Since the squashfs image has not yet been loaded to pnor and the
+ // RW volumes have not yet been created, we need to start the
+ // service files for each of those actions.
+
+ if (!activationProgress)
+ {
+ activationProgress = std::make_unique<ActivationProgress>(bus, path);
+ }
+
+ if (!activationBlocksTransition)
+ {
+ activationBlocksTransition =
+ std::make_unique<ActivationBlocksTransition>(bus, path);
+ }
+
+ constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
+ auto ubimountServiceFile =
+ std::string(ubimountService) + versionId + ".service";
+ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+ method.append(ubimountServiceFile, "replace");
+ bus.call_noreply(method);
+
+ activationProgress->progress(10);
+}
+
+void ActivationUbi::unitStateChange(sdbusplus::message::message& msg)
+{
+ uint32_t newStateID{};
+ sdbusplus::message::object_path newStateObjPath;
+ std::string newStateUnit{};
+ std::string newStateResult{};
+
+ // Read the msg and populate each variable
+ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+
+ auto ubimountServiceFile =
+ "obmc-flash-bios-ubimount@" + versionId + ".service";
+
+ if (newStateUnit == ubimountServiceFile && newStateResult == "done")
+ {
+ ubiVolumesCreated = true;
+ activationProgress->progress(activationProgress->progress() + 50);
+ }
+
+ if (ubiVolumesCreated)
+ {
+ activation(softwareServer::Activation::Activations::Activating);
+ }
+
+ if ((newStateUnit == ubimountServiceFile) &&
+ (newStateResult == "failed" || newStateResult == "dependency"))
+ {
+ activation(softwareServer::Activation::Activations::Failed);
+ }
+
+ return;
+}
+
+void ActivationUbi::finishActivation()
+{
+ activationProgress->progress(90);
+
+ // Set Redundancy Priority before setting to Active
+ if (!redundancyPriority)
+ {
+ redundancyPriority =
+ std::make_unique<RedundancyPriorityUbi>(bus, path, *this, 0);
+ }
+
+ activationProgress->progress(100);
+
+ activationBlocksTransition.reset(nullptr);
+ activationProgress.reset(nullptr);
+
+ ubiVolumesCreated = false;
+ unsubscribeFromSystemdSignals();
+ // Remove version object from image manager
+ deleteImageManagerObject();
+ // Create active association
+ parent.createActiveAssociation(path);
+}
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
diff --git a/ubi/activation_ubi.hpp b/ubi/activation_ubi.hpp
new file mode 100644
index 0000000..a17bb82
--- /dev/null
+++ b/ubi/activation_ubi.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "activation.hpp"
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+class RedundancyPriorityUbi : public RedundancyPriority
+{
+ public:
+ using RedundancyPriority::RedundancyPriority;
+ virtual ~RedundancyPriorityUbi() = default;
+
+ /** @brief Overloaded Priority property set function
+ *
+ * @param[in] value - uint8_t
+ *
+ * @return Success or exception thrown
+ */
+ uint8_t priority(uint8_t value) override;
+};
+
+/** @class ActivationUbi
+ * @brief OpenBMC activation software management implementation.
+ * @details A concrete implementation for
+ * xyz.openbmc_project.Software.Activation DBus API.
+ */
+class ActivationUbi : public Activation
+{
+ public:
+ using Activation::Activation;
+ virtual ~ActivationUbi() = default;
+
+ /** @brief Overloaded Activation property setter function
+ *
+ * @param[in] value - One of Activation::Activations
+ *
+ * @return Success or exception thrown
+ */
+ Activations activation(Activations value) override;
+
+ RequestedActivations
+ requestedActivation(RequestedActivations value) override;
+
+ private:
+ /** @brief Tracks whether the read-only & read-write volumes have been
+ *created as part of the activation process. **/
+ bool ubiVolumesCreated = false;
+
+ void unitStateChange(sdbusplus::message::message& msg) override;
+ void startActivation() override;
+ void finishActivation() override;
+};
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
diff --git a/ubi/item_updater_ubi.cpp b/ubi/item_updater_ubi.cpp
index 7a64244..f576b3c 100644
--- a/ubi/item_updater_ubi.cpp
+++ b/ubi/item_updater_ubi.cpp
@@ -2,7 +2,7 @@
#include "item_updater_ubi.hpp"
-#include "activation.hpp"
+#include "activation_ubi.hpp"
#include "serialize.hpp"
#include "version.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
@@ -127,7 +127,7 @@
->second;
activations.insert(std::make_pair(
- versionId, std::make_unique<Activation>(
+ versionId, std::make_unique<ActivationUbi>(
bus, path, *this, versionId, extendedVersion,
activationState, associations)));
@@ -202,7 +202,7 @@
// Create Activation instance for this version.
activations.insert(
- std::make_pair(id, std::make_unique<Activation>(
+ std::make_pair(id, std::make_unique<ActivationUbi>(
bus, path, *this, id, extendedVersion,
activationState, associations)));
@@ -216,7 +216,7 @@
entry("VERSIONID=%s", id.c_str()));
}
activations.find(id)->second->redundancyPriority =
- std::make_unique<RedundancyPriority>(
+ std::make_unique<RedundancyPriorityUbi>(
bus, path, *(activations.find(id)->second), priority);
}