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