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 /ubi | |
| 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>
Diffstat (limited to 'ubi')
| -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 |
4 files changed, 249 insertions, 4 deletions
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); } |

