Skip to content

Commit

Permalink
Merge pull request #429 from RekhaAparna01/deleteFruVpd
Browse files Browse the repository at this point in the history
API for FRU VPD deletion
  • Loading branch information
jinuthomas authored Dec 6, 2024
2 parents 3ae3e9d + 8b1a32c commit e50d032
Show file tree
Hide file tree
Showing 12 changed files with 1,493 additions and 18 deletions.
216 changes: 216 additions & 0 deletions configuration/ibm/50001000.json

Large diffs are not rendered by default.

216 changes: 216 additions & 0 deletions configuration/ibm/50001000_v2.json

Large diffs are not rendered by default.

216 changes: 216 additions & 0 deletions configuration/ibm/50001001.json

Large diffs are not rendered by default.

242 changes: 229 additions & 13 deletions configuration/ibm/50001001_v2.json

Large diffs are not rendered by default.

210 changes: 210 additions & 0 deletions configuration/ibm/50003000.json

Large diffs are not rendered by default.

214 changes: 214 additions & 0 deletions configuration/ibm/50003000_v2.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions include/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ constexpr auto biosConfigMgrObjPath =
constexpr auto biosConfigMgrService = "xyz.openbmc_project.BIOSConfigManager";
constexpr auto biosConfigMgrInterface =
"xyz.openbmc_project.BIOSConfig.Manager";
constexpr auto objectMapperService = "xyz.openbmc_project.ObjectMapper";
constexpr auto objectMapperPath = "/xyz/openbmc_project/object_mapper";
constexpr auto objectMapperInf = "xyz.openbmc_project.ObjectMapper";
constexpr auto systemVpdInvPath =
"/xyz/openbmc_project/inventory/system/chassis/motherboard";
constexpr auto assetTagInf = "xyz.openbmc_project.Inventory.Decorator.AssetTag";
Expand Down
1 change: 1 addition & 0 deletions include/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ using DbusVariantType = std::variant<

using MapperGetObject =
std::vector<std::pair<std::string, std::vector<std::string>>>;
using MapperGetSubTree = std::map<std::string, std::map<std::string, std::vector<std::string>>>;

/* A type for holding the innermost map of property::value.*/
using IPZKwdValueMap = std::unordered_map<std::string, std::string>;
Expand Down
50 changes: 50 additions & 0 deletions include/utility/dbus_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,56 @@ inline types::PropertyMap getPropertyMap(const std::string& i_service,
return l_propertyValueMap;
}

/**
* @brief API to get object subtree from D-bus.
*
* The API returns the map of object, services and interfaces in the
* subtree that implement a certain interface. If no interfaces are provided
* then all the objects, services and interfaces under the subtree will
* be returned.
*
* Note: Depth can be 0 and interfaces can be null.
* It will be caller's responsibility to check for empty vector returned
* and generate appropriate error.
*
* @param[in] i_objectPath - Path to search for an interface.
* @param[in] i_depth - Maximum depth of the tree to search.
* @param[in] i_interfaces - List of interfaces to search.
*
* @return - A map of object and its related services and interfaces, if
* success. If failed, empty map.
*/

inline types::MapperGetSubTree
getObjectSubTree(const std::string& i_objectPath, const int& i_depth,
const std::vector<std::string>& i_interfaces)
{
types::MapperGetSubTree l_subTreeMap;

if (i_objectPath.empty())
{
logging::logMessage("Object path is empty.");
return l_subTreeMap;
}

try
{
auto l_bus = sdbusplus::bus::new_default();
auto l_method = l_bus.new_method_call(
constants::objectMapperService, constants::objectMapperPath,
constants::objectMapperInf, "GetSubTree");
l_method.append(i_objectPath, i_depth, i_interfaces);
auto l_result = l_bus.call(l_method);
l_result.read(l_subTreeMap);
}
catch (const sdbusplus::exception::SdBusError& l_ex)
{
logging::logMessage(l_ex.what());
}

return l_subTreeMap;
}

/**
* @brief An API to read property from Dbus.
*
Expand Down
9 changes: 9 additions & 0 deletions include/worker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ class Worker
types::ObjectMap& objectInterfaceMap,
const std::string& vpdFilePath);

/**
* @brief An API to delete FRU VPD over DBus.
*
* @param[in] i_dbusObjPath - Dbus object path of the FRU.
*
* @throw std::runtime_error if given input path is empty.
*/
void deleteFruVpd(const std::string& i_dbusObjPath);

