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
flashWrite()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 }
61
onStateChanges(sdbusplus::message_t & msg)62 void Activation::onStateChanges([[maybe_unused]] sdbusplus::message_t& msg)
63 {
64 #ifdef BMC_STATIC_DUAL_IMAGE
65 uint32_t newStateID;
66 auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service";
67 sdbusplus::message::object_path newStateObjPath;
68 std::string newStateUnit{};
69 std::string newStateResult{};
70 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
71
72 if (newStateUnit != serviceFile)
73 {
74 return;
75 }
76 if (newStateResult == "done")
77 {
78 activationProgress->progress(90);
79 onFlashWriteSuccess();
80 }
81 else
82 {
83 Activation::activation(sdbusplus::server::xyz::openbmc_project::
84 software::Activation::Activations::Failed);
85 }
86 #endif
87 }
88
89 } // namespace updater
90 } // namespace software
91 } // namespace phosphor
92