From 70dcb63a8c749f2a1d61621f75858085df05abcf Mon Sep 17 00:00:00 2001 From: Adriana Kobylak Date: Tue, 27 Feb 2018 15:46:52 -0600 Subject: Enable clang code format Change-Id: I4490e930459a7eab6f6dd15198418c5314755d3f Signed-off-by: Adriana Kobylak --- .clang-format | 85 +++++++++ activation.cpp | 89 ++++----- activation.hpp | 493 ++++++++++++++++++++++++-------------------------- item_updater.cpp | 237 +++++++++--------------- item_updater.hpp | 418 +++++++++++++++++++++--------------------- item_updater_main.cpp | 8 +- serialize.cpp | 24 +-- test/utest.cpp | 4 +- version.cpp | 14 +- version.hpp | 295 ++++++++++++++---------------- watch.cpp | 27 +-- watch.hpp | 145 ++++++++------- 12 files changed, 899 insertions(+), 940 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..bbc1bb1c4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,85 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +PointerAlignment: Left +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/activation.cpp b/activation.cpp index 40acc894d..350bf5ad1 100755 --- a/activation.cpp +++ b/activation.cpp @@ -17,15 +17,13 @@ namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server; using namespace phosphor::logging; -constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; -constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1"; +constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; +constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1"; void Activation::subscribeToSystemdSignals() { - auto method = this->bus.new_method_call(SYSTEMD_SERVICE, - SYSTEMD_OBJ_PATH, - SYSTEMD_INTERFACE, - "Subscribe"); + auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH, + SYSTEMD_INTERFACE, "Subscribe"); this->bus.call_noreply(method); return; @@ -33,10 +31,8 @@ void Activation::subscribeToSystemdSignals() void Activation::unsubscribeFromSystemdSignals() { - auto method = this->bus.new_method_call(SYSTEMD_SERVICE, - SYSTEMD_OBJ_PATH, - SYSTEMD_INTERFACE, - "Unsubscribe"); + auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH, + SYSTEMD_INTERFACE, "Unsubscribe"); this->bus.call_noreply(method); return; @@ -50,24 +46,20 @@ void Activation::startActivation() if (!activationProgress) { - activationProgress = std::make_unique( - bus, path); + activationProgress = std::make_unique(bus, path); } if (!activationBlocksTransition) { activationBlocksTransition = - std::make_unique(bus, path); + std::make_unique(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"); + 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); @@ -81,8 +73,8 @@ void Activation::finishActivation() // Set Redundancy Priority before setting to Active if (!redundancyPriority) { - redundancyPriority = std::make_unique( - bus, path, *this, 0); + redundancyPriority = + std::make_unique(bus, path, *this, 0); } activationProgress->progress(100); @@ -98,8 +90,7 @@ void Activation::finishActivation() parent.createActiveAssociation(path); } -auto Activation::activation(Activations value) -> - Activations +auto Activation::activation(Activations value) -> Activations { if (value != softwareServer::Activation::Activations::Active) @@ -130,14 +121,14 @@ auto Activation::activation(Activations value) -> { Activation::finishActivation(); return softwareServer::Activation::activation( - softwareServer::Activation::Activations::Active); + softwareServer::Activation::Activations::Active); } else { activationBlocksTransition.reset(nullptr); activationProgress.reset(nullptr); return softwareServer::Activation::activation( - softwareServer::Activation::Activations::Failed); + softwareServer::Activation::Activations::Failed); } } } @@ -150,23 +141,22 @@ auto Activation::activation(Activations value) -> return softwareServer::Activation::activation(value); } -auto Activation::requestedActivation(RequestedActivations value) -> - RequestedActivations +auto Activation::requestedActivation(RequestedActivations value) + -> RequestedActivations { ubiVolumesCreated = false; if ((value == softwareServer::Activation::RequestedActivations::Active) && (softwareServer::Activation::requestedActivation() != - softwareServer::Activation::RequestedActivations::Active)) + softwareServer::Activation::RequestedActivations::Active)) { if ((softwareServer::Activation::activation() == - softwareServer::Activation::Activations::Ready) || + softwareServer::Activation::Activations::Ready) || (softwareServer::Activation::activation() == - softwareServer::Activation::Activations::Failed)) + softwareServer::Activation::Activations::Failed)) { Activation::activation( - softwareServer::Activation::Activations::Activating); - + softwareServer::Activation::Activations::Activating); } } return softwareServer::Activation::requestedActivation(value); @@ -175,14 +165,12 @@ auto Activation::requestedActivation(RequestedActivations value) -> void Activation::deleteImageManagerObject() { // Get the Delete object for inside image_manager - auto method = this->bus.new_method_call(MAPPER_BUSNAME, - MAPPER_PATH, - MAPPER_INTERFACE, - "GetObject"); + auto method = this->bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, + MAPPER_INTERFACE, "GetObject"); method.append(path); - method.append(std::vector({ - "xyz.openbmc_project.Object.Delete"})); + method.append( + std::vector({"xyz.openbmc_project.Object.Delete"})); auto mapperResponseMsg = bus.call(method); if (mapperResponseMsg.is_method_error()) { @@ -200,13 +188,12 @@ void Activation::deleteImageManagerObject() } // Call the Delete object for inside image_manager - method = this->bus.new_method_call((mapperResponse.begin()->first).c_str(), - path.c_str(), - "xyz.openbmc_project.Object.Delete", - "Delete"); + method = this->bus.new_method_call( + (mapperResponse.begin()->first).c_str(), path.c_str(), + "xyz.openbmc_project.Object.Delete", "Delete"); mapperResponseMsg = bus.call(method); - //Check that the bus call didn't result in an error + // Check that the bus call didn't result in an error if (mapperResponseMsg.is_method_error()) { log("Error in Deleting image from image manager", @@ -224,30 +211,30 @@ uint8_t RedundancyPriority::priority(uint8_t value) void Activation::unitStateChange(sdbusplus::message::message& msg) { - uint32_t newStateID {}; + uint32_t newStateID{}; sdbusplus::message::object_path newStateObjPath; std::string newStateUnit{}; std::string newStateResult{}; - //Read the msg and populate each variable + // Read the msg and populate each variable msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); auto ubimountServiceFile = - "obmc-flash-bios-ubimount@" + versionId + ".service"; + "obmc-flash-bios-ubimount@" + versionId + ".service"; - if(newStateUnit == ubimountServiceFile && newStateResult == "done") + if (newStateUnit == ubimountServiceFile && newStateResult == "done") { ubiVolumesCreated = true; activationProgress->progress(activationProgress->progress() + 50); } - if(ubiVolumesCreated) + if (ubiVolumesCreated) { Activation::activation( - softwareServer::Activation::Activations::Activating); + softwareServer::Activation::Activations::Activating); } - if((newStateUnit == ubimountServiceFile) && + if ((newStateUnit == ubimountServiceFile) && (newStateResult == "failed" || newStateResult == "dependency")) { Activation::activation(softwareServer::Activation::Activations::Failed); diff --git a/activation.hpp b/activation.hpp index ed077ae37..2edbca5c0 100755 --- a/activation.hpp +++ b/activation.hpp @@ -16,13 +16,14 @@ namespace updater { using AssociationList = - std::vector>; + std::vector>; using ActivationInherit = sdbusplus::server::object::object< sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion, sdbusplus::xyz::openbmc_project::Software::server::Activation, sdbusplus::org::openbmc::server::Associations>; using ActivationBlocksTransitionInherit = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Software::server::ActivationBlocksTransition>; + sdbusplus::xyz::openbmc_project::Software::server:: + ActivationBlocksTransition>; using RedundancyPriorityInherit = sdbusplus::server::object::object< sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>; using ActivationProgressInherit = sdbusplus::server::object::object< @@ -41,59 +42,54 @@ class RedundancyPriority; */ class RedundancyPriority : public RedundancyPriorityInherit { - public: - /** @brief Constructs RedundancyPriority. - * - * @param[in] bus - The Dbus bus object - * @param[in] path - The Dbus object path - * @param[in] parent - Parent object. - * @param[in] value - The redundancyPriority value - */ - RedundancyPriority(sdbusplus::bus::bus& bus, - const std::string& path, - Activation& parent, - uint8_t value) : - RedundancyPriorityInherit(bus, - path.c_str(), true), - parent(parent), - bus(bus), - path(path) - { - // Set Property - priority(value); - std::vector interfaces({interface}); - bus.emit_interfaces_added(path.c_str(), interfaces); - } - - ~RedundancyPriority() - { - std::vector interfaces({interface}); - bus.emit_interfaces_removed(path.c_str(), interfaces); - } - - /** @brief Overloaded Priority property set function - * - * @param[in] value - uint8_t - * - * @return Success or exception thrown - */ - uint8_t priority(uint8_t value) override; - - /** @brief Priority property get function - * - * @returns uint8_t - The Priority value - */ - using RedundancyPriorityInherit::priority; - - /** @brief Parent Object. */ - Activation& parent; - - private: - // TODO Remove once openbmc/openbmc#1975 is resolved - static constexpr auto interface = - "xyz.openbmc_project.Software.RedundancyPriority"; - sdbusplus::bus::bus& bus; - std::string path; + public: + /** @brief Constructs RedundancyPriority. + * + * @param[in] bus - The Dbus bus object + * @param[in] path - The Dbus object path + * @param[in] parent - Parent object. + * @param[in] value - The redundancyPriority value + */ + RedundancyPriority(sdbusplus::bus::bus& bus, const std::string& path, + Activation& parent, uint8_t value) : + RedundancyPriorityInherit(bus, path.c_str(), true), + parent(parent), bus(bus), path(path) + { + // Set Property + priority(value); + std::vector interfaces({interface}); + bus.emit_interfaces_added(path.c_str(), interfaces); + } + + ~RedundancyPriority() + { + std::vector interfaces({interface}); + bus.emit_interfaces_removed(path.c_str(), interfaces); + } + + /** @brief Overloaded Priority property set function + * + * @param[in] value - uint8_t + * + * @return Success or exception thrown + */ + uint8_t priority(uint8_t value) override; + + /** @brief Priority property get function + * + * @returns uint8_t - The Priority value + */ + using RedundancyPriorityInherit::priority; + + /** @brief Parent Object. */ + Activation& parent; + + private: + // TODO Remove once openbmc/openbmc#1975 is resolved + static constexpr auto interface = + "xyz.openbmc_project.Software.RedundancyPriority"; + sdbusplus::bus::bus& bus; + std::string path; }; /** @class ActivationBlocksTransition @@ -103,67 +99,63 @@ class RedundancyPriority : public RedundancyPriorityInherit */ class ActivationBlocksTransition : public ActivationBlocksTransitionInherit { - public: - /** @brief Constructs ActivationBlocksTransition. - * - * @param[in] bus - The Dbus bus object - * @param[in] path - The Dbus object path - */ - ActivationBlocksTransition(sdbusplus::bus::bus& bus, - const std::string& path) : - ActivationBlocksTransitionInherit(bus, path.c_str(), true), - bus(bus), - path(path) - { - std::vector interfaces({interface}); - bus.emit_interfaces_added(path.c_str(), interfaces); - } - - ~ActivationBlocksTransition() - { - std::vector interfaces({interface}); - bus.emit_interfaces_removed(path.c_str(), interfaces); - } - - private: - // TODO Remove once openbmc/openbmc#1975 is resolved - static constexpr auto interface = - "xyz.openbmc_project.Software.ActivationBlocksTransition"; - sdbusplus::bus::bus& bus; - std::string path; + public: + /** @brief Constructs ActivationBlocksTransition. + * + * @param[in] bus - The Dbus bus object + * @param[in] path - The Dbus object path + */ + ActivationBlocksTransition(sdbusplus::bus::bus& bus, + const std::string& path) : + ActivationBlocksTransitionInherit(bus, path.c_str(), true), + bus(bus), path(path) + { + std::vector interfaces({interface}); + bus.emit_interfaces_added(path.c_str(), interfaces); + } + + ~ActivationBlocksTransition() + { + std::vector interfaces({interface}); + bus.emit_interfaces_removed(path.c_str(), interfaces); + } + + private: + // TODO Remove once openbmc/openbmc#1975 is resolved + static constexpr auto interface = + "xyz.openbmc_project.Software.ActivationBlocksTransition"; + sdbusplus::bus::bus& bus; + std::string path; }; class ActivationProgress : public ActivationProgressInherit { - public: - /** @brief Constructs ActivationProgress. - * - * @param[in] bus - The Dbus bus object - * @param[in] path - The Dbus object path - */ - ActivationProgress(sdbusplus::bus::bus& bus, - const std::string& path) : - ActivationProgressInherit(bus, path.c_str(), true), - bus(bus), - path(path) - { - progress(0); - std::vector interfaces({interface}); - bus.emit_interfaces_added(path.c_str(), interfaces); - } - - ~ActivationProgress() - { - std::vector interfaces({interface}); - bus.emit_interfaces_removed(path.c_str(), interfaces); - } - - private: - // TODO Remove once openbmc/openbmc#1975 is resolved - static constexpr auto interface = - "xyz.openbmc_project.Software.ActivationProgress"; - sdbusplus::bus::bus& bus; - std::string path; + public: + /** @brief Constructs ActivationProgress. + * + * @param[in] bus - The Dbus bus object + * @param[in] path - The Dbus object path + */ + ActivationProgress(sdbusplus::bus::bus& bus, const std::string& path) : + ActivationProgressInherit(bus, path.c_str(), true), bus(bus), path(path) + { + progress(0); + std::vector interfaces({interface}); + bus.emit_interfaces_added(path.c_str(), interfaces); + } + + ~ActivationProgress() + { + std::vector interfaces({interface}); + bus.emit_interfaces_removed(path.c_str(), interfaces); + } + + private: + // TODO Remove once openbmc/openbmc#1975 is resolved + static constexpr auto interface = + "xyz.openbmc_project.Software.ActivationProgress"; + sdbusplus::bus::bus& bus; + std::string path; }; /** @class Activation @@ -173,148 +165,141 @@ class ActivationProgress : public ActivationProgressInherit */ class Activation : public ActivationInherit { - public: - /** @brief Constructs Activation Software Manager - * - * @param[in] bus - The Dbus bus object - * @param[in] path - The Dbus object path - * @param[in] parent - Parent object. - * @param[in] versionId - The software version id - * @param[in] extVersion - The extended version - * @param[in] activationStatus - The status of Activation - * @param[in] assocs - Association objects - */ - Activation(sdbusplus::bus::bus& bus, const std::string& path, - ItemUpdater& parent, - std::string& versionId, - std::string& extVersion, - sdbusplus::xyz::openbmc_project::Software:: - server::Activation::Activations activationStatus, - AssociationList& assocs) : - ActivationInherit(bus, path.c_str(), true), - bus(bus), - path(path), - parent(parent), - versionId(versionId), - systemdSignals( - bus, - sdbusRule::type::signal() + - sdbusRule::member("JobRemoved") + - sdbusRule::path("/org/freedesktop/systemd1") + - sdbusRule::interface( - "org.freedesktop.systemd1.Manager"), - std::bind(std::mem_fn(&Activation::unitStateChange), - this, std::placeholders::_1)) - { - // Enable systemd signals - subscribeToSystemdSignals(); - // Set Properties. - extendedVersion(extVersion); - activation(activationStatus); - associations(assocs); - - // Emit deferred signal. - emit_object_added(); - } - - /** @brief Activation property get function - * - * @returns One of Activation::Activations - */ - 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 - * - * @return Success or exception thrown - */ - 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 - * - * This object needs to capture when it's systemd targets complete - * so it can keep it's state updated - * - **/ - void subscribeToSystemdSignals(); - - /** - * @brief unsubscribe from the systemd signals - * - * Once the activation process has completed successfully, we can - * safely unsubscribe from systemd signals. - * - **/ - void unsubscribeFromSystemdSignals(); - - /** @brief Persistent sdbusplus DBus bus connection */ - sdbusplus::bus::bus& bus; - - /** @brief Persistent DBus object path */ - std::string path; - - /** @brief Parent Object. */ - ItemUpdater& parent; - - /** @brief Version id */ - std::string versionId; - - /** @brief Persistent ActivationBlocksTransition dbus object */ - std::unique_ptr activationBlocksTransition; - - /** @brief Persistent ActivationProgress dbus object */ - std::unique_ptr activationProgress; - - /** @brief Persistent RedundancyPriority dbus object */ - std::unique_ptr redundancyPriority; - - /** @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: - - /** - * @brief Deletes the version from Image Manager and the - * untar image from image upload dir. - */ - void deleteImageManagerObject(); - - /** @brief Member function for clarity & brevity at activation start */ - void startActivation(); - - /** @brief Member function for clarity & brevity at activation end */ - void finishActivation(); + public: + /** @brief Constructs Activation Software Manager + * + * @param[in] bus - The Dbus bus object + * @param[in] path - The Dbus object path + * @param[in] parent - Parent object. + * @param[in] versionId - The software version id + * @param[in] extVersion - The extended version + * @param[in] activationStatus - The status of Activation + * @param[in] assocs - Association objects + */ + Activation(sdbusplus::bus::bus& bus, const std::string& path, + ItemUpdater& parent, std::string& versionId, + std::string& extVersion, + sdbusplus::xyz::openbmc_project::Software::server::Activation:: + Activations activationStatus, + AssociationList& assocs) : + ActivationInherit(bus, path.c_str(), true), + bus(bus), path(path), parent(parent), versionId(versionId), + systemdSignals( + bus, + sdbusRule::type::signal() + sdbusRule::member("JobRemoved") + + sdbusRule::path("/org/freedesktop/systemd1") + + sdbusRule::interface("org.freedesktop.systemd1.Manager"), + std::bind(std::mem_fn(&Activation::unitStateChange), this, + std::placeholders::_1)) + { + // Enable systemd signals + subscribeToSystemdSignals(); + // Set Properties. + extendedVersion(extVersion); + activation(activationStatus); + associations(assocs); + + // Emit deferred signal. + emit_object_added(); + } + + /** @brief Activation property get function + * + * @returns One of Activation::Activations + */ + 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 + * + * @return Success or exception thrown + */ + 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 + * + * This object needs to capture when it's systemd targets complete + * so it can keep it's state updated + * + **/ + void subscribeToSystemdSignals(); + + /** + * @brief unsubscribe from the systemd signals + * + * Once the activation process has completed successfully, we can + * safely unsubscribe from systemd signals. + * + **/ + void unsubscribeFromSystemdSignals(); + + /** @brief Persistent sdbusplus DBus bus connection */ + sdbusplus::bus::bus& bus; + + /** @brief Persistent DBus object path */ + std::string path; + + /** @brief Parent Object. */ + ItemUpdater& parent; + + /** @brief Version id */ + std::string versionId; + + /** @brief Persistent ActivationBlocksTransition dbus object */ + std::unique_ptr activationBlocksTransition; + + /** @brief Persistent ActivationProgress dbus object */ + std::unique_ptr activationProgress; + + /** @brief Persistent RedundancyPriority dbus object */ + std::unique_ptr redundancyPriority; + + /** @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: + /** + * @brief Deletes the version from Image Manager and the + * untar image from image upload dir. + */ + void deleteImageManagerObject(); + + /** @brief Member function for clarity & brevity at activation start */ + void startActivation(); + + /** @brief Member function for clarity & brevity at activation end */ + void finishActivation(); }; } // namespace updater diff --git a/item_updater.cpp b/item_updater.cpp index 7b7995ea2..ad8f26474 100644 --- a/item_updater.cpp +++ b/item_updater.cpp @@ -40,8 +40,8 @@ void ItemUpdater::createActivation(sdbusplus::message::message& m) namespace variant_ns = msg::variant_ns; sdbusplus::message::object_path objPath; - std::map>> interfaces; + std::map>> + interfaces; m.read(objPath, interfaces); std::string path(std::move(objPath)); @@ -59,7 +59,7 @@ void ItemUpdater::createActivation(sdbusplus::message::message& m) { // Only process the Host and System images auto value = SVersion::convertVersionPurposeFromString( - variant_ns::get(property.second)); + variant_ns::get(property.second)); if (value == VersionPurpose::Host || value == VersionPurpose::System) @@ -110,41 +110,29 @@ void ItemUpdater::createActivation(sdbusplus::message::message& m) activationState = server::Activation::Activations::Ready; // Create an association to the host inventory item associations.emplace_back(std::make_tuple( - ACTIVATION_FWD_ASSOCIATION, - ACTIVATION_REV_ASSOCIATION, - HOST_INVENTORY_PATH)); + ACTIVATION_FWD_ASSOCIATION, ACTIVATION_REV_ASSOCIATION, + HOST_INVENTORY_PATH)); } fs::path manifestPath(filePath); manifestPath /= MANIFEST_FILE; - std::string extendedVersion = (Version::getValue(manifestPath.string(), - std::map - {{"extended_version", ""}})).begin()->second; + std::string extendedVersion = + (Version::getValue( + manifestPath.string(), + std::map{{"extended_version", ""}})) + .begin() + ->second; activations.insert(std::make_pair( - versionId, - std::make_unique( - bus, - path, - *this, - versionId, - extendedVersion, - activationState, - associations))); + versionId, std::make_unique( + bus, path, *this, versionId, extendedVersion, + activationState, associations))); auto versionPtr = std::make_unique( - bus, - path, - *this, - versionId, - version, - purpose, - filePath, - std::bind(&ItemUpdater::erase, - this, - std::placeholders::_1)); + bus, path, *this, versionId, version, purpose, filePath, + std::bind(&ItemUpdater::erase, this, std::placeholders::_1)); versionPtr->deleteObject = - std::make_unique(bus, path, *versionPtr); + std::make_unique(bus, path, *versionPtr); versions.insert(std::make_pair(versionId, std::move(versionPtr))); } return; @@ -162,8 +150,8 @@ void ItemUpdater::processPNORImage() static const auto PNOR_RW_PREFIX_LEN = strlen(PNOR_RW_PREFIX); // Check if the PNOR_RO_PREFIX is the prefix of the iter.path - if (0 == iter.path().native().compare(0, PNOR_RO_PREFIX_LEN, - PNOR_RO_PREFIX)) + if (0 == + iter.path().native().compare(0, PNOR_RO_PREFIX_LEN, PNOR_RO_PREFIX)) { // The versionId is extracted from the path // for example /media/pnor-ro-2a1022fe. @@ -176,10 +164,8 @@ void ItemUpdater::processPNORImage() ItemUpdater::erase(id); continue; } - auto keyValues = - Version::getValue(pnorTOC, - {{ "version", "" }, - { "extended_version", "" } }); + auto keyValues = Version::getValue( + pnorTOC, {{"version", ""}, {"extended_version", ""}}); auto& version = keyValues.at("version"); if (version.empty()) { @@ -204,25 +190,18 @@ void ItemUpdater::processPNORImage() { // Create an association to the host inventory item associations.emplace_back(std::make_tuple( - ACTIVATION_FWD_ASSOCIATION, - ACTIVATION_REV_ASSOCIATION, - HOST_INVENTORY_PATH)); + ACTIVATION_FWD_ASSOCIATION, ACTIVATION_REV_ASSOCIATION, + HOST_INVENTORY_PATH)); // Create an active association since this image is active createActiveAssociation(path); } // Create Activation instance for this version. - activations.insert(std::make_pair( - id, - std::make_unique( - bus, - path, - *this, - id, - extendedVersion, - activationState, - associations))); + activations.insert( + std::make_pair(id, std::make_unique( + bus, path, *this, id, extendedVersion, + activationState, associations))); // If Active, create RedundancyPriority instance for this version. if (activationState == server::Activation::Activations::Active) @@ -234,33 +213,20 @@ void ItemUpdater::processPNORImage() entry("VERSIONID=%s", id)); } activations.find(id)->second->redundancyPriority = - std::make_unique( - bus, - path, - *(activations.find(id)->second), - priority); + std::make_unique( + bus, path, *(activations.find(id)->second), priority); } // Create Version instance for this version. auto versionPtr = std::make_unique( - bus, - path, - *this, - id, - version, - purpose, - "", - std::bind(&ItemUpdater::erase, - this, - std::placeholders::_1)); + bus, path, *this, id, version, purpose, "", + std::bind(&ItemUpdater::erase, this, std::placeholders::_1)); versionPtr->deleteObject = - std::make_unique(bus, path, *versionPtr); - versions.insert(std::make_pair( - id, - std::move(versionPtr))); + std::make_unique(bus, path, *versionPtr); + versions.insert(std::make_pair(id, std::move(versionPtr))); } else if (0 == iter.path().native().compare(0, PNOR_RW_PREFIX_LEN, - PNOR_RW_PREFIX)) + PNOR_RW_PREFIX)) { auto id = iter.path().native().substr(PNOR_RW_PREFIX_LEN); auto roDir = PNOR_RO_PREFIX + id; @@ -298,32 +264,24 @@ int ItemUpdater::validateSquashFSImage(const std::string& filePath) void ItemUpdater::removeReadOnlyPartition(std::string versionId) { - auto serviceFile = "obmc-flash-bios-ubiumount-ro@" + versionId + - ".service"; - - // Remove the read-only partitions. - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); - method.append(serviceFile, "replace"); - bus.call_noreply(method); + auto serviceFile = "obmc-flash-bios-ubiumount-ro@" + versionId + ".service"; + + // Remove the read-only partitions. + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); + method.append(serviceFile, "replace"); + bus.call_noreply(method); } void ItemUpdater::removeReadWritePartition(std::string versionId) { - auto serviceFile = "obmc-flash-bios-ubiumount-rw@" + versionId + - ".service"; - - // Remove the read-write partitions. - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); - method.append(serviceFile, "replace"); - bus.call_noreply(method); + auto serviceFile = "obmc-flash-bios-ubiumount-rw@" + versionId + ".service"; + + // Remove the read-write partitions. + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); + method.append(serviceFile, "replace"); + bus.call_noreply(method); } void ItemUpdater::reset() @@ -339,40 +297,34 @@ void ItemUpdater::reset() for (const auto& it : activations) { - auto serviceFile = "obmc-flash-bios-ubiclear@pnor-rw-" + it.first + - ".service"; + auto serviceFile = + "obmc-flash-bios-ubiclear@pnor-rw-" + it.first + ".service"; // Clear the read-write partitions. - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); method.append(serviceFile, "replace"); auto reply = bus.call(method); if (reply.is_method_error()) { log("Failed to clear read-write partitions", - entry("SERVICE_FILE=%s", serviceFile)); + entry("SERVICE_FILE=%s", serviceFile)); elog(); } } static constexpr auto serviceFile = - "obmc-flash-bios-ubiclear@pnor-prsv.service"; + "obmc-flash-bios-ubiclear@pnor-prsv.service"; // Clear the preserved partition. - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); method.append(serviceFile, "replace"); auto reply = bus.call(method); if (reply.is_method_error()) { log("Failed to clear preserved partition", - entry("SERVICE_FILE=%s", serviceFile)); + entry("SERVICE_FILE=%s", serviceFile)); elog(); } @@ -404,11 +356,8 @@ bool ItemUpdater::isVersionFunctional(const std::string& versionId) bool ItemUpdater::isChassisOn() { - auto mapperCall = bus.new_method_call( - MAPPER_BUSNAME, - MAPPER_PATH, - MAPPER_INTERFACE, - "GetObject"); + auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, + MAPPER_INTERFACE, "GetObject"); mapperCall.append(CHASSIS_STATE_PATH, std::vector({CHASSIS_STATE_OBJ})); @@ -429,8 +378,7 @@ bool ItemUpdater::isChassisOn() auto method = bus.new_method_call((mapperResponse.begin()->first).c_str(), CHASSIS_STATE_PATH, - SYSTEMD_PROPERTY_INTERFACE, - "Get"); + SYSTEMD_PROPERTY_INTERFACE, "Get"); method.append(CHASSIS_STATE_OBJ, "CurrentPowerState"); auto response = bus.call(method); if (response.is_method_error()) @@ -449,7 +397,7 @@ bool ItemUpdater::isChassisOn() void ItemUpdater::freePriority(uint8_t value, const std::string& versionId) { - //TODO openbmc/openbmc#1896 Improve the performance of this function + // TODO openbmc/openbmc#1896 Improve the performance of this function for (const auto& intf : activations) { if (intf.second->redundancyPriority) @@ -480,10 +428,12 @@ bool ItemUpdater::isLowestPriority(uint8_t value) void ItemUpdater::erase(std::string entryId) { - if (isVersionFunctional(entryId) && isChassisOn()) { - log(("Error: Version " + entryId + \ - " is currently active and running on the host." \ - " Unable to remove.").c_str()); + if (isVersionFunctional(entryId) && isChassisOn()) + { + log(("Error: Version " + entryId + + " is currently active and running on the host." + " Unable to remove.") + .c_str()); return; } // Remove priority persistence file @@ -497,9 +447,10 @@ void ItemUpdater::erase(std::string entryId) auto it = versions.find(entryId); if (it == versions.end()) { - log(("Error: Failed to find version " + entryId + \ - " in item updater versions map." \ - " Unable to remove.").c_str()); + log(("Error: Failed to find version " + entryId + + " in item updater versions map." + " Unable to remove.") + .c_str()); } else { @@ -510,9 +461,10 @@ void ItemUpdater::erase(std::string entryId) auto ita = activations.find(entryId); if (ita == activations.end()) { - log(("Error: Failed to find version " + entryId + \ - " in item updater activations map." \ - " Unable to remove.").c_str()); + log(("Error: Failed to find version " + entryId + + " in item updater activations map." + " Unable to remove.") + .c_str()); } else { @@ -533,11 +485,8 @@ void ItemUpdater::deleteAll() // Remove any remaining pnor-ro- or pnor-rw- volumes that do not match // the current version. - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); method.append("obmc-flash-bios-cleanup.service", "replace"); bus.call_noreply(method); } @@ -548,12 +497,14 @@ void ItemUpdater::freeSpace() // Versions with the highest priority in front std::priority_queue, std::vector>, - std::less>> versionsPQ; + std::less>> + versionsPQ; std::size_t count = 0; for (const auto& iter : activations) { - if (iter.second.get()->activation() == server::Activation::Activations::Active) + if (iter.second.get()->activation() == + server::Activation::Activations::Active) { count++; // Don't put the functional version on the queue since we can't @@ -563,8 +514,8 @@ void ItemUpdater::freeSpace() continue; } versionsPQ.push(std::make_pair( - iter.second->redundancyPriority.get()->priority(), - iter.second->versionId)); + iter.second->redundancyPriority.get()->priority(), + iter.second->versionId)); } } @@ -580,9 +531,8 @@ void ItemUpdater::freeSpace() void ItemUpdater::createActiveAssociation(const std::string& path) { - assocs.emplace_back(std::make_tuple(ACTIVE_FWD_ASSOCIATION, - ACTIVE_REV_ASSOCIATION, - path)); + assocs.emplace_back( + std::make_tuple(ACTIVE_FWD_ASSOCIATION, ACTIVE_REV_ASSOCIATION, path)); associations(assocs); } @@ -601,8 +551,7 @@ void ItemUpdater::updateFunctionalAssociation(const std::string& path) } } assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION, - FUNCTIONAL_REV_ASSOCIATION, - path)); + FUNCTIONAL_REV_ASSOCIATION, path)); associations(assocs); } @@ -651,11 +600,8 @@ void GardReset::reset() path /= "GUARD"; std::vector mboxdArgs; - auto dbusCall = bus.new_method_call( - MBOXD_INTERFACE, - MBOXD_PATH, - MBOXD_INTERFACE, - "cmd"); + auto dbusCall = bus.new_method_call(MBOXD_INTERFACE, MBOXD_PATH, + MBOXD_INTERFACE, "cmd"); // Suspend mboxd - no args required. dbusCall.append(static_cast(3), mboxdArgs); @@ -672,11 +618,8 @@ void GardReset::reset() fs::remove(path); } - dbusCall = bus.new_method_call( - MBOXD_INTERFACE, - MBOXD_PATH, - MBOXD_INTERFACE, - "cmd"); + dbusCall = bus.new_method_call(MBOXD_INTERFACE, MBOXD_PATH, MBOXD_INTERFACE, + "cmd"); // Resume mboxd with arg 1, indicating that the flash is modified. mboxdArgs.push_back(1); diff --git a/item_updater.hpp b/item_updater.hpp index 7b37e4d4a..90441c4fe 100755 --- a/item_updater.hpp +++ b/item_updater.hpp @@ -16,17 +16,17 @@ namespace updater { using ItemUpdaterInherit = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Common::server::FactoryReset, - sdbusplus::org::openbmc::server::Associations, - sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>; + sdbusplus::xyz::openbmc_project::Common::server::FactoryReset, + sdbusplus::org::openbmc::server::Associations, + sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>; using GardResetInherit = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Common::server::FactoryReset>; + sdbusplus::xyz::openbmc_project::Common::server::FactoryReset>; using ObjectEnable = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Object::server::Enable>; + sdbusplus::xyz::openbmc_project::Object::server::Enable>; namespace MatchRules = sdbusplus::bus::match::rules; using AssociationList = - std::vector>; + std::vector>; constexpr auto GARD_PATH = "/org/open_power/control/gard"; constexpr static auto volatilePath = "/org/open_power/control/volatile"; @@ -38,39 +38,35 @@ constexpr static auto volatilePath = "/org/open_power/control/volatile"; */ class GardReset : public GardResetInherit { - public: - /** @brief Constructs GardReset. - * - * @param[in] bus - The Dbus bus object - * @param[in] path - The Dbus object path - */ - GardReset(sdbusplus::bus::bus& bus, - const std::string& path) : - GardResetInherit(bus, path.c_str(), true), - bus(bus), - path(path) - { - std::vector interfaces({interface}); - bus.emit_interfaces_added(path.c_str(), interfaces); - } - - ~GardReset() - { - std::vector interfaces({interface}); - bus.emit_interfaces_removed(path.c_str(), interfaces); - } - - private: - // TODO Remove once openbmc/openbmc#1975 is resolved - static constexpr auto interface = - "xyz.openbmc_project.Common.FactoryReset"; - sdbusplus::bus::bus& bus; - std::string path; - - /** - * @brief GARD factory reset - clears the PNOR GARD partition. - */ - void reset() override; + public: + /** @brief Constructs GardReset. + * + * @param[in] bus - The Dbus bus object + * @param[in] path - The Dbus object path + */ + GardReset(sdbusplus::bus::bus& bus, const std::string& path) : + GardResetInherit(bus, path.c_str(), true), bus(bus), path(path) + { + std::vector interfaces({interface}); + bus.emit_interfaces_added(path.c_str(), interfaces); + } + + ~GardReset() + { + std::vector interfaces({interface}); + bus.emit_interfaces_removed(path.c_str(), interfaces); + } + + private: + // TODO Remove once openbmc/openbmc#1975 is resolved + static constexpr auto interface = "xyz.openbmc_project.Common.FactoryReset"; + sdbusplus::bus::bus& bus; + std::string path; + + /** + * @brief GARD factory reset - clears the PNOR GARD partition. + */ + void reset() override; }; /** @class ItemUpdater @@ -78,180 +74,176 @@ class GardReset : public GardResetInherit */ class ItemUpdater : public ItemUpdaterInherit { - public: - /** @brief Constructs ItemUpdater - * - * @param[in] bus - The D-Bus bus object - * @param[in] path - The D-Bus path - */ - ItemUpdater(sdbusplus::bus::bus& bus, const std::string& path) : - ItemUpdaterInherit(bus, path.c_str()), - bus(bus), - versionMatch( - bus, - MatchRules::interfacesAdded() + - MatchRules::path("/xyz/openbmc_project/software"), - std::bind( - std::mem_fn(&ItemUpdater::createActivation), - this, - std::placeholders::_1)) - { - processPNORImage(); - gardReset = std::make_unique(bus, GARD_PATH); - volatileEnable = std::make_unique(bus, volatilePath); - - // Emit deferred signal. - emit_object_added(); - } - - /** @brief Sets the given priority free by incrementing - * any existing priority with the same value by 1 - * - * @param[in] value - The priority that needs to be set free. - * @param[in] versionId - The Id of the version for which we - * are trying to free up the priority. - * @return None - */ - void freePriority(uint8_t value, const std::string& versionId); - - /** @brief Determine is the given priority is the lowest - * - * @param[in] value - The priority that needs to be checked. - * - * @return boolean corresponding to whether the given - * priority is lowest. - */ - bool isLowestPriority(uint8_t value); - - /** - * @brief Create and populate the active PNOR Version. - */ - void processPNORImage(); - - /** @brief Deletes version - * - * @param[in] entryId - Id of the version to delete - * - * @return None - */ - void erase(std::string entryId); - - /** - * @brief Erases any non-active pnor versions. - */ - void deleteAll(); - - /** @brief Brings the total number of active PNOR versions to - * ACTIVE_PNOR_MAX_ALLOWED -1. This function is intended to be - * run before activating a new PNOR version. If this function - * needs to delete any PNOR version(s) it will delete the - * version(s) with the highest priority, skipping the - * functional PNOR version. - */ - void freeSpace(); - - /** @brief Determine the software version id - * from the symlink target (e.g. /media/ro-2a1022fe). - * - * @param[in] symlinkPath - The path of the symlink. - * @param[out] id - The version id as a string. - */ - static std::string determineId(const std::string& symlinkPath); - - /** @brief Creates an active association to the - * newly active software image - * - * @param[in] path - The path to create the association to. - */ - void createActiveAssociation(const std::string& path); - - /** @brief Updates the functional association to the - * new "running" PNOR image - * - * @param[in] path - The path to update the association to. - */ - void updateFunctionalAssociation(const std::string& path); - - /** @brief Removes an active association to the software image - * - * @param[in] path - The path to remove the association from. - */ - void removeActiveAssociation(const std::string& path); - - /** @brief Persistent GardReset dbus object */ - std::unique_ptr 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); - - /** @brief Persistent ObjectEnable D-Bus object */ - std::unique_ptr volatileEnable; - - private: - /** @brief Callback function for Software.Version match. - * @details Creates an Activation D-Bus object. - * - * @param[in] msg - Data associated with subscribed signal - */ - void createActivation(sdbusplus::message::message& msg); - - /** - * @brief Validates the presence of SquashFS image in the image dir. - * - * @param[in] filePath - The path to the SquashFS image. - * @param[out] result - 0 --> if validation was successful - * - -1--> Otherwise - */ - static int validateSquashFSImage(const std::string& filePath); - - /** @brief Persistent sdbusplus D-Bus bus connection. */ - sdbusplus::bus::bus& bus; - - /** @brief Persistent map of Activation D-Bus objects and their - * version id */ - std::map> activations; - - /** @brief Persistent map of Version D-Bus objects and their - * version id */ - std::map> versions; - - /** @brief sdbusplus signal match for Software.Version */ - sdbusplus::bus::match_t versionMatch; - - /** @brief This entry's associations */ - AssociationList assocs = {}; - - /** @brief Clears read only PNOR partition for - * given Activation D-Bus object - * - * @param[in] versionId - The id of the ro partition to remove. - */ - void removeReadOnlyPartition(std::string versionId); - - /** @brief Clears read write PNOR partition for - * given Activation D-Bus object - * - * @param[in] versionId - The id of the rw partition to remove. - */ - void removeReadWritePartition(std::string versionId); - - /** @brief Clears preserved PNOR partition */ - void removePreservedPartition(); - - /** @brief Host factory reset - clears PNOR partitions for each - * Activation D-Bus object */ - void reset() override; - - /** @brief Check whether the host is running - * - * @return - Returns true if the Chassis is powered on. - */ - bool isChassisOn(); + public: + /** @brief Constructs ItemUpdater + * + * @param[in] bus - The D-Bus bus object + * @param[in] path - The D-Bus path + */ + ItemUpdater(sdbusplus::bus::bus& bus, const std::string& path) : + ItemUpdaterInherit(bus, path.c_str()), bus(bus), + versionMatch(bus, + MatchRules::interfacesAdded() + + MatchRules::path("/xyz/openbmc_project/software"), + std::bind(std::mem_fn(&ItemUpdater::createActivation), + this, std::placeholders::_1)) + { + processPNORImage(); + gardReset = std::make_unique(bus, GARD_PATH); + volatileEnable = std::make_unique(bus, volatilePath); + + // Emit deferred signal. + emit_object_added(); + } + + /** @brief Sets the given priority free by incrementing + * any existing priority with the same value by 1 + * + * @param[in] value - The priority that needs to be set free. + * @param[in] versionId - The Id of the version for which we + * are trying to free up the priority. + * @return None + */ + void freePriority(uint8_t value, const std::string& versionId); + + /** @brief Determine is the given priority is the lowest + * + * @param[in] value - The priority that needs to be checked. + * + * @return boolean corresponding to whether the given + * priority is lowest. + */ + bool isLowestPriority(uint8_t value); + + /** + * @brief Create and populate the active PNOR Version. + */ + void processPNORImage(); + + /** @brief Deletes version + * + * @param[in] entryId - Id of the version to delete + * + * @return None + */ + void erase(std::string entryId); + + /** + * @brief Erases any non-active pnor versions. + */ + void deleteAll(); + + /** @brief Brings the total number of active PNOR versions to + * ACTIVE_PNOR_MAX_ALLOWED -1. This function is intended to be + * run before activating a new PNOR version. If this function + * needs to delete any PNOR version(s) it will delete the + * version(s) with the highest priority, skipping the + * functional PNOR version. + */ + void freeSpace(); + + /** @brief Determine the software version id + * from the symlink target (e.g. /media/ro-2a1022fe). + * + * @param[in] symlinkPath - The path of the symlink. + * @param[out] id - The version id as a string. + */ + static std::string determineId(const std::string& symlinkPath); + + /** @brief Creates an active association to the + * newly active software image + * + * @param[in] path - The path to create the association to. + */ + void createActiveAssociation(const std::string& path); + + /** @brief Updates the functional association to the + * new "running" PNOR image + * + * @param[in] path - The path to update the association to. + */ + void updateFunctionalAssociation(const std::string& path); + + /** @brief Removes an active association to the software image + * + * @param[in] path - The path to remove the association from. + */ + void removeActiveAssociation(const std::string& path); + + /** @brief Persistent GardReset dbus object */ + std::unique_ptr 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); + + /** @brief Persistent ObjectEnable D-Bus object */ + std::unique_ptr volatileEnable; + + private: + /** @brief Callback function for Software.Version match. + * @details Creates an Activation D-Bus object. + * + * @param[in] msg - Data associated with subscribed signal + */ + void createActivation(sdbusplus::message::message& msg); + + /** + * @brief Validates the presence of SquashFS image in the image dir. + * + * @param[in] filePath - The path to the SquashFS image. + * @param[out] result - 0 --> if validation was successful + * - -1--> Otherwise + */ + static int validateSquashFSImage(const std::string& filePath); + + /** @brief Persistent sdbusplus D-Bus bus connection. */ + sdbusplus::bus::bus& bus; + + /** @brief Persistent map of Activation D-Bus objects and their + * version id */ + std::map> activations; + + /** @brief Persistent map of Version D-Bus objects and their + * version id */ + std::map> versions; + + /** @brief sdbusplus signal match for Software.Version */ + sdbusplus::bus::match_t versionMatch; + + /** @brief This entry's associations */ + AssociationList assocs = {}; + + /** @brief Clears read only PNOR partition for + * given Activation D-Bus object + * + * @param[in] versionId - The id of the ro partition to remove. + */ + void removeReadOnlyPartition(std::string versionId); + + /** @brief Clears read write PNOR partition for + * given Activation D-Bus object + * + * @param[in] versionId - The id of the rw partition to remove. + */ + void removeReadWritePartition(std::string versionId); + + /** @brief Clears preserved PNOR partition */ + void removePreservedPartition(); + + /** @brief Host factory reset - clears PNOR partitions for each + * Activation D-Bus object */ + void reset() override; + + /** @brief Check whether the host is running + * + * @return - Returns true if the Chassis is powered on. + */ + bool isChassisOn(); }; } // namespace updater diff --git a/item_updater_main.cpp b/item_updater_main.cpp index 0933505ae..db7cae456 100755 --- a/item_updater_main.cpp +++ b/item_updater_main.cpp @@ -30,11 +30,9 @@ int main(int argc, char* argv[]) try { openpower::software::updater::Watch watch( - loop, - std::bind(std::mem_fn( - &ItemUpdater::updateFunctionalAssociation), - &updater, - std::placeholders::_1)); + loop, + std::bind(std::mem_fn(&ItemUpdater::updateFunctionalAssociation), + &updater, std::placeholders::_1)); bus.attach_event(loop, SD_EVENT_PRIORITY_NORMAL); auto rc = sd_event_loop(loop); if (rc < 0) diff --git a/serialize.cpp b/serialize.cpp index 595a970b3..d96bf0b8e 100644 --- a/serialize.cpp +++ b/serialize.cpp @@ -40,12 +40,9 @@ void storeToFile(std::string versionId, uint8_t priority) // lastly, store the priority as an environment variable pnor-[versionId] std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + - "\\x3d" + std::to_string(priority) + ".service"; - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); + "\\x3d" + std::to_string(priority) + ".service"; + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); method.append(serviceFile, "replace"); bus.call_noreply(method); } @@ -107,7 +104,9 @@ bool restoreFromFile(std::string versionId, uint8_t& priority) } } } - catch (const std::exception& e){} + catch (const std::exception& e) + { + } return false; } @@ -117,13 +116,10 @@ void removeFile(std::string versionId) auto bus = sdbusplus::bus::new_default(); // Clear the environment variable pnor-[versionId]. - std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + - ".service"; - auto method = bus.new_method_call( - SYSTEMD_BUSNAME, - SYSTEMD_PATH, - SYSTEMD_INTERFACE, - "StartUnit"); + std::string serviceFile = + "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + ".service"; + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); method.append(serviceFile, "replace"); bus.call_noreply(method); diff --git a/test/utest.cpp b/test/utest.cpp index 7ce738eff..e27655a7d 100644 --- a/test/utest.cpp +++ b/test/utest.cpp @@ -14,10 +14,10 @@ TEST(VersionTest, TestGetId) SHA512_Init(&ctx); SHA512_Update(&ctx, version, strlen(version)); SHA512_Final(digest, &ctx); - char mdString[SHA512_DIGEST_LENGTH*2+1]; + char mdString[SHA512_DIGEST_LENGTH * 2 + 1]; for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) { - snprintf(&mdString[i*2], 3, "%02x", (unsigned int)digest[i]); + snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]); } std::string hexId = std::string(mdString); hexId = hexId.substr(0, 8); diff --git a/version.cpp b/version.cpp index c8fe7cf95..23f90f40c 100644 --- a/version.cpp +++ b/version.cpp @@ -36,10 +36,10 @@ std::string Version::getId(const std::string& version) SHA512_Init(&ctx); SHA512_Update(&ctx, version.c_str(), strlen(version.c_str())); SHA512_Final(digest, &ctx); - char mdString[SHA512_DIGEST_LENGTH*2+1]; + char mdString[SHA512_DIGEST_LENGTH * 2 + 1]; for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) { - snprintf(&mdString[i*2], 3, "%02x", (unsigned int)digest[i]); + snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]); } // Only need 8 hex digits. @@ -47,8 +47,9 @@ std::string Version::getId(const std::string& version) return (hexId.substr(0, 8)); } -std::map Version::getValue( - const std::string& filePath, std::map keys) +std::map + Version::getValue(const std::string& filePath, + std::map keys) { if (filePath.empty()) { @@ -59,8 +60,7 @@ std::map Version::getValue( std::ifstream efile; std::string line; - efile.exceptions(std::ifstream::failbit | - std::ifstream::badbit | + efile.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit); try @@ -68,7 +68,7 @@ std::map Version::getValue( efile.open(filePath); while (getline(efile, line)) { - for(auto& key : keys) + for (auto& key : keys) { auto value = key.first + "="; auto keySize = value.length(); diff --git a/version.hpp b/version.hpp index 13b42ea37..8a07ae0c3 100644 --- a/version.hpp +++ b/version.hpp @@ -18,10 +18,10 @@ class ItemUpdater; typedef std::function eraseFunc; using VersionInherit = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Software::server::Version, - sdbusplus::xyz::openbmc_project::Common::server::FilePath>; + sdbusplus::xyz::openbmc_project::Software::server::Version, + sdbusplus::xyz::openbmc_project::Common::server::FilePath>; using DeleteInherit = sdbusplus::server::object::object< - sdbusplus::xyz::openbmc_project::Object::server::Delete>; + sdbusplus::xyz::openbmc_project::Object::server::Delete>; namespace sdbusRule = sdbusplus::bus::match::rules; @@ -32,51 +32,45 @@ class Version; * @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, - Version& parent) : - DeleteInherit(bus, path.c_str(), true), - parent(parent), - bus(bus), - path(path) - { - std::vector interfaces({interface}); - bus.emit_interfaces_added(path.c_str(), interfaces); - } - - ~Delete() - { - std::vector interfaces({interface}); - bus.emit_interfaces_removed(path.c_str(), interfaces); - } - - /** - * @brief Delete the D-Bus object. - * Overrides the default delete function by calling - * Version class erase Method. - **/ - void delete_() override; - - private: - - /** @brief Parent Object. */ - Version& parent; - - // TODO Remove once openbmc/openbmc#1975 is resolved - static constexpr auto interface = - "xyz.openbmc_project.Object.Delete"; - sdbusplus::bus::bus& bus; - std::string path; + 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, Version& parent) : + DeleteInherit(bus, path.c_str(), true), parent(parent), bus(bus), + path(path) + { + std::vector interfaces({interface}); + bus.emit_interfaces_added(path.c_str(), interfaces); + } + + ~Delete() + { + std::vector interfaces({interface}); + bus.emit_interfaces_removed(path.c_str(), interfaces); + } + + /** + * @brief Delete the D-Bus object. + * Overrides the default delete function by calling + * Version class erase Method. + **/ + void delete_() override; + + private: + /** @brief Parent Object. */ + Version& parent; + + // TODO Remove once openbmc/openbmc#1975 is resolved + static constexpr auto interface = "xyz.openbmc_project.Object.Delete"; + sdbusplus::bus::bus& bus; + std::string path; }; /** @class Version @@ -86,115 +80,106 @@ class Delete : public DeleteInherit */ class Version : public VersionInherit { - public: - /** @brief Constructs Version Software Manager. - * - * @param[in] bus - The D-Bus bus object - * @param[in] objPath - The D-Bus object path - * @param[in] parent - Parent object. - * @param[in] versionId - The version Id - * @param[in] versionString - The version string - * @param[in] versionPurpose - The version purpose - * @param[in] filePath - The image filesystem path - * @param[in] callback - The eraseFunc callback - */ - Version(sdbusplus::bus::bus& bus, - const std::string& objPath, - ItemUpdater& parent, - const std::string& versionId, - const std::string& versionString, - VersionPurpose versionPurpose, - const std::string& filePath, eraseFunc callback) : - VersionInherit(bus, (objPath).c_str(), true), - bus(bus), - objPath(objPath), - parent(parent), - versionId(versionId), - versionStr(versionString), - 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( - &Version::updateDeleteInterface), this, - std::placeholders::_1)) - { - // Bind erase method - eraseCallback = callback; - // Set properties. - purpose(versionPurpose); - version(versionString); - path(filePath); - - // Emit deferred signal. - emit_object_added(); - } - - /** - * @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 Read the manifest file to get the value of the key. - * - * @param[in] filePath - The path to the file which contains the value - * of keys. - * @param[in] keys - A map of keys with empty values. - * - * @return The map of keys with filled values. - **/ - static std::map getValue( - const std::string& filePath, - std::map keys); - - /** - * @brief Calculate the version id from the version string. - * - * @details The version id is a unique 8 hexadecimal digit id - * calculated from the version string. - * - * @param[in] version - The image version string (e.g. v1.99.10-19). - * - * @return The id. - */ - static std::string getId(const std::string& version); - - /** @brief Persistent Delete D-Bus object */ - std::unique_ptr deleteObject; - - /** @brief The parent's erase callback. */ - eraseFunc eraseCallback; - - private: - /** @brief Persistent sdbusplus DBus bus connection */ - sdbusplus::bus::bus& bus; - - /** @brief Persistent DBus object path */ - std::string objPath; - - /** @brief Parent Object. */ - ItemUpdater& parent; - - /** @brief This Version's version Id */ - const std::string versionId; - - /** @brief This Version's version string */ - const std::string versionStr; - - /** @brief Used to subscribe to chassis power state changes **/ - sdbusplus::bus::match_t chassisStateSignals; - + public: + /** @brief Constructs Version Software Manager. + * + * @param[in] bus - The D-Bus bus object + * @param[in] objPath - The D-Bus object path + * @param[in] parent - Parent object. + * @param[in] versionId - The version Id + * @param[in] versionString - The version string + * @param[in] versionPurpose - The version purpose + * @param[in] filePath - The image filesystem path + * @param[in] callback - The eraseFunc callback + */ + Version(sdbusplus::bus::bus& bus, const std::string& objPath, + ItemUpdater& parent, const std::string& versionId, + const std::string& versionString, VersionPurpose versionPurpose, + const std::string& filePath, eraseFunc callback) : + VersionInherit(bus, (objPath).c_str(), true), + bus(bus), objPath(objPath), parent(parent), versionId(versionId), + versionStr(versionString), + 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(&Version::updateDeleteInterface), this, + std::placeholders::_1)) + { + // Bind erase method + eraseCallback = callback; + // Set properties. + purpose(versionPurpose); + version(versionString); + path(filePath); + + // Emit deferred signal. + emit_object_added(); + } + + /** + * @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 Read the manifest file to get the value of the key. + * + * @param[in] filePath - The path to the file which contains the value + * of keys. + * @param[in] keys - A map of keys with empty values. + * + * @return The map of keys with filled values. + **/ + static std::map + getValue(const std::string& filePath, + std::map keys); + + /** + * @brief Calculate the version id from the version string. + * + * @details The version id is a unique 8 hexadecimal digit id + * calculated from the version string. + * + * @param[in] version - The image version string (e.g. v1.99.10-19). + * + * @return The id. + */ + static std::string getId(const std::string& version); + + /** @brief Persistent Delete D-Bus object */ + std::unique_ptr deleteObject; + + /** @brief The parent's erase callback. */ + eraseFunc eraseCallback; + + private: + /** @brief Persistent sdbusplus DBus bus connection */ + sdbusplus::bus::bus& bus; + + /** @brief Persistent DBus object path */ + std::string objPath; + + /** @brief Parent Object. */ + ItemUpdater& parent; + + /** @brief This Version's version Id */ + const std::string versionId; + + /** @brief This Version's version string */ + const std::string versionStr; + + /** @brief Used to subscribe to chassis power state changes **/ + sdbusplus::bus::match_t chassisStateSignals; }; } // namespace updater diff --git a/watch.cpp b/watch.cpp index e076450d5..9402057d6 100644 --- a/watch.cpp +++ b/watch.cpp @@ -23,8 +23,8 @@ namespace fs = std::experimental::filesystem; Watch::Watch(sd_event* loop, std::function functionalCallback) : - functionalCallback(functionalCallback), - fd(inotifyInit()) + functionalCallback(functionalCallback), + fd(inotifyInit()) { // Create PNOR_ACTIVE_PATH if doesn't exist. @@ -37,25 +37,18 @@ Watch::Watch(sd_event* loop, if (-1 == wd) { auto error = errno; - throw std::system_error(error, - std::generic_category(), + throw std::system_error(error, std::generic_category(), "Error occurred during the inotify_init1"); } decltype(eventSource.get()) sourcePtr = nullptr; - auto rc = sd_event_add_io(loop, - &sourcePtr, - fd(), - EPOLLIN, - callback, - this); + auto rc = sd_event_add_io(loop, &sourcePtr, fd(), EPOLLIN, callback, this); eventSource.reset(sourcePtr); if (0 > rc) { - throw std::system_error(-rc, - std::generic_category(), + throw std::system_error(-rc, std::generic_category(), "Error occurred during the inotify_init1"); } } @@ -68,9 +61,7 @@ Watch::~Watch() } } -int Watch::callback(sd_event_source* s, - int fd, - uint32_t revents, +int Watch::callback(sd_event_source* s, int fd, uint32_t revents, void* userdata) { if (!(revents & EPOLLIN)) @@ -84,8 +75,7 @@ int Watch::callback(sd_event_source* s, if (0 > bytes) { auto error = errno; - throw std::system_error(error, - std::generic_category(), + throw std::system_error(error, std::generic_category(), "failed to read inotify event"); } @@ -117,8 +107,7 @@ int Watch::inotifyInit() if (-1 == fd) { auto error = errno; - throw std::system_error(error, - std::generic_category(), + throw std::system_error(error, std::generic_category(), "Error occurred during the inotify_init1"); } diff --git a/watch.hpp b/watch.hpp index bdea792c0..0ce5d0ed3 100644 --- a/watch.hpp +++ b/watch.hpp @@ -26,35 +26,37 @@ using EventSourcePtr = std::unique_ptr; */ struct CustomFd { - public: - CustomFd() = delete; - CustomFd(const CustomFd&) = delete; - CustomFd& operator=(const CustomFd&) = delete; - CustomFd(CustomFd&&) = delete; - CustomFd& operator=(CustomFd&&) = delete; - - /** @brief Saves File descriptor and uses it to do file operation - * - * @param[in] fd - File descriptor - */ - CustomFd(int fd) : fd(fd) {} - - ~CustomFd() - { - if (fd >= 0) - { - close(fd); - } - } + public: + CustomFd() = delete; + CustomFd(const CustomFd&) = delete; + CustomFd& operator=(const CustomFd&) = delete; + CustomFd(CustomFd&&) = delete; + CustomFd& operator=(CustomFd&&) = delete; + + /** @brief Saves File descriptor and uses it to do file operation + * + * @param[in] fd - File descriptor + */ + CustomFd(int fd) : fd(fd) + { + } - int operator()() const + ~CustomFd() + { + if (fd >= 0) { - return fd; + close(fd); } + } + + int operator()() const + { + return fd; + } - private: - /** @brief File descriptor */ - int fd = -1; + private: + /** @brief File descriptor */ + int fd = -1; }; /** @class Watch @@ -68,54 +70,51 @@ struct CustomFd */ class Watch { - public: - /** @brief ctor - hook inotify watch with sd-event - * - * @param[in] loop - sd-event object - * @param[in] functionalCallback - The callback function for updating - * the functional associations. - */ - Watch(sd_event* loop, - std::function functionalCallback); - - Watch(const Watch&) = delete; - Watch& operator=(const Watch&) = delete; - Watch(Watch&&) = delete; - Watch& operator=(Watch&&) = delete; - - /** @brief dtor - remove inotify watch - */ - ~Watch(); - - private: - /** @brief sd-event callback - * - * @param[in] s - event source, floating (unused) in our case - * @param[in] fd - inotify fd - * @param[in] revents - events that matched for fd - * @param[in] userdata - pointer to Watch object - * @returns 0 on success, -1 on fail - */ - static int callback(sd_event_source* s, - int fd, - uint32_t revents, - void* userdata); - - /** initialize an inotify instance and returns file descriptor */ - int inotifyInit(); - - /** @brief PNOR symlink file watch descriptor */ - int wd = -1; - - /** @brief event source */ - EventSourcePtr eventSource; - - /** @brief The callback function for updating the - functional associations. */ - std::function functionalCallback; - - /** @brief inotify file descriptor */ - CustomFd fd; + public: + /** @brief ctor - hook inotify watch with sd-event + * + * @param[in] loop - sd-event object + * @param[in] functionalCallback - The callback function for updating + * the functional associations. + */ + Watch(sd_event* loop, std::function functionalCallback); + + Watch(const Watch&) = delete; + Watch& operator=(const Watch&) = delete; + Watch(Watch&&) = delete; + Watch& operator=(Watch&&) = delete; + + /** @brief dtor - remove inotify watch + */ + ~Watch(); + + private: + /** @brief sd-event callback + * + * @param[in] s - event source, floating (unused) in our case + * @param[in] fd - inotify fd + * @param[in] revents - events that matched for fd + * @param[in] userdata - pointer to Watch object + * @returns 0 on success, -1 on fail + */ + static int callback(sd_event_source* s, int fd, uint32_t revents, + void* userdata); + + /** initialize an inotify instance and returns file descriptor */ + int inotifyInit(); + + /** @brief PNOR symlink file watch descriptor */ + int wd = -1; + + /** @brief event source */ + EventSourcePtr eventSource; + + /** @brief The callback function for updating the + functional associations. */ + std::function functionalCallback; + + /** @brief inotify file descriptor */ + CustomFd fd; }; } // namespace updater -- cgit v1.2.1