Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corrected EventDataOp during removal of fru #647

Open
wants to merge 1 commit into
base: 1110
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 138 additions & 18 deletions libpldmresponder/fru.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "fru.hpp"

#include "common/utils.hpp"
#ifdef OEM_IBM
#include "oem/ibm/libpldmresponder/utils.hpp"
#endif

#include <libpldm/entity.h>
#include <libpldm/utils.h>
Expand Down Expand Up @@ -379,6 +382,12 @@ uint32_t FruImpl::populateRecords(
void FruImpl::removeIndividualFRU(const std::string& fruObjPath)
{
uint16_t rsi = objectPathToRSIMap[fruObjPath];
if (!rsi)
{
info("No Pdrs to delete for the object path {PATH}", "PATH",
fruObjPath);
return;
}
pldm_entity removeEntity;
uint16_t terminusHdl{};
uint16_t entityType{};
Expand All @@ -398,14 +407,38 @@ void FruImpl::removeIndividualFRU(const std::string& fruObjPath)
auto removeBmcEntityRc =
pldm_entity_association_pdr_remove_contained_entity(
pdrRepo, &removeEntity, false, &updateRecordHdlBmc);
error("delete/remove contained entity from bmc record handle: {HANDLE}", "HANDLE", updateRecordHdlBmc);

pldm::responder::pdr_utils::PdrEntry pdrEntry;
uint8_t* pdrData = nullptr;
auto record = pldm_pdr_find_record(pdrRepo, updateRecordHdlBmc, &pdrData,
&pdrEntry.size,
&pdrEntry.handle.nextRecordHandle);
if (record)
{
error("Found BMC Record {REC}", "REC", updateRecordHdlBmc);
}
bmcEventDataOps = record ? PLDM_RECORDS_MODIFIED : PLDM_RECORDS_DELETED;

auto removeHostEntityRc =
pldm_entity_association_pdr_remove_contained_entity(
pdrRepo, &removeEntity, true, &updateRecordHdlHost);
error("delete/remove contained entity host record handle: {HANDLE}", "HANDLE", updateRecordHdlHost);
record = pldm_pdr_find_record(pdrRepo, updateRecordHdlHost, &pdrData,
&pdrEntry.size,
&pdrEntry.handle.nextRecordHandle);
if (record)
{
error("Found Host Record {REC}", "REC", updateRecordHdlHost);
}
hostEventDataOps = record ? PLDM_RECORDS_MODIFIED : PLDM_RECORDS_DELETED;

pldm_pdr_remove_fru_record_set_by_rsi(pdrRepo, rsi, false,
&deleteRecordHdl);

error("delete record handle: {HANDLE} from rsi: {RSI}", "HANDLE",
deleteRecordHdl, "RSI", rsi);

pldm_entity_association_tree_delete_node(entityTree, removeEntity);
pldm_entity_association_tree_delete_node(bmcEntityTree, removeEntity);

Expand All @@ -419,6 +452,7 @@ void FruImpl::removeIndividualFRU(const std::string& fruObjPath)
static_cast<unsigned>(removeEntity.entity_container_id));
associatedEntityMap.erase(fruObjPath);

error("delete RSI: {HANDLE}", "HANDLE", rsi);
deleteFruRecord(rsi);

std::vector<ChangeEntry> handlesTobeDeleted;
Expand All @@ -437,6 +471,8 @@ void FruImpl::removeIndividualFRU(const std::string& fruObjPath)
effecterDbusObjMaps.erase(ids);
if (delEffecterHdl != 0)
{
error("delete effecter ID: {ID} and record handle: {HANDLE}", "ID",
ids, "HANDLE", delEffecterHdl);
handlesTobeDeleted.push_back(delEffecterHdl);
}
}
Expand All @@ -450,6 +486,8 @@ void FruImpl::removeIndividualFRU(const std::string& fruObjPath)
sensorDbusObjMaps.erase(ids);
if (delSensorHdl != 0)
{
error("delete sensor ID: {ID} and record handle: {HANDLE}", "ID",
ids, "HANDLE", delSensorHdl);
handlesTobeDeleted.push_back(delSensorHdl);
}
}
Expand All @@ -469,15 +507,30 @@ void FruImpl::removeIndividualFRU(const std::string& fruObjPath)
? handlesTobeDeleted.push_back(updateRecordHdlHost)
: handlesTobeModified.push_back(updateRecordHdlHost);
}


error("Modified Handles");
for(const auto &modified : handlesTobeModified)
{
error("{H}", "H", modified);
}
error("Deleted Handles");
for(const auto &deleted : handlesTobeDeleted)
{
error("{H}", "H", deleted);
}

