1 #include "config.h" 2 3 #include "flash.hpp" 4 5 #include "activation.hpp" 6 #include "images.hpp" 7 #include "item_updater.hpp" 8 9 #include <phosphor-logging/lg2.hpp> 10 11 #include <filesystem> 12 #include <system_error> 13 14 namespace 15 { 16 constexpr auto PATH_INITRAMFS = "/run/initramfs"; 17 constexpr auto FLASH_ALT_SERVICE_TMPL = "obmc-flash-bmc-alt@"; 18 } // namespace 19 20 namespace phosphor 21 { 22 namespace software 23 { 24 namespace updater 25 { 26 27 PHOSPHOR_LOG2_USING; 28 29 namespace fs = std::filesystem; 30 using namespace phosphor::software::image; 31 32 void Activation::flashWrite() 33 { 34 #ifdef BMC_STATIC_DUAL_IMAGE 35 if (parent.runningImageSlot != 0) 36 { 37 // It's running on the secondary chip, update the primary one 38 info("Flashing primary flash from secondary, id: {ID}", "ID", 39 versionId); 40 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, 41 SYSTEMD_INTERFACE, "StartUnit"); 42 auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service"; 43 method.append(serviceFile, "replace"); 44 bus.call_noreply(method); 45 return; 46 } 47 #endif 48 // For static layout code update, just put images in /run/initramfs. 49 // It expects user to trigger a reboot and an updater script will program 50 // the image to flash during reboot. 51 fs::path uploadDir(IMG_UPLOAD_DIR); 52 fs::path toPath(PATH_INITRAMFS); 53 54 for (const auto& bmcImage : parent.imageUpdateList) 55 { 56 std::error_code ec; 57 fs::copy_file(uploadDir / versionId / bmcImage, toPath / bmcImage, 58 fs::copy_options::overwrite_existing, ec); 59 } 60 for (const auto& optionalImaage : getOptionalImages()) 61 { 62 std::error_code ec; 63 fs::copy_file(uploadDir / versionId / optionalImaage, 64 toPath / optionalImaage, 65 fs::copy_options::overwrite_existing, ec); 66 } 67 } 68 69 void Activation::onStateChanges([[maybe_unused]] sdbusplus::message_t& msg) 70 { 71 #ifdef BMC_STATIC_DUAL_IMAGE 72 uint32_t newStateID; 73 auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service"; 74 sdbusplus::message::object_path newStateObjPath; 75 std::string newStateUnit{}; 76 std::string newStateResult{}; 77 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); 78 79 if (newStateUnit != serviceFile) 80 { 81 return; 82 } 83 if (newStateResult == "done") 84 { 85 activationProgress->progress(90); 86 onFlashWriteSuccess(); 87 } 88 else 89 { 90 Activation::activation(sdbusplus::server::xyz::openbmc_project:: 91 software::Activation::Activations::Failed); 92 } 93 #endif 94 } 95 96 } // namespace updater 97 } // namespace software 98 } // namespace phosphor 99