/**
* @brief API to get status of VPD collection process.
*
Expand Down
24 changes: 22 additions & 2 deletions src/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,28 @@ void Manager::collectSingleFruVpd(
void Manager::deleteSingleFruVpd(
const sdbusplus::message::object_path& i_dbusObjPath)
{
// Dummy code to supress unused variable warning. To be removed.
logging::logMessage(std::string(i_dbusObjPath));
try
{
if (std::string(i_dbusObjPath).empty())
{
throw std::runtime_error(
"Given DBus object path is empty. Aborting FRU VPD deletion.");
}

if (m_worker.get() == nullptr)
{
throw std::runtime_error(
"Worker object not found, can't perform FRU VPD deletion for: " +
std::string(i_dbusObjPath));
}

m_worker->deleteFruVpd(std::string(i_dbusObjPath));
}
catch (const std::exception& l_ex)
{
// TODO: Log PEL
logging::logMessage(l_ex.what());
}
}

bool Manager::isValidUnexpandedLocationCode(
Expand Down
110 changes: 107 additions & 3 deletions src/worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1282,13 +1282,13 @@ bool Worker::processPostAction(
// Check if post action tag is to be triggered in the flow of collection
// based on some CCIN value?
if (m_parsedJson["frus"][i_vpdFruPath]
.at(0)["postAction"]["collection"]
.at(0)["postAction"][i_flagToProcess]
.contains("ccin"))
{
if (!i_parsedVpd.has_value())
{
throw std::runtime_error(
"Parsed VPD map parameter is mandatory for CCIN match");
logging::logMessage("Empty VPD Map");
return false;
}

// CCIN match is required to process post action for this FRU as it
Expand Down Expand Up @@ -1563,4 +1563,108 @@ void Worker::performBackupAndRestore(types::VPDMapVariant& io_srcVpdMap)
*/
}
}

void Worker::deleteFruVpd(const std::string& i_dbusObjPath)
{
if (i_dbusObjPath.empty())
{
throw std::runtime_error("Given DBus object path is empty.");
}

const std::string& l_fruPath =
jsonUtility::getFruPathFromJson(m_parsedJson, i_dbusObjPath);

try
{
auto l_presentPropValue = dbusUtility::readDbusProperty(
constants::pimServiceName, i_dbusObjPath,
constants::inventoryItemInf, "Present");

if (auto l_value = std::get_if<bool>(&l_presentPropValue))
{
if (!(*l_value))
{
throw std::runtime_error("Given FRU is not present");
}
else
{
if (jsonUtility::isActionRequired(m_parsedJson, l_fruPath,
"preAction", "deletion"))
{
if (!processPreAction(l_fruPath, "deletion"))
{
throw std::runtime_error("Pre action failed");
}
}

std::vector<std::string> l_interfaceList{
constants::operationalStatusInf};

types::MapperGetSubTree l_subTreeMap =
dbusUtility::getObjectSubTree(i_dbusObjPath, 0,
l_interfaceList);

types::ObjectMap l_objectMap;

// Updates VPD specific interfaces property value under PIM for
// sub FRUs.
for (const auto& [l_objectPath, l_serviceInterfaceMap] :
l_subTreeMap)
{
types::InterfaceMap l_interfaceMap;
vpdSpecificUtility::resetDataUnderPIM(l_objectPath,
l_interfaceMap);
l_objectMap.emplace(l_objectPath,
std::move(l_interfaceMap));
}

types::InterfaceMap l_interfaceMap;
vpdSpecificUtility::resetDataUnderPIM(i_dbusObjPath,
l_interfaceMap);

l_objectMap.emplace(i_dbusObjPath, std::move(l_interfaceMap));

if (!dbusUtility::callPIM(std::move(l_objectMap)))
{
throw std::runtime_error(
"Can't process delete VPD for FRU [" + i_dbusObjPath +
"] as unable to read present property");
}

if (jsonUtility::isActionRequired(m_parsedJson, l_fruPath,
"postAction", "deletion"))
{
if (!processPostAction(l_fruPath, "deletion"))
{
throw std::runtime_error("Post action failed");
}
}
}
}
else
{
logging::logMessage("DBus read failed");
return;
}

logging::logMessage("Successfully completed deletion of FRU VPD for " +
i_dbusObjPath);
}
catch (const std::exception& l_ex)
{
if (jsonUtility::isActionRequired(m_parsedJson, l_fruPath,
"postFailAction", "deletion"))
{
if (!jsonUtility::executePostFailAction(m_parsedJson, l_fruPath,
"deletion"))
{
logging::logMessage("Post fail action failed for: " +
i_dbusObjPath);
}
}

logging::logMessage("Failed to delete VPD for FRU : " + i_dbusObjPath +
" error: " + std::string(l_ex.what()));
}
}
} // namespace vpd

0 comments on commit e50d032

Please sign in to comment.