// Adapter PDRs can have deleted records
if (!handlesTobeDeleted.empty())
{
error("Sending repo change event for deleted handler");
sendPDRRepositoryChgEventbyPDRHandles(
std::move(handlesTobeDeleted),
std::move(std::vector<uint8_t>(1, PLDM_RECORDS_DELETED)));
}
if (!handlesTobeModified.empty())
{
error("Sending repo change event fored handler");
sendPDRRepositoryChgEventbyPDRHandles(
std::move(handlesTobeModified),
std::move(std::vector<uint8_t>(1, PLDM_RECORDS_MODIFIED)));
Expand Down Expand Up @@ -538,6 +591,14 @@ void FruImpl::buildIndividualFRU(const std::string& fruInterface,
pldm_entity parentEntity{};
static uint32_t bmc_record_handle = 0;
uint32_t newRecordHdl{};

if (fruInterface == "xyz.openbmc_project.Inventory.Item.PCIeDevice")
{
// Delete the existing adapter PDR before creating new one
info("Removing old PDRs {PATH}", "PATH", fruObjectPath);
removeIndividualFRU(fruObjectPath);
}

try
{
entity.entity_type = parser.getEntityType(fruInterface);
Expand Down Expand Up @@ -580,14 +641,28 @@ void FruImpl::buildIndividualFRU(const std::string& fruInterface,
pldm_entity_association_tree_add(bmcEntityTree, &entity, 0xFFFF,
bmcTreeParentNode,
PLDM_ENTITY_ASSOCIAION_PHYSICAL);
info(
"2 Building Individual FRU [{FRU_OBJ_PATH}] with entityid [ {ENTITY_TYPE}, {ENTITY_NUM}, {ENTITY_ID} ] Parent :[ {P_ENTITY_TYP}, {P_ENTITY_NUM}, {P_ENTITY_ID} ]",
"FRU_OBJ_PATH", fruObjectPath, "ENTITY_TYPE",
static_cast<unsigned>(node_entity.entity_type), "ENTITY_NUM",
static_cast<unsigned>(node_entity.entity_instance_num), "ENTITY_ID",
static_cast<unsigned>(node_entity.entity_container_id),
"P_ENTITY_TYP", static_cast<unsigned>(parent.entity_type),
"P_ENTITY_NUM", static_cast<unsigned>(parent.entity_instance_num),
"P_ENTITY_ID", static_cast<unsigned>(parent.entity_container_id));

objects = DBusHandler::getManagedObj(
"xyz.openbmc_project.Inventory.Manager", inventoryPath);
for (const auto& object : objects)
{
if (object.first.str == fruObjectPath)
{
const auto& interfaces = object.second;
newRecordHdl = populateRecords(interfaces, recordInfos, entity,
fruObjectPath, true);
error(
"build record handle: {HANDLE} FRU object path: {OBJPATH}",
"HANDLE", newRecordHdl, "OBJPATH", fruObjectPath);
associatedEntityMap.emplace(fruObjectPath, entity);
break;
}
Expand Down Expand Up @@ -637,18 +712,22 @@ void FruImpl::buildIndividualFRU(const std::string& fruInterface,
found = false;
pldm_entity_association_find_parent_entity(pdrRepo, &parent, true,
&updatedRecordHdlHost, &found);
error("build host record handle: {HANDLE}", "HANDLE", updatedRecordHdlHost);
if (found)
{
pldm_entity_association_pdr_add_contained_entity_to_remote_pdr(
pdrRepo, &entity, updatedRecordHdlHost);
hostEventDataOps = PLDM_RECORDS_MODIFIED;
error("Modify build host record handle: {HANDLE}", "HANDLE", updatedRecordHdlHost);
}
else
{
pldm_entity_association_pdr_create_new(pdrRepo, bmc_record_handle,
&parent, &entity,
&updatedRecordHdlHost);
hostEventDataOps = PLDM_RECORDS_ADDED;
error(" build host record handle: {HANDLE}", "HANDLE", updatedRecordHdlHost);

}

// create the relevant state effecter and sensor PDRs for the new fru record
Expand All @@ -662,6 +741,7 @@ void FruImpl::buildIndividualFRU(const std::string& fruInterface,

for (auto& ids : recordHdlList)
{
error("build record handle from list: {HANDLE}", "HANDLE", ids);
handlesTobeAdded.push_back(ids);
}
if (updatedRecordHdlBmc != 0)
Expand All @@ -676,6 +756,16 @@ void FruImpl::buildIndividualFRU(const std::string& fruInterface,
? handlesTobeModified.push_back(updatedRecordHdlHost)
: handlesTobeAdded.push_back(updatedRecordHdlHost);
}
error("Modified Handles");
for(const auto &modified : handlesTobeModified)
{
error("{H}", "H", modified);
}
error("Added Handles");
for(const auto &deleted : handlesTobeAdded)
{
error("{H}", "H", deleted);
}
if (!handlesTobeAdded.empty())
{
sendPDRRepositoryChgEventbyPDRHandles(
Expand Down Expand Up @@ -922,37 +1012,67 @@ void FruImpl::processFruPresenceChange(const DbusChangedProps& chProperties,
}

std::vector<std::string> portObjects;
static constexpr auto portInterface =
"xyz.openbmc_project.Inventory.Item.Connector";

if (oemUtilsHandler)
if (newPropVal)
{
if (fruInterface == "xyz.openbmc_project.Inventory.Item.PCIeDevice")
info("Presence changed to true for {PATH}", "PATH", fruObjPath);
// oemUtilsHandler check is added to make sure that it is OEM_IBM path
if (fruInterface == "xyz.openbmc_project.Inventory.Item.PCIeDevice" &&
oemUtilsHandler)
{
if (!oemUtilsHandler->checkFruPresence(fruObjPath.c_str()))
if (pldm::responder::utils::checkIfIBMFru(fruObjPath))
{
static constexpr auto portInterface =
"xyz.openbmc_project.Inventory.Item.Connector";

// if the added fru is IBM cable card, build the adapter
// PDRs and the port PDRs.
buildIndividualFRU(fruInterface, fruObjPath);
portObjects = oemUtilsHandler->findPortObjects(fruObjPath);
info("Ports under the cable card: {NUM}", "NUM",
(int)portObjects.size());
for (auto portObject : portObjects)
{
buildIndividualFRU(portInterface, portObject);
}
return;
}
else
{
// PDRs realted to industry standard card are not
// rebuilt.
return;
}
portObjects = oemUtilsHandler->findPortObjects(fruObjPath);
}
// as per current code the ports do not have Present property
}

if (newPropVal)
{
buildIndividualFRU(fruInterface, fruObjPath);
for (auto portObject : portObjects)
{
buildIndividualFRU(portInterface, portObject);
}
}
else
{
for (auto portObject : portObjects)
info("Presence changed to false for {PATH}", "PATH", fruObjPath);
if (fruInterface == "xyz.openbmc_project.Inventory.Item.PCIeDevice")
{
// If the card is removed from the system, we do remove the port
// pdrs(if present) but not the adapter PDR as adapter PDR should be
// always there inspite of the presence of the card.
if (oemUtilsHandler)
{
portObjects = oemUtilsHandler->findPortObjects(fruObjPath);
for (auto portObject : portObjects)
{
removeIndividualFRU(portObject);
}
}
else
{
// Non OEM-IBM path, remove the pcieDevice pdrs
removeIndividualFRU(fruObjPath);
}
}
else
{
removeIndividualFRU(portObject);
info("Removing Individual FRU {PATH}", "PATH", fruObjPath);
removeIndividualFRU(fruObjPath);
}
removeIndividualFRU(fruObjPath);
}
}

Expand Down
23 changes: 15 additions & 8 deletions oem/ibm/libpldmresponder/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,25 +608,31 @@ bool pldm::responder::oem_ibm_utils::Handler::checkFruPresence(
// the port is considered as present. this is so because
// the ports do not have "Present" property
std::string pcieAdapter("pcie_card");
std::string nvmeAdapter("_drive");
std::string portStr("cxp_");
std::string connectorStr("_connector");
std::string newObjPath = objPath;
bool isPresent = true;

if (newObjPath.find(pcieAdapter) != std::string::npos)
if ((newObjPath.find(pcieAdapter) != std::string::npos) ||
(newObjPath.find(nvmeAdapter) != std::string::npos))
{
if (newObjPath.find(portStr) != std::string::npos)
if ((newObjPath.find(portStr) != std::string::npos) ||
(newObjPath.find(connectorStr) != std::string::npos))
{
newObjPath = pldm::utils::findParent(objPath);
}
else
{
return true; // industry std cards
// Adapter PDRs are always created underneath the slot for
// Insustry standard cards as well as IBM cable cards.
// Phyp expects the FRU records for industry std cards to be always
// built, irrespective of presence. This is needed by PHYP to send
// the Fan floor information
return true; // industry std cards/IBM cable cards
}
}

// Phyp expects the FRU records for industry std cards to be always
// built, irrespective of presence

static constexpr auto presentInterface =
"xyz.openbmc_project.Inventory.Item";
static constexpr auto presentProperty = "Present";
Expand All @@ -638,8 +644,9 @@ bool pldm::responder::oem_ibm_utils::Handler::checkFruPresence(
}
catch (const sdbusplus::exception::SdBusError& e)
{
error("D-Bus method call to get the FRU presence failed ERROR={ERROR}",
"ERROR", e);
error(
"D-Bus method call to get the FRU presence of {FRU} failed ERROR={ERR} and return is {V}",
"FRU", newObjPath, "ERR", e.what(), "V", (int)isPresent);
}
return isPresent;
}
Expand Down