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/src/worker.cpp b/vpd-manager/src/worker.cpp index 2021b6b8..ef94bb7e 100644 --- a/vpd-manager/src/worker.cpp +++ b/vpd-manager/src/worker.cpp @@ -852,6 +852,14 @@ bool Worker::primeInventory(const std::string& i_vpdFilePath) processFunctionalProperty(l_Fru["inventoryPath"], l_interfaces); processEnabledProperty(l_Fru["inventoryPath"], l_interfaces); + // Emplace the default state of FRU VPD collection + types::PropertyMap l_fruCollectionProperty = { + {"CollectionStatus", constants::vpdCollectionNotStarted}}; + + vpdSpecificUtility::insertOrMerge(l_interfaces, + constants::vpdCollectionInterface, + std::move(l_fruCollectionProperty)); + l_objectInterfaceMap.emplace(std::move(l_fruObjectPath), std::move(l_interfaces)); } @@ -1102,6 +1110,7 @@ void Worker::populateDbus(const types::VPDMapVariant& parsedVpdMap, { const auto& inventoryPath = aFru["inventoryPath"]; sdbusplus::message::object_path fruObjectPath(inventoryPath); + if (aFru.contains("ccin")) { if (!processFruWithCCIN(aFru, parsedVpdMap)) @@ -1138,6 +1147,14 @@ void Worker::populateDbus(const types::VPDMapVariant& parsedVpdMap, processFunctionalProperty(inventoryPath, interfaces); processEnabledProperty(inventoryPath, interfaces); + // Update collection status as successful + types::PropertyMap l_collectionProperty = { + {"CollectionStatus", constants::vpdCollectionSuccess}}; + + vpdSpecificUtility::insertOrMerge(interfaces, + constants::vpdCollectionInterface, + std::move(l_collectionProperty)); + objectInterfaceMap.emplace(std::move(fruObjectPath), std::move(interfaces)); } @@ -1374,7 +1391,6 @@ types::VPDMapVariant Worker::parseVpdFile(const std::string& i_vpdFilePath) std::shared_ptr vpdParser = std::make_shared(i_vpdFilePath, m_parsedJson); - types::VPDMapVariant l_parsedVpd = vpdParser->parse(); // Before returning, as collection is over, check if FRU qualifies for @@ -1420,6 +1436,9 @@ types::VPDMapVariant Worker::parseVpdFile(const std::string& i_vpdFilePath) std::tuple Worker::parseAndPublishVPD(const std::string& i_vpdFilePath) { + const std::string& l_inventoryPath = + jsonUtility::getInventoryObjPathFromJson(m_parsedJson, i_vpdFilePath); + try { m_semaphore.acquire(); @@ -1429,6 +1448,24 @@ std::tuple m_activeCollectionThreadCount++; m_mutex.unlock(); + // Set CollectionStatus as InProgress. Since it's an intermediate state + // D-bus set-property call is good enough to update the status. + try + { + const std::string& l_collStatusProp = "CollectionStatus"; + dbusUtility::writeDbusProperty( + jsonUtility::getServiceName(m_parsedJson, l_inventoryPath), + l_inventoryPath, constants::vpdCollectionInterface, + l_collStatusProp, + types::DbusVariantType{constants::vpdCollectionInProgress}); + } + catch (const std::exception& e) + { + logging::logMessage( + "Unable to set CollectionStatus as InProgress for " + + i_vpdFilePath); + } + const types::VPDMapVariant& parsedVpdMap = parseVpdFile(i_vpdFilePath); types::ObjectMap objectInterfaceMap; @@ -1468,14 +1505,32 @@ std::tuple logging::logMessage(ex.what()); } + // update CollectionStatus as Failure + types::ObjectMap l_objectMap; + types::InterfaceMap l_interfaceMap; + types::PropertyMap l_propertyMap; + + l_propertyMap.emplace("CollectionStatus", + constants::vpdCollectionFailure); + l_interfaceMap.emplace(constants::vpdCollectionInterface, + l_propertyMap); + l_objectMap.emplace(l_inventoryPath, l_interfaceMap); + + if (!dbusUtility::callPIM(std::move(l_objectMap))) + { + logging::logMessage( + "Call to PIM Notify method failed to update Collection status as Failure for " + + i_vpdFilePath); + } + // TODO: Figure out a way to clear data in case of any failure at // runtime. // Prime the inventry for FRUs which // are not present/processing had some error. /* if (!primeInventory(i_vpdFilePath)) { - logging::logMessage("Priming of inventory failed for FRU " + - i_vpdFilePath); + logging::logMessage("Priming of inventory failed for FRU " + + i_vpdFilePath); }*/ m_semaphore.release(); return std::make_tuple(false, i_vpdFilePath);