Error handling for executeCmd API
This commit updates executeCmd API to set error code in case of error.
This helps the caller of API to take action based on the error code
returned from the API.
Change-Id: Ie5b7804f5d486a278765d460eabaef0bd46d555e
Signed-off-by: Rekha Aparna <vrekhaaparna@ibm.com>
diff --git a/vpd-manager/include/error_codes.hpp b/vpd-manager/include/error_codes.hpp
index 0665709..e404cf5 100644
--- a/vpd-manager/include/error_codes.hpp
+++ b/vpd-manager/include/error_codes.hpp
@@ -33,6 +33,7 @@
ERROR_PROCESSING_SYSTEM_CMD,
STANDARD_EXCEPTION,
DBUS_FAILURE,
+ POPEN_FAILED,
// VPD specific errors
UNSUPPORTED_VPD_TYPE,
@@ -84,5 +85,6 @@
"Failed to detect location code type"},
{error_code::DBUS_FAILURE, "Dbus call failed"},
{error_code::RECEIVED_INVALID_KWD_TYPE_FROM_DBUS,
- "Received invalid keyword data type from DBus."}};
+ "Received invalid keyword data type from DBus."},
+ {error_code::POPEN_FAILED, "popen failed"}};
} // namespace vpd
diff --git a/vpd-manager/include/utility/common_utility.hpp b/vpd-manager/include/utility/common_utility.hpp
index dc5da28..6c28f5b 100644
--- a/vpd-manager/include/utility/common_utility.hpp
+++ b/vpd-manager/include/utility/common_utility.hpp
@@ -99,28 +99,45 @@
* @throw std::runtime_error.
*
* @param[in] arguments for command
+ * @param[out] o_errCode - To set error code in case of error.
* @returns output of that command
*/
template <typename T, typename... Types>
-inline std::vector<std::string> executeCmd(T&& i_path, Types... i_args)
+inline std::vector<std::string> executeCmd(T&& i_path, uint16_t& o_errCode,
+ Types... i_args)
{
+ o_errCode = 0;
std::vector<std::string> l_cmdOutput;
- std::array<char, constants::CMD_BUFFER_LENGTH> l_buffer;
- std::string l_cmd = i_path + getCommand(i_args...);
-
- std::unique_ptr<FILE, decltype(&pclose)> l_cmdPipe(
- popen(l_cmd.c_str(), "r"), pclose);
-
- if (!l_cmdPipe)
+ try
{
- logging::logMessage(
- "popen failed with error " + std::string(strerror(errno)));
- throw std::runtime_error("popen failed!");
+ std::array<char, constants::CMD_BUFFER_LENGTH> l_buffer;
+
+ std::string l_cmd = i_path + getCommand(i_args...);
+
+ std::unique_ptr<FILE, decltype(&pclose)> l_cmdPipe(
+ popen(l_cmd.c_str(), "r"), pclose);
+
+ if (!l_cmdPipe)
+ {
+ o_errCode = error_code::POPEN_FAILED;
+ Logger::getLoggerInstance()->logMessage(
+ "popen failed with error " + std::string(strerror(errno)));
+ return l_cmdOutput;
+ }
+
+ while (fgets(l_buffer.data(), l_buffer.size(), l_cmdPipe.get()) !=
+ nullptr)
+ {
+ l_cmdOutput.emplace_back(l_buffer.data());
+ }
}
- while (fgets(l_buffer.data(), l_buffer.size(), l_cmdPipe.get()) != nullptr)
+ catch (const std::exception& l_ex)
{
- l_cmdOutput.emplace_back(l_buffer.data());
+ o_errCode = error_code::STANDARD_EXCEPTION;
+ Logger::getLoggerInstance()->logMessage(
+ "Error while trying to execute command [" + std::string(i_path) +
+ "], error : " + std::string(l_ex.what()));
}
return l_cmdOutput;
@@ -283,8 +300,9 @@
{
try
{
+ uint16_t l_errCode = 0;
std::vector<std::string> l_cmdOutput =
- executeCmd("/sbin/fw_printenv fieldmode");
+ executeCmd("/sbin/fw_printenv fieldmode", l_errCode);
if (l_cmdOutput.size() > 0)
{
@@ -292,9 +310,15 @@
// Remove the new line character from the string.
l_cmdOutput[0].erase(l_cmdOutput[0].length() - 1);
-
return l_cmdOutput[0] == "fieldmode=true";
}
+ else if (l_errCode)
+ {
+ // ToDo : Remove log and set error code.
+ Logger::getLoggerInstance()->logMessage(
+ "Failed to execute command, error : " +
+ getErrCodeMsg(l_errCode));
+ }
}
catch (const std::exception& l_ex)
{}
@@ -315,11 +339,12 @@
inline types::VpdCollectionMode getVpdCollectionMode(
uint16_t& o_errCode) noexcept
{
+ o_errCode = 0;
types::VpdCollectionMode l_result{types::VpdCollectionMode::DEFAULT_MODE};
try
{
std::vector<std::string> l_cmdOutput =
- commonUtility::executeCmd("/sbin/fw_printenv vpdmode");
+ commonUtility::executeCmd("/sbin/fw_printenv vpdmode", o_errCode);
if (l_cmdOutput.size() > 0)
{
diff --git a/vpd-manager/include/utility/json_utility.hpp b/vpd-manager/include/utility/json_utility.hpp
index 9f5e12a..83617d7 100644
--- a/vpd-manager/include/utility/json_utility.hpp
+++ b/vpd-manager/include/utility/json_utility.hpp
@@ -319,7 +319,7 @@
i_parsedConfigJson["frus"][i_vpdFilePath].at(
0)[i_baseAction][i_flagToProcess]["systemCmd"]["cmd"];
- commonUtility::executeCmd(l_systemCommand);
+ commonUtility::executeCmd(l_systemCommand, o_errCode);
}
catch (const std::exception& l_ex)
{
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index ec3597b..607ba34 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -4,6 +4,7 @@
#include "configuration.hpp"
#include "listener.hpp"
+#include "logger.hpp"
#include "parser.hpp"
#include <utility/common_utility.hpp>
@@ -417,6 +418,7 @@
// iterate over each MUX detail and enable them.
for (const auto& item : m_sysCfgJsonObj["muxes"])
{
+ uint16_t l_errCode = 0;
if (item.contains("holdidlepath"))
{
std::string cmd = "echo 0 > ";
@@ -424,7 +426,15 @@
logging::logMessage("Enabling mux with command = " + cmd);
- commonUtility::executeCmd(cmd);
+ commonUtility::executeCmd(cmd, l_errCode);
+
+ if (l_errCode)
+ {
+ m_logger->logMessage(
+ "Failed to execute command [" + cmd +
+ "], error : " + commonUtility::getErrCodeMsg(l_errCode));
+ }
+
continue;
}
@@ -507,7 +517,16 @@
const std::string& i_value)
{
// set env and reboot and break.
- commonUtility::executeCmd("/sbin/fw_setenv", i_key, i_value);
+ uint16_t l_errCode = 0;
+ commonUtility::executeCmd("/sbin/fw_setenv", l_errCode, i_key, i_value);
+
+ if (l_errCode)
+ {
+ throw std::runtime_error(
+ "Failed to execute command [/sbin/fw_setenv " + i_key + " " +
+ i_value + "], error : " + commonUtility::getErrCodeMsg(l_errCode));
+ }
+
logging::logMessage("Rebooting BMC to pick up new device tree");
// make dbus call to reboot
@@ -520,8 +539,17 @@
static std::string readFitConfigValue()
{
+ uint16_t l_errCode = 0;
std::vector<std::string> l_output =
- commonUtility::executeCmd("/sbin/fw_printenv");
+ commonUtility::executeCmd("/sbin/fw_printenv", l_errCode);
+
+ if (l_errCode)
+ {
+ Logger::getLoggerInstance()->logMessage(
+ "Failed to execute command [/sbin/fw_printenv], error : " +
+ commonUtility::getErrCodeMsg(l_errCode));
+ }
+
std::string l_fitConfigValue;
for (const auto& l_entry : l_output)