| #include "activation_static.hpp" |
| |
| #include "item_updater.hpp" |
| |
| #include <phosphor-logging/log.hpp> |
| |
| 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<level::ERR>("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<ActivationProgress>(bus, path); |
| } |
| |
| if (!activationBlocksTransition) |
| { |
| activationBlocksTransition = |
| std::make_unique<ActivationBlocksTransition>(bus, path); |
| } |
| |
| // TODO: check why the signal is still received without calling this |
| // function? |
| subscribeToSystemdSignals(); |
| |
| log<level::INFO>("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<RedundancyPriority>(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 |