Skip to content

Commit

Permalink
Merge pull request #517 from souvik1914581/sr_addRebootGuardWriteHard…
Browse files Browse the repository at this point in the history
…ware

Add Reboot Guard in Parser updateVpdKeyword API
  • Loading branch information
SunnySrivastava1984 authored Jan 2, 2025
2 parents 38810d6 + 53e0854 commit b86a972
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 15 deletions.
5 changes: 5 additions & 0 deletions vpd-manager/include/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,10 @@ static constexpr auto eventLoggingServiceName = "xyz.openbmc_project.Logging";
static constexpr auto eventLoggingObjectPath = "/xyz/openbmc_project/logging";
static constexpr auto eventLoggingInterface =
"xyz.openbmc_project.Logging.Create";

static constexpr auto systemdService = "org.freedesktop.systemd1";
static constexpr auto systemdObjectPath = "/org/freedesktop/systemd1";
static constexpr auto systemdManagerInterface =
"org.freedesktop.systemd1.Manager";
} // namespace constants
} // namespace vpd
111 changes: 111 additions & 0 deletions vpd-manager/include/utility/dbus_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "logger.hpp"
#include "types.hpp"

#include <chrono>

namespace vpd
{
/**
Expand Down Expand Up @@ -453,5 +455,114 @@ inline bool isBMCReady()

return false;
}

/**
* @brief An API to enable BMC reboot guard
*
* This API does a D-Bus method call to enable BMC reboot guard.
*
* @return On success, returns 0, otherwise returns -1.
*/
inline int EnableRebootGuard() noexcept
{
int l_rc{constants::FAILURE};
try
{
auto l_bus = sdbusplus::bus::new_default();
auto l_method = l_bus.new_method_call(
constants::systemdService, constants::systemdObjectPath,
constants::systemdManagerInterface, "StartUnit");
l_method.append("reboot-guard-enable.service", "replace");
l_bus.call_noreply(l_method);
l_rc = constants::SUCCESS;
}
catch (const sdbusplus::exception::SdBusError& l_ex)
{
std::string l_errMsg =
"D-Bus call to enable BMC reboot guard failed for reason: ";
l_errMsg += l_ex.what();

logging::logMessage(l_errMsg);
}
return l_rc;
}

/**
* @brief An API to disable BMC reboot guard
*
* This API disables BMC reboot guard. This API has an inbuilt re-try mechanism.
* If Disable Reboot Guard fails, this API attempts to Disable Reboot Guard for
* 3 more times at an interval of 333ms.
*
* @return On success, returns 0, otherwise returns -1.
*/
inline int DisableRebootGuard() noexcept
{
int l_rc{constants::FAILURE};

// A lambda which executes the DBus call to disable BMC reboot guard.
auto l_executeDisableRebootGuard = []() -> int {
int l_dBusCallRc{constants::FAILURE};
try
{
auto l_bus = sdbusplus::bus::new_default();
auto l_method = l_bus.new_method_call(
constants::systemdService, constants::systemdObjectPath,
constants::systemdManagerInterface, "StartUnit");
l_method.append("reboot-guard-disable.service", "replace");
l_bus.call_noreply(l_method);
l_dBusCallRc = constants::SUCCESS;
}
catch (const sdbusplus::exception::SdBusError& l_ex)
{}
return l_dBusCallRc;
};

if (constants::FAILURE == l_executeDisableRebootGuard())
{
std::function<void()> l_retryDisableRebootGuard;

// A lambda which tries to disable BMC reboot guard for 3 times at an
// interval of 333 ms.
l_retryDisableRebootGuard = [&]() {
constexpr int MAX_RETRIES{3};
static int l_numRetries{0};

if (l_numRetries < MAX_RETRIES)
{
l_numRetries++;
if (constants::FAILURE == l_executeDisableRebootGuard())
{
// sleep for 333ms before next retry. This is just a random
// value so that 3 re-tries * 333ms takes ~1 second in the
// worst case.
const std::chrono::milliseconds l_sleepTime{333};
std::this_thread::sleep_for(l_sleepTime);
l_retryDisableRebootGuard();
}
else
{
l_numRetries = 0;
l_rc = constants::SUCCESS;
}
}
else
{
// Failed to Disable Reboot Guard even after 3 retries.
logging::logMessage("Failed to Disable Reboot Guard after " +
std::to_string(MAX_RETRIES) + " re-tries");
l_numRetries = 0;
}
};

l_retryDisableRebootGuard();
}
else
{
l_rc = constants::SUCCESS;
}
return l_rc;
}

} // namespace dbusUtility
} // namespace vpd
63 changes: 48 additions & 15 deletions vpd-manager/src/parser.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "parser.hpp"

