Back up and Restore update
The commit updates the flow of Back up and Restore of system VPD.
Updates:
- Removing call_out_inventory_path tag from the PEL create call
in case there is any issue while backup or restore.
This was done to avoid any calls from phosphor-logging to
VPD-Manager at this stage as Manager service is not up at this
point resulting in a D-Bus call failure.
- Removing dupicate code as and where possible in the flow.
The commit is an extension of following commit:
https://gerrit.openbmc.org/c/openbmc/openpower-vpd-parser/+/62250/
Tests:
PEL was created duringthe flow and confirmed that there was no
call to VPD-Manager from phosphor-logging.
Tested for all te scenarios w.r.t backup and restore of system
VPD.
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
Change-Id: I92779247438bf50d907fd7f60ed94dda6fadb2a0
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index 9799982..8acb03a 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -44,6 +44,21 @@
using namespace openpower::vpd::manager::editor;
/**
+ * @brief API declaration, 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] js - Inventory json object
+ * @param[in] filePath - Path of the vpd file
+ * @param[in] preIntrStr - Interface string
+ */
+template <typename T>
+static void populateDbus(T& vpdMap, nlohmann::json& js, const string& filePath);
+
+/**
* @brief Returns the BMC state
*/
static auto getBMCState()
@@ -859,14 +874,11 @@
* @brief Parse the given EEPROM file.
*
* @param[in] vpdFilePath - Path of EEPROM file
- * @param[in] invPath - Path of inventory object
* @param[in] js- Reference to vpd inventory json object
- *
* @return Parsed VPD map
*/
std::variant<KeywordVpdMap, openpower::vpd::Store>
- parseVpdFile(const std::string& vpdFilePath, const std::string& invPath,
- const nlohmann::json& js)
+ parseVpdFile(const std::string& vpdFilePath, const nlohmann::json& js)
{
uint32_t vpdStartOffset = 0;
for (const auto& item : js["frus"][vpdFilePath])
@@ -874,13 +886,17 @@
if (item.find("offset") != item.end())
{
vpdStartOffset = item["offset"];
+ break;
}
}
Binary vpdVector = getVpdDataInVector(js, vpdFilePath);
ParserInterface* parser = ParserFactory::getParser(
- vpdVector, (pimPath + invPath), vpdFilePath, vpdStartOffset);
+ vpdVector,
+ (pimPath + js["frus"][vpdFilePath][0]["inventoryPath"]
+ .get_ref<const nlohmann::json::string_t&>()),
+ vpdFilePath, vpdStartOffset);
auto parseResult = parser->parse();
@@ -921,13 +937,17 @@
}
else
{
- auto backupVpdParsedResult = parseVpdFile(systemVpdBackupPath,
- backupVpdInvPath, js);
+ auto backupVpdParsedResult = parseVpdFile(systemVpdBackupPath, js);
if (auto pVal = get_if<Store>(&backupVpdParsedResult))
{
backupVpdMap = pVal->getVpdMap();
}
+ else
+ {
+ std::cerr << "Invalid format of VPD in back up. Restore aborted."
+ << std::endl;
+ }
}
}
@@ -960,135 +980,6 @@
}
/**
- * @brief Populate base panel object on dbus.
-
- * This method invokes all the populateInterface functions
- * and notifies PIM about base panel dbus object.
-
- * @param[in] vpdMap - Base panel vpd map in IPZ format
- * @param[in] js - Inventory json object
- * @param[in] filePath - Path of the base panel vpd file
- */
-void populateBasePanelObjectOnDBus(const Parsed& vpdMap, nlohmann::json& js,
- const string& filePath)
-{
- inventory::InterfaceMap interfaces;
- inventory::ObjectMap objects;
- inventory::PropertyMap prop;
-
- string ccinFromVpd = getKwVal(vpdMap, "VINI", "CC");
- transform(ccinFromVpd.begin(), ccinFromVpd.end(), ccinFromVpd.begin(),
- ::toupper);
-
- for (const auto& item : js["frus"][filePath])
- {
- const auto& objectPath = item["inventoryPath"];
- sdbusplus::message::object_path object(objectPath);
-
- vector<string> ccinList;
- if (item.find("ccin") != item.end())
- {
- for (const auto& cc : item["ccin"])
- {
- string ccin = cc;
- transform(ccin.begin(), ccin.end(), ccin.begin(), ::toupper);
- ccinList.push_back(ccin);
- }
- }
-
- if (!ccinFromVpd.empty() && !ccinList.empty() &&
- (find(ccinList.begin(), ccinList.end(), ccinFromVpd) ==
- ccinList.end()))
- {
- continue;
- }
-
- if ((item.value("noprime", false)))
- {
- // Populate one time properties for non-primeable frus.
- // For the remaining FRUs, this will get handled as a part of
- // priming the inventory.
- setOneTimeProperties(objectPath, interfaces);
- }
-
- // 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.
- if (item.value("inherit", true))
- {
- // 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(
- record.second, ipzVpdInf + record.first, interfaces);
- }
-
- if (js.find("commonInterfaces") != js.end())
- {
- populateInterfaces(js["commonInterfaces"], interfaces, vpdMap,
- false);
- }
- }
- else
- {
- // Check if we have been asked to inherit specific record(s)
- if (item.find("copyRecords") != item.end())
- {
- for (const auto& record : item["copyRecords"])
- {
- const string& recordName = record;
- if (vpdMap.find(recordName) != vpdMap.end())
- {
- populateFruSpecificInterfaces(vpdMap.at(recordName),
- ipzVpdInf + recordName,
- interfaces);
- }
- }
- }
- }
-
- // Populate interfaces and properties that are common to every FRU
- // and additional interface that might be defined on a per-FRU
- // basis.
- if (item.find("extraInterfaces") != item.end())
- {
- populateInterfaces(item["extraInterfaces"], interfaces, vpdMap,
- false);
- }
-
- // embedded property(true or false) says whether the subfru is embedded
- // into the parent fru (or) not. VPD sets Present property only for
- // embedded frus. If the subfru is not an embedded FRU, the subfru may
- // or may not be physically present. Those non embedded frus will always
- // have Present=false irrespective of its physical presence or absence.
- // Eg: nvme drive in nvme slot is not an embedded FRU. So don't set
- // Present to true for such sub frus.
- // Eg: ethernet port is embedded into bmc card. So set Present to true
- // for such sub frus. Also donot populate present property for embedded
- // subfru which is synthesized. Currently there is no subfru which are
- // both embedded and synthesized. But still the case is handled here.
- if ((item.value("embedded", true)) &&
- (!item.value("synthesized", false)))
- {
- // Check if its required to handle presence for this FRU.
- if (item.value("handlePresence", true))
- {
- inventory::PropertyMap presProp;
- presProp.emplace("Present", true);
- insertOrMerge(interfaces, invItemIntf, move(presProp));
- }
- }
-
- objects.emplace(move(object), move(interfaces));
- }
-
- // Notify PIM
- common::utility::callPIM(move(objects));
-}
-
-/**
* @brief API to check if we need to restore system VPD
* This functionality is only applicable for IPZ VPD data.
@@ -1118,6 +1009,7 @@
if (backupVpdMap.empty())
{
+ std::cerr << "Backup VPD map is empty" << std::endl;
return;
}
}
@@ -1158,52 +1050,35 @@
}
else
{
- auto recItr = backupVpdMap.find(backupVpdRecName);
- if (recItr != backupVpdMap.end())
+ backupValue = getKwVal(backupVpdMap, backupVpdRecName,
+ backupVpdKwName);
+
+ if (backupValue.empty())
{
- string errorMsg = backupVpdRecName +
- " Record does not exist in "
- "the EEPROM file ";
+ string errorMsg{};
+ if (backupVpdMap.find(backupVpdRecName) ==
+ backupVpdMap.end())
+ {
+ errorMsg = backupVpdRecName +
+ " Record does not exist in "
+ "the EEPROM file ";
+ }
+ else
+ {
+ errorMsg = backupVpdKwName +
+ " Keyword not found or empty.";
+ }
errorMsg += systemVpdBackupPath;
PelAdditionalData additionalData;
additionalData.emplace("DESCRIPTION", errorMsg);
- additionalData.emplace("CALLOUT_INVENTORY_PATH",
- INVENTORY_PATH +
- backupVpdInvPath);
-
createPEL(additionalData, PelSeverity::ERROR,
errIntfForInvalidVPD, nullptr);
continue;
}
- else
- {
- backupValue = getKwVal(backupVpdMap,
- backupVpdRecName,
- backupVpdKwName);
- if (backupValue.empty())
- {
- string errorMsg = backupVpdKwName +
- " Keyword not found in "
- "the backup VPD file ";
-
- errorMsg += systemVpdBackupPath;
-
- PelAdditionalData additionalData;
- additionalData.emplace("DESCRIPTION", errorMsg);
-
- additionalData.emplace("CALLOUT_INVENTORY_PATH",
- INVENTORY_PATH +
- backupVpdInvPath);
-
- createPEL(additionalData, PelSeverity::ERROR,
- errIntfForInvalidVPD, nullptr);
- continue;
- }
- }
}
Binary backupDataInBinary(backupValue.begin(),
@@ -1242,9 +1117,6 @@
// data mismatch
PelAdditionalData additionalData;
- additionalData.emplace("CALLOUT_INVENTORY_PATH",
- INVENTORY_PATH +
- objectPath);
additionalData.emplace("DESCRIPTION", errMsg);
additionalData.emplace(
@@ -1267,6 +1139,13 @@
continue;
}
}
+ else
+ {
+ // both the backup and primary data is
+ // non-default and same. Nothing needs to be
+ // done.
+ continue;
+ }
}
// If the backup is on the cache we need to copy the
@@ -1299,16 +1178,12 @@
errMsg += (*it).first;
errMsg += " and keyword: ";
errMsg += keywordName;
- errMsg += ". SSR need to update primary VPD.";
+ errMsg += ". Update primary VPD.";
// mfg default on both backup and primary, log PEL
PelAdditionalData additionalData;
- additionalData.emplace("CALLOUT_INVENTORY_PATH",
- INVENTORY_PATH + objectPath);
-
additionalData.emplace("DESCRIPTION", errMsg);
- // log PEL TODO: Block IPL
createPEL(additionalData, PelSeverity::ERROR,
errIntfForVPDDefault, nullptr);
@@ -1332,11 +1207,6 @@
}
}
}
-
- if (!isBackupOnCache)
- {
- populateBasePanelObjectOnDBus(backupVpdMap, js, systemVpdBackupPath);
- }
}
/**
@@ -1895,8 +1765,7 @@
try
{
variant<KeywordVpdMap, Store> parseResult;
-
- parseResult = parseVpdFile(file, baseFruInventoryPath, js);
+ parseResult = parseVpdFile(file, js);
if (isSystemVpd)
{
@@ -1923,6 +1792,12 @@
}
catch (const exception& e)
{
+ if (!systemVpdBackupPath.empty())
+ {
+ file = systemVpdBackupPath;
+ baseFruInventoryPath = backupVpdInvPath;
+ }
+
executePostFailAction(js, file);
throw;
}
@@ -1938,11 +1813,6 @@
}
catch (const VpdEccException& ex)
{
- if (!systemVpdBackupPath.empty())
- {
- baseFruInventoryPath = backupVpdInvPath;
- }
-
additionalData.emplace("DESCRIPTION", "ECC check failed");
additionalData.emplace("CALLOUT_INVENTORY_PATH",
INVENTORY_PATH + baseFruInventoryPath);
@@ -1958,12 +1828,6 @@
}
catch (const VpdDataException& ex)
{
- if (!systemVpdBackupPath.empty())
- {
- file = systemVpdBackupPath;
- baseFruInventoryPath = backupVpdInvPath;
- }
-
if (isThisPcieOnPass1planar(js, file))
{
std::cout << "Pcie_device [" << file
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index cf3a798..d5d280c 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -672,6 +672,14 @@
{
kwVal = findKwd->second;
}
+ else
+ {
+ std::cout << "Keyword not found" << std::endl;
+ }
+ }
+ else
+ {
+ std::cerr << "Record not found" << std::endl;
}
return kwVal;
diff --git a/types.hpp b/types.hpp
index 6efdcfe..70defda 100644
--- a/types.hpp
+++ b/types.hpp
@@ -80,7 +80,6 @@
using IntfPropMap = std::map<RecordName, GetAllResultType>;
using RecKwValMap =
std::unordered_map<RecordName, std::unordered_map<Keyword, Binary>>;
-
} // namespace inventory
} // namespace vpd