| Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 1 | #include "software_update.hpp" | 
 | 2 |  | 
 | 3 | #include "device.hpp" | 
 | 4 | #include "software.hpp" | 
 | 5 |  | 
 | 6 | #include <phosphor-logging/elog-errors.hpp> | 
 | 7 | #include <phosphor-logging/elog.hpp> | 
 | 8 | #include <phosphor-logging/lg2.hpp> | 
 | 9 | #include <sdbusplus/async/context.hpp> | 
 | 10 | #include <xyz/openbmc_project/Software/Update/aserver.hpp> | 
 | 11 |  | 
 | 12 | PHOSPHOR_LOG2_USING; | 
 | 13 |  | 
 | 14 | using Unavailable = sdbusplus::xyz::openbmc_project::Common::Error::Unavailable; | 
 | 15 |  | 
 | 16 | using namespace phosphor::logging; | 
 | 17 | using namespace phosphor::software::update; | 
 | 18 | using namespace phosphor::software::device; | 
 | 19 | using namespace phosphor::software; | 
 | 20 |  | 
 | 21 | namespace SoftwareLogging = phosphor::logging::xyz::openbmc_project::software; | 
 | 22 | namespace SoftwareErrors = | 
 | 23 |     sdbusplus::error::xyz::openbmc_project::software::image; | 
 | 24 |  | 
 | 25 | SoftwareUpdate::SoftwareUpdate( | 
 | 26 |     sdbusplus::async::context& ctx, const char* path, Software& software, | 
 | 27 |     const std::set<RequestedApplyTimes>& allowedApplyTimes) : | 
 | 28 |     sdbusplus::aserver::xyz::openbmc_project::software::Update<SoftwareUpdate>( | 
 | 29 |         ctx, path), | 
 | 30 |     software(software), allowedApplyTimes(allowedApplyTimes) | 
| Alexander Hansen | 8b4ab1e | 2025-04-10 14:25:53 +0200 | [diff] [blame] | 31 | { | 
 | 32 |     emit_added(); | 
 | 33 | } | 
 | 34 |  | 
 | 35 | SoftwareUpdate::~SoftwareUpdate() | 
 | 36 | { | 
 | 37 |     emit_removed(); | 
 | 38 | } | 
| Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 39 |  | 
 | 40 | auto SoftwareUpdate::method_call(start_update_t /*unused*/, auto image, | 
 | 41 |                                  auto applyTime) | 
 | 42 |     -> sdbusplus::async::task<start_update_t::return_type> | 
 | 43 | { | 
 | 44 |     debug("Requesting Image update with {FD}", "FD", image.fd); | 
 | 45 |  | 
 | 46 |     Device& device = software.parentDevice; | 
 | 47 |  | 
 | 48 |     if (device.updateInProgress) | 
 | 49 |     { | 
 | 50 |         error("An update is already in progress, cannot update."); | 
| Alexander Hansen | f9cfdca | 2025-08-08 09:39:00 +0200 | [diff] [blame] | 51 |         elog<Unavailable>(); | 
| Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 52 |     } | 
 | 53 |  | 
 | 54 |     device.updateInProgress = true; | 
 | 55 |  | 
 | 56 |     // check if the apply time is allowed by our device | 
 | 57 |     if (!allowedApplyTimes.contains(applyTime)) | 
 | 58 |     { | 
 | 59 |         error( | 
 | 60 |             "the selected apply time {APPLYTIME} is not allowed by the device", | 
 | 61 |             "APPLYTIME", applyTime); | 
 | 62 |         device.updateInProgress = false; | 
| Alexander Hansen | f9cfdca | 2025-08-08 09:39:00 +0200 | [diff] [blame] | 63 |         elog<sdbusplus::error::xyz::openbmc_project::software::update:: | 
 | 64 |                  Incompatible>(); | 
| Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 65 |     } | 
 | 66 |  | 
 | 67 |     debug("started asynchronous update with fd {FD}", "FD", image.fd); | 
 | 68 |  | 
 | 69 |     int imageDup = dup(image.fd); | 
 | 70 |  | 
 | 71 |     if (imageDup < 0) | 
 | 72 |     { | 
 | 73 |         error("ERROR calling dup on fd: {ERR}", "ERR", strerror(errno)); | 
 | 74 |         device.updateInProgress = false; | 
 | 75 |         co_return software.objectPath; | 
 | 76 |     } | 
 | 77 |  | 
 | 78 |     debug("starting async update with FD: {FD}\n", "FD", imageDup); | 
 | 79 |  | 
 | 80 |     std::unique_ptr<Software> softwareInstance = | 
 | 81 |         std::make_unique<Software>(ctx, device); | 
 | 82 |  | 
 | 83 |     softwareInstance->setActivation(ActivationInterface::Activations::NotReady); | 
 | 84 |  | 
 | 85 |     std::string newObjPath = softwareInstance->objectPath; | 
 | 86 |  | 
| Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 87 |     ctx.spawn( | 
 | 88 |         [](Device& device, int imageDup, RequestedApplyTimes applyTime, | 
 | 89 |            std::unique_ptr<Software> swupdate) -> sdbusplus::async::task<> { | 
 | 90 |             co_await device.startUpdateAsync(imageDup, applyTime, | 
 | 91 |                                              std::move(swupdate)); | 
 | 92 |             device.updateInProgress = false; | 
 | 93 |             close(imageDup); | 
 | 94 |             co_return; | 
 | 95 |         }(device, imageDup, applyTime, std::move(softwareInstance))); | 
| Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 96 |  | 
 | 97 |     // We need the object path for the new software here. | 
 | 98 |     // It must be the same as constructed during the update process. | 
 | 99 |     // This is so that bmcweb and redfish clients can keep track of the update | 
 | 100 |     // process. | 
 | 101 |     co_return newObjPath; | 
 | 102 | } | 
 | 103 |  | 
 | 104 | auto SoftwareUpdate::get_property(allowed_apply_times_t /*unused*/) const | 
 | 105 | { | 
 | 106 |     return allowedApplyTimes; | 
 | 107 | } |