#include "constants.hpp"
#include "event_logger.hpp"

#include <utility/dbus_utility.hpp>
#include <utility/json_utility.hpp>
Expand Down Expand Up @@ -59,8 +60,41 @@ types::VPDMapVariant Parser::parse()
int Parser::updateVpdKeyword(const types::WriteVpdParams& i_paramsToWriteData)
{
int l_bytesUpdatedOnHardware = constants::FAILURE;

// A lambda to extract Record : Keyword string from i_paramsToWriteData
auto l_keyWordIdentifier =
[](const types::WriteVpdParams& i_paramsToWriteData) -> std::string {
std::string l_keywordString{};
if (const types::IpzData* l_ipzData =
std::get_if<types::IpzData>(&i_paramsToWriteData))
{
l_keywordString = std::get<0>(*l_ipzData) + ":" +
std::get<1>(*l_ipzData);
}
else if (const types::KwData* l_kwData =
std::get_if<types::KwData>(&i_paramsToWriteData))
{
l_keywordString = std::get<0>(*l_kwData);
}
return l_keywordString;
};

try
{
// Enable Reboot Guard
if (constants::FAILURE == dbusUtility::EnableRebootGuard())
{
EventLogger::createAsyncPel(
types::ErrorType::DbusFailure,
types::SeverityType::Informational, __FILE__, __FUNCTION__, 0,
std::string(
"Failed to enable BMC Reboot Guard while updating " +
l_keyWordIdentifier(i_paramsToWriteData)),
std::nullopt, std::nullopt, std::nullopt, std::nullopt);

return constants::FAILURE;
}

// Update keyword's value on hardware
try
{
Expand Down Expand Up @@ -178,26 +212,25 @@ int Parser::updateVpdKeyword(const types::WriteVpdParams& i_paramsToWriteData)
}
catch (const std::exception& l_ex)
{
std::string l_keywordIdentifier{};
if (const types::IpzData* l_ipzData =
std::get_if<types::IpzData>(&i_paramsToWriteData))
{
l_keywordIdentifier = std::get<0>(*l_ipzData) + ":" +
std::get<1>(*l_ipzData);
}
else if (const types::KwData* l_kwData =
std::get_if<types::KwData>(&i_paramsToWriteData))
{
l_keywordIdentifier = std::get<0>(*l_kwData);
}
logging::logMessage(
"Update VPD Keyword failed for : " + l_keywordIdentifier +
" failed due to error: " + l_ex.what());
logging::logMessage("Update VPD Keyword failed for : " +
l_keyWordIdentifier(i_paramsToWriteData) +
" failed due to error: " + l_ex.what());

// update failed, set return value to failure
l_bytesUpdatedOnHardware = constants::FAILURE;
}

// Disable Reboot Guard
if (constants::FAILURE == dbusUtility::DisableRebootGuard())
{
EventLogger::createAsyncPel(
types::ErrorType::DbusFailure, types::SeverityType::Critical,
__FILE__, __FUNCTION__, 0,
std::string("Failed to disable BMC Reboot Guard while updating " +
l_keyWordIdentifier(i_paramsToWriteData)),
std::nullopt, std::nullopt, std::nullopt, std::nullopt);
}

return l_bytesUpdatedOnHardware;
}

Expand Down

0 comments on commit b86a972

Please sign in to comment.