diff --git a/vpd-manager/include/constants.hpp b/vpd-manager/include/constants.hpp index e20a46b6..7ea8d554 100644 --- a/vpd-manager/include/constants.hpp +++ b/vpd-manager/include/constants.hpp @@ -187,5 +187,17 @@ 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 vpdCollectionInterface = "com.ibm.VPD.Collection"; + +// enumerated values of CollectionStatus D-bus property defined under +// com.ibm.VPD.Collection interface. +static constexpr auto vpdCollectionSuccess = + "com.ibm.VPD.Collection.Status.Success"; +static constexpr auto vpdCollectionFailure = + "com.ibm.VPD.Collection.Status.Failure"; +static constexpr auto vpdCollectionInProgress = + "com.ibm.VPD.Collection.Status.InProgress"; +static constexpr auto vpdCollectionNotStarted = + "com.ibm.VPD.Collection.Status.NotStarted"; } // namespace constants } // namespace vpd diff --git a/vpd-manager/include/utility/dbus_utility.hpp b/vpd-manager/include/utility/dbus_utility.hpp index 0567ab70..c2621957 100644 --- a/vpd-manager/include/utility/dbus_utility.hpp +++ b/vpd-manager/include/utility/dbus_utility.hpp @@ -454,5 +454,31 @@ inline bool isBMCReady() return false; } + +/** + * @brief API to set status of FRU VPD collection on D-bus. + * + * This API is to set value of CollectionStatus property hosted under + * com.ibm.VPD.Collection interface for the given FRU's inventory object. + * + * @param[in] i_invObjPath - D-bus inventory object path. + * @param[in] i_fruVpdCollectionStatus - FRU VPD collection status. + * + * @return true if given status is set successfully, false otherwise. + */ +inline bool + setFruVpdCollectionStatus(const std::string& i_invObjPath, + const std::string& i_fruVpdCollectionStatus) +{ + types::ObjectMap l_objectMap; + types::InterfaceMap l_interfaceMap; + types::PropertyMap l_propertyMap; + + l_propertyMap.emplace("CollectionStatus", i_fruVpdCollectionStatus); + l_interfaceMap.emplace(constants::vpdCollectionInterface, l_propertyMap); + l_objectMap.emplace(i_invObjPath, l_interfaceMap); + + return callPIM(std::move(l_objectMap)); +} } // namespace dbusUtility } // namespace vpd diff --git a/vpd-manager/include/worker.hpp b/vpd-manager/include/worker.hpp index 7689aea4..b2bd79a3 100644 --- a/vpd-manager/include/worker.hpp +++ b/vpd-manager/include/worker.hpp @@ -469,6 +469,19 @@ class Worker void processEnabledProperty(const std::string& i_inventoryObjPath, types::InterfaceMap& io_interfaces); + /** + * @brief API to process FRU VPD Collection status. + * + * This API sets the given FRU VPD collection status to the given interface + * map. + * + * @param[in,out] io_interfaces - Map which holds FRU's interfaces and its + * properties. + * @param[in] i_fruCollectionStatus - FRU VPD collection status. + */ + void processFRUCollectionStatus(types::InterfaceMap& io_interfaces, + const std::string& i_fruCollectionStatus); + /** * @brief API to form asset tag string for the system. * diff --git a/vpd-manager/src/manager.cpp b/vpd-manager/src/manager.cpp index 5169f659..7e9ef80a 100644 --- a/vpd-manager/src/manager.cpp +++ b/vpd-manager/src/manager.cpp @@ -387,6 +387,7 @@ types::DbusVariantType void Manager::collectSingleFruVpd( const sdbusplus::message::object_path& i_dbusObjPath) { + std::string l_fruPath{}; try { if (m_vpdCollectionStatus != "Completed") @@ -413,8 +414,8 @@ void Manager::collectSingleFruVpd( } // Get FRU path for the given D-bus object path from JSON - const std::string& l_fruPath = - jsonUtility::getFruPathFromJson(l_sysCfgJsonObj, i_dbusObjPath); + l_fruPath = jsonUtility::getFruPathFromJson(l_sysCfgJsonObj, + i_dbusObjPath); if (l_fruPath.empty()) { @@ -447,6 +448,16 @@ void Manager::collectSingleFruVpd( } } + // Set CollectionStatus as InProgress before performing single FRU VPD + // collection + if (!dbusUtility::setFruVpdCollectionStatus( + i_dbusObjPath, constants::vpdCollectionInProgress)) + { + logging::logMessage( + "Unable to set CollectionStatus as InProgress for " + + std::string(i_dbusObjPath) + ". Continue collecting VPD."); + } + // Parse VPD types::VPDMapVariant l_parsedVpd = m_worker->parseVpdFile(l_fruPath); @@ -480,6 +491,21 @@ void Manager::collectSingleFruVpd( { // TODO: Log PEL logging::logMessage(std::string(l_error.what())); + + std::string l_collectionStatus = constants::vpdCollectionFailure; + + if (!std::filesystem::exists(l_fruPath)) + { + l_collectionStatus = constants::vpdCollectionNotStarted; + } + + if (!dbusUtility::setFruVpdCollectionStatus(i_dbusObjPath, + l_collectionStatus)) + { + logging::logMessage("Unable to set CollectionStatus as " + + l_collectionStatus + " for " + + std::string(i_dbusObjPath)); + } } } diff --git a/vpd-manager/src/worker.cpp b/vpd-manager/src/worker.cpp index 2021b6b8..fe63604d 100644 --- a/vpd-manager/src/worker.cpp +++ b/vpd-manager/src/worker.cpp @@ -833,9 +833,20 @@ bool Worker::primeInventory(const std::string& i_vpdFilePath) types::PropertyMap l_propertyValueMap; l_propertyValueMap.emplace("Present", false); + if (std::filesystem::exists(i_vpdFilePath)) { l_propertyValueMap["Present"] = true; + + // FRU exist and if we hit prime inventory path + processFRUCollectionStatus(l_interfaces, + constants::vpdCollectionFailure); + } + else + { + // FRU doesn't exist and if we hit prime inventory path + processFRUCollectionStatus(l_interfaces, + constants::vpdCollectionNotStarted); } vpdSpecificUtility::insertOrMerge(l_interfaces, @@ -1138,6 +1149,10 @@ void Worker::populateDbus(const types::VPDMapVariant& parsedVpdMap, processFunctionalProperty(inventoryPath, interfaces); processEnabledProperty(inventoryPath, interfaces); + // FRU VPD collection is successful + processFRUCollectionStatus(interfaces, + constants::vpdCollectionSuccess); + objectInterfaceMap.emplace(std::move(fruObjectPath), std::move(interfaces)); } @@ -1470,13 +1485,13 @@ std::tuple // TODO: Figure out a way to clear data in case of any failure at // runtime. - // Prime the inventry for FRUs which + // Prime the inventory for FRUs which // are not present/processing had some error. - /* if (!primeInventory(i_vpdFilePath)) - { - logging::logMessage("Priming of inventory failed for FRU " + - i_vpdFilePath); - }*/ + if (!primeInventory(i_vpdFilePath)) + { + logging::logMessage("Priming of inventory failed for FRU " + + i_vpdFilePath); + } m_semaphore.release(); return std::make_tuple(false, i_vpdFilePath); } @@ -1683,4 +1698,15 @@ void Worker::deleteFruVpd(const std::string& i_dbusObjPath) " error: " + std::string(l_ex.what())); } } + +void Worker::processFRUCollectionStatus( + types::InterfaceMap& io_interfaces, + const std::string& i_fruCollectionStatus) +{ + types::PropertyMap l_fruCollectionProperty = { + {"CollectionStatus", i_fruCollectionStatus}}; + vpdSpecificUtility::insertOrMerge(io_interfaces, + constants::vpdCollectionInterface, + std::move(l_fruCollectionProperty)); +} } // namespace vpd