Prime the Inventory VPD objects
At the time of collecting the system vpd, prime those non system vpd
inventory objects by populating only certain properites of the objects
(like - Location code, Type interface and the inventory object).
Test:
Tested on simics by adding a missing fru in inventory json
and introspecting it to get the primed version of the object.
Output:
root@rainier:/tmp# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/dasd_card_pyramid0
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
com.ibm.ipzvpd.Location interface - - -
.LocationCode property s "U78DA.ND1.1234567-P1" emits-change writable
org.freedesktop.DBus.Introspectable interface - - -
.Introspect method - s -
org.freedesktop.DBus.Peer interface - - -
.GetMachineId method - s -
.Ping method - - -
org.freedesktop.DBus.Properties interface - - -
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
xyz.openbmc_project.Inventory.Item.DiskBackplane interface - - -
Tested in conjunction with this commit
<https://gerrit.openbmc-project.xyz/c/openbmc/meta-ibm/+/31821>
Change-Id: I4bf44e47b7cd1206555c42de43002c6aa8424517
Signed-off-by: Priyanga Ramasamy <priyanga24@in.ibm.com>
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index 4100d83..4c3aba4 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -85,7 +85,6 @@
}
return expanded;
}
-
/**
* @brief Populate FRU specific interfaces.
*
@@ -200,11 +199,74 @@
}
/**
- * @brief Populate Dbus.
+ * @brief Prime the Inventory
+ * Prime the inventory by populating only the location code,
+ * type interface and the inventory object for the frus
+ * which are not system vpd fru.
*
+ * @param[in] jsObject - Reference to vpd inventory json object
+ * @param[in] vpdMap - Reference to the parsed vpd map
+ *
+ * @returns Map of items in extraInterface.
+ */
+template <typename T>
+inventory::ObjectMap primeInventory(const nlohmann::json& jsObject,
+ const T& vpdMap)
+{
+ inventory::ObjectMap objects;
+
+ for (auto& itemFRUS : jsObject["frus"].items())
+ {
+ for (auto& itemEEPROM : itemFRUS.value())
+ {
+ inventory::InterfaceMap interfaces;
+ auto isSystemVpd = itemEEPROM.value("isSystemVpd", false);
+ inventory::Object object(itemEEPROM.at("inventoryPath"));
+
+ if (!isSystemVpd && !itemEEPROM.value("noprime", false))
+ {
+ if (itemEEPROM.find("extraInterfaces") != itemEEPROM.end())
+ {
+ for (const auto& eI : itemEEPROM["extraInterfaces"].items())
+ {
+ inventory::PropertyMap props;
+ if (eI.key() ==
+ openpower::vpd::constants::LOCATION_CODE_INF)
+ {
+ if constexpr (std::is_same<T, Parsed>::value)
+ {
+ for (auto& lC : eI.value().items())
+ {
+ auto propVal = expandLocationCode(
+ lC.value().get<string>(), vpdMap, true);
+
+ props.emplace(move(lC.key()),
+ move(propVal));
+ interfaces.emplace(move(eI.key()),
+ move(props));
+ }
+ }
+ }
+ else if (eI.key().find("Inventory.Item.") !=
+ string::npos)
+ {
+ interfaces.emplace(move(eI.key()), move(props));
+ }
+ }
+ }
+ objects.emplace(move(object), move(interfaces));
+ }
+ }
+ }
+ return objects;
+}
+
+/**
+ * @brief Populate Dbus.
* This method invokes all the populateInterface functions
* and notifies PIM about dbus object.
- * @param[in] vpdMap - Either IPZ vpd map or Keyword vpd map based on the input.
+ * @param[in] vpdMap - Either IPZ vpd map or Keyword vpd map based on the
+ * input.
* @param[in] js - Inventory json object
* @param[in] filePath - Path of the vpd file
* @param[in] preIntrStr - Interface string
@@ -217,11 +279,12 @@
inventory::ObjectMap objects;
inventory::PropertyMap prop;
+ bool isSystemVpd;
for (const auto& item : js["frus"][filePath])
{
const auto& objectPath = item["inventoryPath"];
sdbusplus::message::object_path object(objectPath);
- auto isSystemVpd = item.value("isSystemVpd", false);
+ isSystemVpd = item.value("isSystemVpd", false);
// Populate the VPD keywords and the common interfaces only if we
// are asked to inherit that data from the VPD, else only add the
// extraInterfaces.
@@ -229,8 +292,9 @@
{
if constexpr (std::is_same<T, Parsed>::value)
{
- // Each record in the VPD becomes an interface and all keyword
- // within the record are properties under that interface.
+ // Each record in the VPD becomes an interface and all
+ // keyword within the record are properties under that
+ // interface.
for (const auto& record : vpdMap)
{
populateFruSpecificInterfaces(
@@ -269,7 +333,8 @@
}
// Populate interfaces and properties that are common to every FRU
- // and additional interface that might be defined on a per-FRU basis.
+ // and additional interface that might be defined on a per-FRU
+ // basis.
if (item.find("extraInterfaces") != item.end())
{
populateInterfaces(item["extraInterfaces"], interfaces, vpdMap,
@@ -278,6 +343,12 @@
objects.emplace(move(object), move(interfaces));
}
+ if (isSystemVpd)
+ {
+ inventory::ObjectMap primeObject = primeInventory(js, vpdMap);
+ objects.insert(primeObject.begin(), primeObject.end());
+ }
+
// Notify PIM
inventory::callPIM(move(objects));
}