summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRAJESWARAN THILLAIGOVINDAN <rajeswgo@in.ibm.com>2019-02-21 19:59:03 +0300
committerEd Tanous <ed.tanous@intel.com>2019-08-09 01:45:51 +0300
commitec8faf9243b6f6320daeb3ba6a94d1f257034506 (patch)
tree1f2a52e1096eab3ebba798f94c15de8edb458d6c
parent9d3ae10e0f1b7a694678ef6b4b051a3d9836307f (diff)
downloadbmcweb-ec8faf9243b6f6320daeb3ba6a94d1f257034506.tar.xz
Add CPU core count property
Read the core objects for the given CPU Id and report the count of core objects having the property "Present" set as true. Testing: 1.Ran Redfish schema validator - no issues 2.Ran GET request for cpu0 and cpu1 to get the total cores for verification. The total cores that are present reported by the Redfish output matches with the total cores reported by the inventory Rest API. curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${bmc}/redfish/v1/Systems/system/Processors/cpu0 { "@odata.context": "/redfish/v1/$metadata#Processor.Processor", "@odata.id": "/redfish/v1/Systems/system/Processors/cpu0", "@odata.type": "#Processor.v1_3_1.Processor", "Id": "cpu0", "InstructionSet": "PowerISA", "Manufacturer": "IBM", "Model": "", "Name": "Processor", "ProcessorArchitecture": "Power", "ProcessorType": "CPU", "Status": { "Health": "OK", "State": "Enabled" }, "TotalCores": 18 } Change-Id: I3d65daed42fafd85ae2e4659e764ac061f1b1626 Signed-off-by: RAJESWARAN THILLAIGOVINDAN <rajeswgo@in.ibm.com>
-rw-r--r--redfish-core/lib/cpudimm.hpp205
1 files changed, 149 insertions, 56 deletions
diff --git a/redfish-core/lib/cpudimm.hpp b/redfish-core/lib/cpudimm.hpp
index 263ef8e696..2e084d4481 100644
--- a/redfish-core/lib/cpudimm.hpp
+++ b/redfish-core/lib/cpudimm.hpp
@@ -18,11 +18,14 @@
#include <boost/container/flat_map.hpp>
#include <node.hpp>
#include <utils/json_utils.hpp>
-#include <variant>
namespace redfish
{
+using InterfacesProperties = boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>;
+
void getResourceList(std::shared_ptr<AsyncResp> aResp,
const std::string &subclass,
const std::vector<const char *> &collectionName)
@@ -63,32 +66,21 @@ void getResourceList(std::shared_ptr<AsyncResp> aResp,
"/xyz/openbmc_project/inventory", int32_t(0), collectionName);
}
-void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
- const std::string &cpuId, const std::string &service,
- const std::string &objPath)
+void getCpuDataByInterface(std::shared_ptr<AsyncResp> aResp,
+ const InterfacesProperties &cpuInterfacesProperties)
{
- BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
- crow::connections::systemBus->async_method_call(
- [cpuId, aResp{std::move(aResp)}](
- const boost::system::error_code ec,
- const boost::container::flat_map<
- std::string, std::variant<std::string, uint32_t, uint16_t>>
- &properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
- messages::internalError(aResp->res);
+ BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
- return;
- }
- aResp->res.jsonValue["Id"] = cpuId;
- aResp->res.jsonValue["Name"] = "Processor";
- const auto coresCountProperty =
- properties.find("ProcessorCoreCount");
- if (coresCountProperty != properties.end())
+ const bool *present = NULL;
+ const bool *functional = NULL;
+ for (const auto &interface : cpuInterfacesProperties)
+ {
+ for (const auto &property : interface.second)
+ {
+ if (property.first == "ProcessorCoreCount")
{
const uint16_t *coresCount =
- std::get_if<uint16_t>(&coresCountProperty->second);
+ std::get_if<uint16_t>(&property.second);
if (coresCount == nullptr)
{
// Important property not in desired type
@@ -106,53 +98,154 @@ void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
aResp->res.jsonValue["TotalCores"] = *coresCount;
}
-
- aResp->res.jsonValue["Status"]["State"] = "Enabled";
- aResp->res.jsonValue["Status"]["Health"] = "OK";
-
- for (const auto &property : properties)
+ else if (property.first == "ProcessorType")
{
- if (property.first == "ProcessorType")
- {
- aResp->res.jsonValue["Name"] = property.second;
- }
- else if (property.first == "ProcessorManufacturer")
+ aResp->res.jsonValue["Name"] = property.second;
+ }
+ else if (property.first == "Manufacturer")
+ {
+ const std::string *value =
+ std::get_if<std::string>(&property.second);
+ if (value != nullptr)
{
aResp->res.jsonValue["Manufacturer"] = property.second;
- const std::string *value =
- std::get_if<std::string>(&property.second);
- if (value != nullptr)
+ // Otherwise would be unexpected.
+ if (value->find("Intel") != std::string::npos)
{
- // Otherwise would be unexpected.
- if (value->find("Intel") != std::string::npos)
- {
- aResp->res.jsonValue["ProcessorArchitecture"] =
- "x86";
- aResp->res.jsonValue["InstructionSet"] = "x86-64";
- }
- else if (value->find("IBM") != std::string::npos)
- {
- aResp->res.jsonValue["ProcessorArchitecture"] =
- "Power";
- aResp->res.jsonValue["InstructionSet"] = "PowerISA";
- }
+ aResp->res.jsonValue["ProcessorArchitecture"] = "x86";
+ aResp->res.jsonValue["InstructionSet"] = "x86-64";
+ }
+ else if (value->find("IBM") != std::string::npos)
+ {
+ aResp->res.jsonValue["ProcessorArchitecture"] = "Power";
+ aResp->res.jsonValue["InstructionSet"] = "PowerISA";
}
}
- else if (property.first == "ProcessorMaxSpeed")
+ }
+ else if (property.first == "ProcessorMaxSpeed")
+ {
+ aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
+ }
+ else if (property.first == "ProcessorThreadCount")
+ {
+ aResp->res.jsonValue["TotalThreads"] = property.second;
+ }
+ else if (property.first == "Model")
+ {
+ const std::string *value =
+ std::get_if<std::string>(&property.second);
+ if (value != nullptr)
{
- aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
+ aResp->res.jsonValue["Model"] = *value;
}
- else if (property.first == "ProcessorThreadCount")
+ }
+ else if (property.first == "Present")
+ {
+ present = std::get_if<bool>(&property.second);
+ }
+ else if (property.first == "Functional")
+ {
+ functional = std::get_if<bool>(&property.second);
+ }
+ }
+ }
+
+ if ((present == nullptr) || (functional == nullptr))
+ {
+ // Important property not in desired type
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ if (*present == false)
+ {
+ aResp->res.jsonValue["Status"]["State"] = "Absent";
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
+ }
+ else
+ {
+ aResp->res.jsonValue["Status"]["State"] = "Enabled";
+ if (*functional == true)
+ {
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
+ }
+ else
+ {
+ aResp->res.jsonValue["Status"]["Health"] = "Critical";
+ }
+ }
+
+ return;
+}
+
+void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
+ const std::string &cpuId, const std::string &service,
+ const std::string &objPath)
+{
+ BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
+
+ crow::connections::systemBus->async_method_call(
+ [cpuId, service, objPath, aResp{std::move(aResp)}](
+ const boost::system::error_code ec,
+ const dbus::utility::ManagedObjectType &dbusData) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+ messages::internalError(aResp->res);
+ return;
+ }
+ aResp->res.jsonValue["Id"] = cpuId;
+ aResp->res.jsonValue["Name"] = "Processor";
+ aResp->res.jsonValue["ProcessorType"] = "CPU";
+
+ std::string corePath = objPath + "/core";
+ size_t totalCores = 0;
+ for (const auto &object : dbusData)
+ {
+ if (object.first.str == objPath)
{
- aResp->res.jsonValue["TotalThreads"] = property.second;
+ getCpuDataByInterface(aResp, object.second);
}
- else if (property.first == "ProcessorVersion")
+ else if (boost::starts_with(object.first.str, corePath))
{
- aResp->res.jsonValue["Model"] = property.second;
+ for (const auto &interface : object.second)
+ {
+ if (interface.first ==
+ "xyz.openbmc_project.Inventory.Item")
+ {
+ for (const auto &property : interface.second)
+ {
+ if (property.first == "Present")
+ {
+ const bool *present =
+ std::get_if<bool>(&property.second);
+ if (present != nullptr)
+ {
+ if (*present == true)
+ {
+ totalCores++;
+ }
+ }
+ }
+ }
+ }
+ }
}
}
+ // In getCpuDataByInterface(), state and health are set
+ // based on the present and functional status. If core
+ // count is zero, then it has a higher precedence.
+ if (totalCores == 0)
+ {
+ // Slot is not populated, set status end return
+ aResp->res.jsonValue["Status"]["State"] = "Absent";
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
+ }
+ aResp->res.jsonValue["TotalCores"] = totalCores;
+ return;
},
- service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
+ service, "/xyz/openbmc_project/inventory",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}
void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,