API to check powerVS configuration
The commit implements change to check for powerVS configuration.
It is a combination of system series and driver running on the system.
Once that is established, only after that VPD vpdate will take place
w.r.t powerVS system.
Change-Id: I93fefcb79ced4f89bd6f5143666b4cd487897ac8
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
diff --git a/vpd-manager/include/constants.hpp b/vpd-manager/include/constants.hpp
index f7e55d0..9358f78 100644
--- a/vpd-manager/include/constants.hpp
+++ b/vpd-manager/include/constants.hpp
@@ -113,6 +113,11 @@
// Zero based index position of first EQ in CP00's PG keyword
static constexpr auto INDEX_OF_EQ0_IN_PG = 97;
+static constexpr auto HEX_VALUE_50 = 0x50;
+static constexpr auto HEX_VALUE_30 = 0x30;
+static constexpr auto HEX_VALUE_10 = 0x10;
+static constexpr auto HEX_VALUE_00 = 0x00;
+
constexpr auto systemInvPath = "/xyz/openbmc_project/inventory/system";
constexpr auto pimPath = "/xyz/openbmc_project/inventory";
constexpr auto pimIntf = "xyz.openbmc_project.Inventory.Manager";
@@ -161,6 +166,19 @@
constexpr auto hostService = "xyz.openbmc_project.State.Host";
constexpr auto hostRunningState =
"xyz.openbmc_project.State.Host.HostState.Running";
+constexpr auto imageUpdateService = "xyz.openbmc_project.Software.BMC.Updater";
+constexpr auto imagePrirotyInf =
+ "xyz.openbmc_project.Software.RedundancyPriority";
+constexpr auto imageExtendedVerInf =
+ "xyz.openbmc_project.Software.ExtendedVersion";
+constexpr auto functionalImageObjPath =
+ "/xyz/openbmc_project/software/functional";
+constexpr auto associationInterface = "xyz.openbmc_project.Association";
+constexpr auto powerVsImagePrefix_MY = "MY";
+constexpr auto powerVsImagePrefix_MZ = "MZ";
+constexpr auto powerVsImagePrefix_NY = "NY";
+constexpr auto powerVsImagePrefix_NZ = "NZ";
+
static constexpr auto BD_YEAR_END = 4;
static constexpr auto BD_MONTH_END = 7;
static constexpr auto BD_DAY_END = 10;
diff --git a/vpd-manager/include/utility/dbus_utility.hpp b/vpd-manager/include/utility/dbus_utility.hpp
index d13e123..344a637 100644
--- a/vpd-manager/include/utility/dbus_utility.hpp
+++ b/vpd-manager/include/utility/dbus_utility.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "constants.hpp"
+#include "exceptions.hpp"
#include "logger.hpp"
#include "types.hpp"
@@ -607,5 +608,82 @@
return *l_imValue;
}
+
+/**
+ * @brief API to return prefix of functional firmware image.
+ *
+ * Every functional image belongs to a series which is denoted by the first two
+ * characters of the image name. The API extracts that and returns it to the
+ * caller.
+ *
+ * @return Two character string, empty string in case of any error.
+ */
+inline std::string getImagePrefix()
+{
+ try
+ {
+ types::DbusVariantType l_retVal = readDbusProperty(
+ constants::objectMapperService, constants::functionalImageObjPath,
+ constants::associationInterface, "endpoints");
+
+ auto l_listOfFunctionalPath =
+ std::get_if<std::vector<std::string>>(&l_retVal);
+
+ if (!l_listOfFunctionalPath || (*l_listOfFunctionalPath).empty())
+ {
+ throw DbusException("failed to get functional image path.");
+ }
+
+ for (const auto& l_imagePath : *l_listOfFunctionalPath)
+ {
+ types::DbusVariantType l_retValPriority =
+ readDbusProperty(constants::imageUpdateService, l_imagePath,
+ constants::imagePrirotyInf, "Priority");
+
+ auto l_imagePriority = std::get_if<uint8_t>(&l_retValPriority);
+ if (!l_imagePriority)
+ {
+ throw DbusException(
+ "failed to read functional image priority for path [" +
+ l_imagePath + "]");
+ }
+
+ // only interested in running image.
+ if (*l_imagePriority != constants::VALUE_0)
+ {
+ continue;
+ }
+
+ types::DbusVariantType l_retExVer = readDbusProperty(
+ constants::imageUpdateService, l_imagePath,
+ constants::imageExtendedVerInf, "ExtendedVersion");
+
+ auto l_imageExtendedVersion = std::get_if<std::string>(&l_retExVer);
+ if (!l_imageExtendedVersion)
+ {
+ throw DbusException(
+ "Unable to read extended version for the functional image [" +
+ l_imagePath + "]");
+ }
+
+ if ((*l_imageExtendedVersion).empty() ||
+ (*l_imageExtendedVersion).length() <= constants::VALUE_2)
+ {
+ throw DbusException("Invalid extended version read for path [" +
+ l_imagePath + "]");
+ }
+
+ // return first two character from image name.
+ return (*l_imageExtendedVersion)
+ .substr(constants::VALUE_0, constants::VALUE_2);
+ }
+ throw std::runtime_error("No Image found with required priority.");
+ }
+ catch (const std::exception& l_ex)
+ {
+ logging::logMessage(l_ex.what());
+ return std::string{};
+ }
+}
} // namespace dbusUtility
} // namespace vpd
diff --git a/vpd-manager/include/utility/vpd_specific_utility.hpp b/vpd-manager/include/utility/vpd_specific_utility.hpp
index 83db199..4fc553d 100644
--- a/vpd-manager/include/utility/vpd_specific_utility.hpp
+++ b/vpd-manager/include/utility/vpd_specific_utility.hpp
@@ -687,5 +687,45 @@
return l_rc;
}
+
+/**
+ * @brief API to detect if system configuration is that of PowerVS system.
+ *
+ * @param[in] i_imValue - IM value of the system.
+ * @return true if it is PowerVS configuration, false otherwise.
+ */
+inline bool isPowerVsConfiguration(const types::BinaryVector& i_imValue)
+{
+ if (i_imValue.empty() || i_imValue.size() != constants::VALUE_4)
+ {
+ return false;
+ }
+
+ // Should be a 0x5000XX series system.
+ if (i_imValue.at(0) == constants::HEX_VALUE_50 &&
+ i_imValue.at(1) == constants::HEX_VALUE_00)
+ {
+ std::string l_imagePrefix = dbusUtility::getImagePrefix();
+
+ // Check image for 0x500030XX series.
+ if ((i_imValue.at(2) == constants::HEX_VALUE_30) &&
+ ((l_imagePrefix == constants::powerVsImagePrefix_MY) ||
+ (l_imagePrefix == constants::powerVsImagePrefix_NY)))
+ {
+ logging::logMessage("PowerVS configuration");
+ return true;
+ }
+
+ // Check image for 0X500010XX series.
+ if ((i_imValue.at(2) == constants::HEX_VALUE_10) &&
+ ((l_imagePrefix == constants::powerVsImagePrefix_MZ) ||
+ (l_imagePrefix == constants::powerVsImagePrefix_NZ)))
+ {
+ logging::logMessage("PowerVS configuration");
+ return true;
+ }
+ }
+ return false;
+}
} // namespace vpdSpecificUtility
} // namespace vpd
diff --git a/vpd-manager/src/manager.cpp b/vpd-manager/src/manager.cpp
index eca1588..b608e0b 100644
--- a/vpd-manager/src/manager.cpp
+++ b/vpd-manager/src/manager.cpp
@@ -335,6 +335,13 @@
{
throw DbusException("Invalid IM value read from Dbus");
}
+
+ if (!vpdSpecificUtility::isPowerVsConfiguration(l_imValue))
+ {
+ // TODO: Should booting be blocked in case of some
+ // misconfigurations?
+ return;
+ }
}
catch (const std::exception& l_ex)
{