1 #include "activation_static.hpp" 2 3 #include "item_updater.hpp" 4 5 #include <phosphor-logging/log.hpp> 6 7 namespace openpower 8 { 9 namespace software 10 { 11 namespace updater 12 { 13 namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server; 14 15 using namespace phosphor::logging; 16 17 auto ActivationStatic::activation(Activations value) -> Activations 18 { 19 auto ret = value; 20 if (value != softwareServer::Activation::Activations::Active) 21 { 22 redundancyPriority.reset(nullptr); 23 } 24 25 if (value == softwareServer::Activation::Activations::Activating) 26 { 27 fs::path imagePath(IMG_DIR); 28 imagePath /= versionId; 29 30 for (const auto& entry : fs::directory_iterator(imagePath)) 31 { 32 if (entry.path().extension() == ".pnor") 33 { 34 pnorFilePath = entry; 35 break; 36 } 37 } 38 if (pnorFilePath.empty()) 39 { 40 log<level::ERR>("Unable to find pnor file", 41 entry("DIR=%s", imagePath.c_str())); 42 ret = softwareServer::Activation::Activations::Failed; 43 goto out; 44 } 45 #ifdef WANT_SIGNATURE_VERIFY 46 // Validate the signed image. 47 if (!validateSignature(pnorFilePath.filename())) 48 { 49 // Cleanup 50 activationBlocksTransition.reset(nullptr); 51 activationProgress.reset(nullptr); 52 53 ret = softwareServer::Activation::Activations::Failed; 54 goto out; 55 } 56 #endif 57 if (parent.freeSpace()) 58 { 59 startActivation(); 60 } 61 else 62 { 63 ret = softwareServer::Activation::Activations::Failed; 64 } 65 } 66 else 67 { 68 activationBlocksTransition.reset(nullptr); 69 activationProgress.reset(nullptr); 70 } 71 72 out: 73 return softwareServer::Activation::activation(ret); 74 } 75 76 void ActivationStatic::startActivation() 77 { 78 if (!activationProgress) 79 { 80 activationProgress = std::make_unique<ActivationProgress>(bus, path); 81 } 82 83 if (!activationBlocksTransition) 84 { 85 activationBlocksTransition = 86 std::make_unique<ActivationBlocksTransition>(bus, path); 87 } 88 89 // TODO: check why the signal is still received without calling this 90 // function? 91 subscribeToSystemdSignals(); 92 93 log<level::INFO>("Start programming...", 94 entry("PNOR=%s", pnorFilePath.c_str())); 95 96 std::string pnorFileEscaped = pnorFilePath.string(); 97 // Escape all '/' to '-' 98 std::replace(pnorFileEscaped.begin(), pnorFileEscaped.end(), '/', '-'); 99 100 constexpr auto updatePNORService = "openpower-pnor-update@"; 101 pnorUpdateUnit = std::string(updatePNORService) + pnorFileEscaped + 102 ".service"; 103 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, 104 SYSTEMD_INTERFACE, "StartUnit"); 105 method.append(pnorUpdateUnit, "replace"); 106 bus.call_noreply(method); 107 108 activationProgress->progress(10); 109 } 110 111 void ActivationStatic::unitStateChange(sdbusplus::message_t& msg) 112 { 113 uint32_t newStateID{}; 114 sdbusplus::message::object_path newStateObjPath; 115 std::string newStateUnit{}; 116 std::string newStateResult{}; 117 118 // Read the msg and populate each variable 119 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); 120 121 if (newStateUnit == pnorUpdateUnit) 122 { 123 if (newStateResult == "done") 124 { 125 finishActivation(); 126 } 127 if (newStateResult == "failed" || newStateResult == "dependency") 128 { 129 Activation::activation( 130 softwareServer::Activation::Activations::Failed); 131 } 132 } 133 } 134 135 void ActivationStatic::finishActivation() 136 { 137 activationProgress->progress(90); 138 139 // Set Redundancy Priority before setting to Active 140 if (!redundancyPriority) 141 { 142 redundancyPriority = std::make_unique<RedundancyPriority>(bus, path, 143 *this, 0); 144 } 145 146 activationProgress->progress(100); 147 148 activationBlocksTransition.reset(); 149 activationProgress.reset(); 150 151 unsubscribeFromSystemdSignals(); 152 // Remove version object from image manager 153 deleteImageManagerObject(); 154 // Create active association 155 parent.createActiveAssociation(path); 156 // Create updateable association as this 157 // can be re-programmed. 158 parent.createUpdateableAssociation(path); 159 // Create functional assocaition 160 parent.updateFunctionalAssociation(versionId); 161 162 Activation::activation(Activation::Activations::Active); 163 } 164 165 } // namespace updater 166 } // namespace software 167 } // namespace openpower 168