common: move asyncSystem() to common
asyncSystem() is shared across updaters, so moved to common.
Change-Id: I3545d34ecc1f1bf8a226d020267ae00bcf42c5f9
Signed-off-by: Kevin Tung <Kevin.Tung@quantatw.com>
diff --git a/bios/spi_device.cpp b/bios/spi_device.cpp
index a1b1f49..1af1e66 100644
--- a/bios/spi_device.cpp
+++ b/bios/spi_device.cpp
@@ -4,6 +4,7 @@
#include "common/include/device.hpp"
#include "common/include/host_power.hpp"
#include "common/include/software_manager.hpp"
+#include "common/include/utils.hpp"
#include <gpiod.hpp>
#include <phosphor-logging/lg2.hpp>
@@ -273,17 +274,15 @@
{
if (tool == flashToolFlashrom)
{
- const int status =
- co_await SPIDevice::writeSPIFlashWithFlashrom(image,
- image_size);
- if (status != 0)
+ success = co_await SPIDevice::writeSPIFlashWithFlashrom(
+ image, image_size);
+ if (!success)
{
error(
- "Error writing to SPI flash {CONTROLLERINDEX}:{DEVICEINDEX}, exit code {EXITCODE}",
+ "Error writing to SPI flash {CONTROLLERINDEX}:{DEVICEINDEX}",
"CONTROLLERINDEX", spiControllerIndex, "DEVICEINDEX",
- spiDeviceIndex, "EXITCODE", status);
+ spiDeviceIndex);
}
- success = (status == 0);
}
else if (tool == flashToolFlashcp)
{
@@ -318,50 +317,7 @@
co_return success;
}
-sdbusplus::async::task<int> asyncSystem(sdbusplus::async::context& ctx,
- const std::string& cmd)
-{
- int pipefd[2];
- if (pipe(pipefd) == -1)
- {
- perror("pipe");
- co_return -1;
- }
-
- pid_t pid = fork();
- if (pid == -1)
- {
- perror("fork");
- close(pipefd[0]);
- close(pipefd[1]);
- co_return -1;
- }
- else if (pid == 0)
- {
- close(pipefd[0]);
- int exitCode = std::system(cmd.c_str());
-
- ssize_t status = write(pipefd[1], &exitCode, sizeof(exitCode));
- close(pipefd[1]);
- exit((status == sizeof(exitCode)) ? 0 : 1);
- }
- else
- {
- close(pipefd[1]);
-
- sdbusplus::async::fdio pipe_fdio(ctx, pipefd[0]);
-
- co_await pipe_fdio.next();
-
- int status;
- waitpid(pid, &status, 0);
- close(pipefd[0]);
-
- co_return WEXITSTATUS(status);
- }
-}
-
-sdbusplus::async::task<int> SPIDevice::writeSPIFlashWithFlashrom(
+sdbusplus::async::task<bool> SPIDevice::writeSPIFlashWithFlashrom(
const uint8_t* image, size_t image_size) const
{
// randomize the name to enable parallel updates
@@ -424,11 +380,11 @@
debug("[flashrom] running {CMD}", "CMD", cmd);
- const int exitCode = co_await asyncSystem(ctx, cmd);
+ auto success = co_await asyncSystem(ctx, cmd);
std::filesystem::remove(path);
- co_return exitCode;
+ co_return success;
}
sdbusplus::async::task<bool> SPIDevice::writeSPIFlashWithFlashcp(
@@ -470,11 +426,11 @@
debug("running {CMD}", "CMD", cmd);
- const int exitCode = co_await asyncSystem(ctx, cmd);
+ auto success = co_await asyncSystem(ctx, cmd);
std::filesystem::remove(path);
- co_return exitCode == 0;
+ co_return success;
}
sdbusplus::async::task<bool> SPIDevice::writeSPIFlashDefault(
diff --git a/bios/spi_device.hpp b/bios/spi_device.hpp
index 25a53d1..63e7956 100644
--- a/bios/spi_device.hpp
+++ b/bios/spi_device.hpp
@@ -110,8 +110,8 @@
// Intel Flash Descriptor
// @param image the component image
// @param image_size size of 'image'
- // @returns 0 on success
- sdbusplus::async::task<int> writeSPIFlashWithFlashrom(
+ // @returns true on success
+ sdbusplus::async::task<bool> writeSPIFlashWithFlashrom(
const uint8_t* image, size_t image_size) const;
// @description preconditions:
diff --git a/common/include/utils.hpp b/common/include/utils.hpp
new file mode 100644
index 0000000..928b136
--- /dev/null
+++ b/common/include/utils.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <sdbusplus/async.hpp>
+
+/**
+ * @brief Asynchronously executes a shell command.
+ * @param ctx Async context for monitoring the pipe.
+ * @param cmd Shell command to execute.
+ * @return Task resolving to true on success (exit code 0), false otherwise.
+ */
+sdbusplus::async::task<bool> asyncSystem(sdbusplus::async::context& ctx,
+ const std::string& cmd);
diff --git a/common/meson.build b/common/meson.build
index 1e29ae8..8f515e1 100644
--- a/common/meson.build
+++ b/common/meson.build
@@ -9,6 +9,7 @@
'src/software.cpp',
'src/software_update.cpp',
'src/host_power.cpp',
+ 'src/utils.cpp',
include_directories: ['.', 'include/', common_include],
dependencies: [pdi_dep, phosphor_logging_dep, sdbusplus_dep, libpldm_dep],
)
diff --git a/common/src/utils.cpp b/common/src/utils.cpp
new file mode 100644
index 0000000..683ca84
--- /dev/null
+++ b/common/src/utils.cpp
@@ -0,0 +1,79 @@
+#include "common/include/utils.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+sdbusplus::async::task<bool> asyncSystem(sdbusplus::async::context& ctx,
+ const std::string& cmd)
+{
+ int pipefd[2];
+ if (pipe(pipefd) == -1)
+ {
+ error("Failed to create pipe for command: {CMD}", "CMD", cmd);
+ co_return false;
+ }
+
+ pid_t pid = fork();
+ if (pid == 0)
+ {
+ close(pipefd[0]);
+
+ int exitCode = std::system(cmd.c_str());
+ ssize_t status = write(pipefd[1], &exitCode, sizeof(exitCode));
+
+ close(pipefd[1]);
+ _exit((status == sizeof(exitCode)) ? 0 : 1);
+ }
+ else if (pid > 0)
+ {
+ close(pipefd[1]);
+
+ auto fdio = std::make_unique<sdbusplus::async::fdio>(ctx, pipefd[0]);
+
+ if (!fdio)
+ {
+ error("Failed to create fdio for command: {CMD}", "CMD", cmd);
+ close(pipefd[0]);
+ co_return false;
+ }
+
+ co_await fdio->next();
+
+ int exitCode = -1;
+ ssize_t bytesRead = read(pipefd[0], &exitCode, sizeof(exitCode));
+ close(pipefd[0]);
+
+ if (bytesRead != sizeof(exitCode))
+ {
+ error("Failed to read exit code from command {CMD}", "CMD", cmd);
+ co_return false;
+ }
+
+ int status;
+ if (waitpid(pid, &status, 0) < 0)
+ {
+ error("waitpid failed for PID {PID} for command {CMD}", "PID", pid,
+ "CMD", cmd);
+ co_return false;
+ }
+
+ if (exitCode != 0)
+ {
+ error("Command {CMD} exited with code {CODE}", "CMD", cmd, "CODE",
+ exitCode);
+ co_return false;
+ }
+
+ debug("{CMD} executed successfully", "CMD", cmd);
+
+ co_return true;
+ }
+ else
+ {
+ error("Fork failed for command: {CMD}", "CMD", cmd);
+ close(pipefd[0]);
+ close(pipefd[1]);
+ co_return false;
+ }
+}
diff --git a/eeprom-device/eeprom_device.cpp b/eeprom-device/eeprom_device.cpp
index ca27c28..fbe65f3 100644
--- a/eeprom-device/eeprom_device.cpp
+++ b/eeprom-device/eeprom_device.cpp
@@ -1,6 +1,7 @@
#include "eeprom_device.hpp"
#include "common/include/software.hpp"
+#include "common/include/utils.hpp"
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/async.hpp>
@@ -88,55 +89,6 @@
return lineBulks;
}
-sdbusplus::async::task<int> asyncSystem(sdbusplus::async::context& ctx,
- const std::string& cmd)
-{
- int pipefd[2];
- if (pipe(pipefd) == -1)
- {
- perror("pipe");
- co_return -1;
- }
-
- pid_t pid = fork();
- if (pid == -1)
- {
- perror("fork");
- close(pipefd[0]);
- close(pipefd[1]);
- co_return -1;
- }
- else if (pid == 0)
- {
- close(pipefd[0]);
- int exitCode = std::system(cmd.c_str());
-
- ssize_t status = write(pipefd[1], &exitCode, sizeof(exitCode));
- close(pipefd[1]);
- exit((status == sizeof(exitCode)) ? 0 : 1);
- }
- else
- {
- close(pipefd[1]);
-
- auto fdio = std::make_unique<sdbusplus::async::fdio>(ctx, pipefd[0]);
- if (!fdio)
- {
- perror("fdio creation failed");
- close(pipefd[0]);
- co_return -1;
- }
-
- co_await fdio->next();
-
- int status;
- waitpid(pid, &status, 0);
- close(pipefd[0]);
-
- co_return WEXITSTATUS(status);
- }
-}
-
static std::string getDriverPath(const std::string& chipModel)
{
// Currently, only EEPROM chips with the model AT24 are supported.
@@ -220,13 +172,7 @@
setUpdateProgress(40);
- const int rc = co_await writeEEPROM(image, image_size);
- if (rc != 0)
- {
- error("Error writing to EEPROM, exit code {CODE}", "CODE", rc);
- }
-
- bool success = (rc == 0);
+ auto success = co_await writeEEPROM(image, image_size);
if (success)
{
@@ -378,8 +324,8 @@
return std::filesystem::exists(driverPath + "/" + i2cDeviceId);
}
-sdbusplus::async::task<int> EEPROMDevice::writeEEPROM(const uint8_t* image,
- size_t image_size) const
+sdbusplus::async::task<bool> EEPROMDevice::writeEEPROM(const uint8_t* image,
+ size_t image_size) const
{
auto eepromPath = getEEPROMPath(bus, address);
if (eepromPath.empty())
@@ -415,11 +361,11 @@
debug("Running {CMD}", "CMD", cmd);
- const int exitCode = co_await asyncSystem(ctx, cmd);
+ auto success = co_await asyncSystem(ctx, cmd);
std::filesystem::remove(path);
- co_return exitCode;
+ co_return success;
}
sdbusplus::async::task<> EEPROMDevice::processHostStateChange()
diff --git a/eeprom-device/eeprom_device.hpp b/eeprom-device/eeprom_device.hpp
index 6e6eee5..de1fd2d 100644
--- a/eeprom-device/eeprom_device.hpp
+++ b/eeprom-device/eeprom_device.hpp
@@ -65,8 +65,8 @@
* @param image_size - Size of the data to write in bytes.
* @return `true` on success, `false` otherwise.
*/
- sdbusplus::async::task<int> writeEEPROM(const uint8_t* image,
- size_t image_size) const;
+ sdbusplus::async::task<bool> writeEEPROM(const uint8_t* image,
+ size_t image_size) const;
/**
* @brief Handle async host state change signal and updates the version.
*/