diff options
author | Lei YU <mine260309@gmail.com> | 2019-02-21 15:52:53 +0800 |
---|---|---|
committer | Lei YU <mine260309@gmail.com> | 2019-03-08 14:25:30 +0800 |
commit | 9b21efc5b44cd8956325f7856a6ef417aa1d7703 (patch) | |
tree | 636d35cdef9b55a78e5d77539ef63f115ca31bab | |
parent | eaa9b07637e457392f89e83194b2d818c9dfa9cb (diff) | |
download | openpower-pnor-code-mgmt-9b21efc5b44cd8956325f7856a6ef417aa1d7703.tar.gz openpower-pnor-code-mgmt-9b21efc5b44cd8956325f7856a6ef417aa1d7703.zip |
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>
-rw-r--r-- | activation.cpp | 157 | ||||
-rw-r--r-- | activation.hpp | 43 | ||||
-rw-r--r-- | ubi/Makefile.am.include | 1 | ||||
-rw-r--r-- | ubi/activation_ubi.cpp | 183 | ||||
-rw-r--r-- | ubi/activation_ubi.hpp | 61 | ||||
-rw-r--r-- | ubi/item_updater_ubi.cpp | 8 |
6 files changed, 266 insertions, 187 deletions
diff --git a/activation.cpp b/activation.cpp index 52427f0f6..166057289 100644 --- a/activation.cpp +++ b/activation.cpp @@ -78,129 +78,9 @@ void Activation::unsubscribeFromSystemdSignals() 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 @@ void Activation::deleteImageManagerObject() 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 2fc08d72c..7e8eec5ad 100644 --- a/activation.hpp +++ b/activation.hpp @@ -64,7 +64,7 @@ class RedundancyPriority : public RedundancyPriorityInherit 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 @@ class Activation : public ActivationInherit // Emit deferred signal. emit_object_added(); } + virtual ~Activation() = default; /** @brief Activation property get function * @@ -210,14 +211,6 @@ class Activation : public ActivationInherit */ 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 @@ class Activation : public ActivationInherit 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 @@ class Activation : public ActivationInherit /** @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 @@ class Activation : public ActivationInherit 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 @@ class Activation : public ActivationInherit * 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 a83666101..c75293d83 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 000000000..9ce7085b8 --- /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 000000000..a17bb8263 --- /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 7a6424451..f576b3c28 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 @@ void ItemUpdaterUbi::createActivation(sdbusplus::message::message& m) ->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 @@ void ItemUpdaterUbi::processPNORImage() // 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 @@ void ItemUpdaterUbi::processPNORImage() 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); } |