#include "activation_static.hpp" #include "item_updater.hpp" #include namespace openpower { namespace software { namespace updater { namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server; using namespace phosphor::logging; auto ActivationStatic::activation(Activations value) -> Activations { auto ret = value; if (value != softwareServer::Activation::Activations::Active) { redundancyPriority.reset(nullptr); } if (value == softwareServer::Activation::Activations::Activating) { fs::path imagePath(IMG_DIR); imagePath /= versionId; for (const auto& entry : fs::directory_iterator(imagePath)) { if (entry.path().extension() == ".pnor") { pnorFilePath = entry; break; } } if (pnorFilePath.empty()) { log("Unable to find pnor file", entry("DIR=%s", imagePath.c_str())); ret = softwareServer::Activation::Activations::Failed; goto out; } #ifdef WANT_SIGNATURE_VERIFY // Validate the signed image. if (!validateSignature(pnorFilePath.filename())) { // Cleanup activationBlocksTransition.reset(nullptr); activationProgress.reset(nullptr); ret = softwareServer::Activation::Activations::Failed; goto out; } #endif if (parent.freeSpace()) { startActivation(); } else { ret = softwareServer::Activation::Activations::Failed; } } else { activationBlocksTransition.reset(nullptr); activationProgress.reset(nullptr); } out: return softwareServer::Activation::activation(ret); } void ActivationStatic::startActivation() { if (!activationProgress) { activationProgress = std::make_unique(bus, path); } if (!activationBlocksTransition) { activationBlocksTransition = std::make_unique(bus, path); } // TODO: check why the signal is still received without calling this // function? subscribeToSystemdSignals(); log("Start programming...", entry("PNOR=%s", pnorFilePath.c_str())); std::string pnorFileEscaped = pnorFilePath.string(); // Escape all '/' to '-' std::replace(pnorFileEscaped.begin(), pnorFileEscaped.end(), '/', '-'); constexpr auto updatePNORService = "openpower-pnor-update@"; pnorUpdateUnit = std::string(updatePNORService) + pnorFileEscaped + ".service"; auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, SYSTEMD_INTERFACE, "StartUnit"); method.append(pnorUpdateUnit, "replace"); bus.call_noreply(method); activationProgress->progress(10); } void ActivationStatic::unitStateChange(sdbusplus::message_t& 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); if (newStateUnit == pnorUpdateUnit) { if (newStateResult == "done") { finishActivation(); } if (newStateResult == "failed" || newStateResult == "dependency") { Activation::activation( softwareServer::Activation::Activations::Failed); } } } void ActivationStatic::finishActivation() { activationProgress->progress(90); // Set Redundancy Priority before setting to Active if (!redundancyPriority) { redundancyPriority = std::make_unique(bus, path, *this, 0); } activationProgress->progress(100); activationBlocksTransition.reset(); activationProgress.reset(); unsubscribeFromSystemdSignals(); // Remove version object from image manager deleteImageManagerObject(); // Create active association parent.createActiveAssociation(path); // Create updateable association as this // can be re-programmed. parent.createUpdateableAssociation(path); // Create functional association parent.updateFunctionalAssociation(versionId); Activation::activation(Activation::Activations::Active); } } // namespace updater } // namespace software } // namespace openpower