FRU object to be created once - Create and recreate fru only when invnetory info change Fixes jira https://jirasw.nvidia.com/browse/DGXOPENBMC-17802
diff --git a/nsmd/deviceManager.cpp b/nsmd/deviceManager.cpp index 02b50b8..e5b1572 100644 --- a/nsmd/deviceManager.cpp +++ b/nsmd/deviceManager.cpp
@@ -737,67 +737,63 @@ } } - // expose inventory information to FruDevice PDI - std::string objPath = "/xyz/openbmc_project/FruDevice/" + - std::to_string(eid); - nsmDevice->fruDeviceIntf = objServer.add_unique_interface( - objPath, "xyz.openbmc_project.FruDevice"); + // Determine currently supported properties by checking specific known + // properties + std::set<std::string> currentProperties; + // Check for dynamic properties that the device might support if (properties.find(BOARD_PART_NUMBER) != properties.end()) { - nsmDevice->fruDeviceIntf->register_property( - "BOARD_PART_NUMBER", - std::get<std::string>(properties[BOARD_PART_NUMBER])); + currentProperties.insert("BOARD_PART_NUMBER"); } - if (properties.find(FRU_PART_NUMBER) != properties.end()) { - nsmDevice->fruDeviceIntf->register_property( - "FRU_PART_NUMBER", - std::get<std::string>(properties[FRU_PART_NUMBER])); + currentProperties.insert("FRU_PART_NUMBER"); } - if (properties.find(SERIAL_NUMBER) != properties.end()) { - nsmDevice->fruDeviceIntf->register_property( - "SERIAL_NUMBER", std::get<std::string>(properties[SERIAL_NUMBER])); + currentProperties.insert("SERIAL_NUMBER"); } - if (properties.find(MARKETING_NAME) != properties.end()) { - nsmDevice->fruDeviceIntf->register_property( - "MARKETING_NAME", - std::get<std::string>(properties[MARKETING_NAME])); + currentProperties.insert("MARKETING_NAME"); } - if (properties.find(BUILD_DATE) != properties.end()) { - nsmDevice->fruDeviceIntf->register_property( - "BUILD_DATE", std::get<std::string>(properties[BUILD_DATE])); + currentProperties.insert("BUILD_DATE"); } - - auto mctpUuid = utils::getUUIDFromEID(eidTable, eid); - if (mctpUuid.has_value()) - { - nsmDevice->uuid = *mctpUuid; - } - if (properties.find(DEVICE_GUID) != properties.end()) { - nsmDevice->fruDeviceIntf->register_property( - "DEVICE_UUID", std::get<uuid_t>(properties[DEVICE_GUID])); - nsmDevice->deviceUuid = std::get<uuid_t>(properties[DEVICE_GUID]); + currentProperties.insert("DEVICE_UUID"); } - nsmDevice->fruDeviceIntf->register_property("DEVICE_TYPE", - nsmDevice->getDeviceType()); - nsmDevice->fruDeviceIntf->register_property("INSTANCE_NUMBER", - nsmDevice->getInstanceNumber()); - nsmDevice->fruDeviceIntf->register_property("UUID", nsmDevice->uuid); + // Always include fixed properties + currentProperties.insert("DEVICE_TYPE"); + currentProperties.insert("INSTANCE_NUMBER"); + currentProperties.insert("UUID"); - nsmDevice->fruDeviceIntf->initialize(); + // Check if interface needs recreation + if (nsmDevice->fruDeviceManager.needsRecreation(currentProperties)) + { + lg2::info( + "Creating/Recreating FRU interface for eid={EID} with {COUNT} properties", + "EID", eid, "COUNT", currentProperties.size()); - // coverity[missing_return] + // Create interface and register all properties + nsmDevice->fruDeviceManager.createAndRegisterInterface( + objServer, eid, nsmDevice, properties, eidTable); + + nsmDevice->fruDeviceManager.markInitialized(currentProperties); + } + else + { + lg2::debug("Updating FRU property values for eid={EID}", "EID", eid); + + // Just update property values + nsmDevice->fruDeviceManager.updateAllPropertyValues( + nsmDevice, properties, eidTable); + } + co_return rc; }
diff --git a/nsmd/nsmDevice.cpp b/nsmd/nsmDevice.cpp index 60e2136..5852739 100644 --- a/nsmd/nsmDevice.cpp +++ b/nsmd/nsmDevice.cpp
@@ -318,4 +318,163 @@ addSensor(msgTypesSensor, false); } +// FruInterfaceManager method implementations +bool FruInterfaceManager::needsRecreation( + const std::set<std::string>& newProperties) const +{ + return !initialized || (supportedProperties != newProperties); +} + +void FruInterfaceManager::markInitialized( + const std::set<std::string>& properties) +{ + supportedProperties = properties; + initialized = true; +} + +bool FruInterfaceManager::isPropertySupported( + const std::string& propertyName) const +{ + return supportedProperties.find(propertyName) != supportedProperties.end(); +} + +void FruInterfaceManager::reset() +{ + interface.reset(); + supportedProperties.clear(); + initialized = false; +} + +void FruInterfaceManager::createAndRegisterInterface( + sdbusplus::asio::object_server& objServer, uint8_t eid, + std::shared_ptr<NsmDevice> nsmDevice, const InventoryProperties& properties, + const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>& + eidTable) +{ + std::string objPath = "/xyz/openbmc_project/FruDevice/" + + std::to_string(eid); + interface = objServer.add_unique_interface(objPath, + "xyz.openbmc_project.FruDevice"); + registerAllProperties(nsmDevice, properties, eidTable); + interface->initialize(); +} + +void FruInterfaceManager::updateAllPropertyValues( + std::shared_ptr<NsmDevice> nsmDevice, const InventoryProperties& properties, + const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>& + eidTable) +{ + if (!interface) + return; + + if (properties.find(BOARD_PART_NUMBER) != properties.end()) + { + interface->set_property( + "BOARD_PART_NUMBER", + std::get<std::string>(properties.at(BOARD_PART_NUMBER))); + } + + if (properties.find(FRU_PART_NUMBER) != properties.end()) + { + interface->set_property( + "FRU_PART_NUMBER", + std::get<std::string>(properties.at(FRU_PART_NUMBER))); + } + + if (properties.find(SERIAL_NUMBER) != properties.end()) + { + interface->set_property( + "SERIAL_NUMBER", + std::get<std::string>(properties.at(SERIAL_NUMBER))); + } + + if (properties.find(MARKETING_NAME) != properties.end()) + { + interface->set_property( + "MARKETING_NAME", + std::get<std::string>(properties.at(MARKETING_NAME))); + } + + if (properties.find(BUILD_DATE) != properties.end()) + { + interface->set_property( + "BUILD_DATE", std::get<std::string>(properties.at(BUILD_DATE))); + } + + auto mctpUuid = utils::getUUIDFromEID(eidTable, nsmDevice->eid); + if (mctpUuid.has_value()) + { + nsmDevice->uuid = *mctpUuid; + } + + if (properties.find(DEVICE_GUID) != properties.end()) + { + interface->set_property("DEVICE_UUID", + std::get<uuid_t>(properties.at(DEVICE_GUID))); + nsmDevice->deviceUuid = std::get<uuid_t>(properties.at(DEVICE_GUID)); + } + + interface->set_property("DEVICE_TYPE", nsmDevice->getDeviceType()); + interface->set_property("INSTANCE_NUMBER", nsmDevice->getInstanceNumber()); + interface->set_property("UUID", nsmDevice->uuid); +} + +void FruInterfaceManager::registerAllProperties( + std::shared_ptr<NsmDevice> nsmDevice, const InventoryProperties& properties, + const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>& + eidTable) +{ + if (properties.find(BOARD_PART_NUMBER) != properties.end()) + { + interface->register_property( + "BOARD_PART_NUMBER", + std::get<std::string>(properties.at(BOARD_PART_NUMBER))); + } + + if (properties.find(FRU_PART_NUMBER) != properties.end()) + { + interface->register_property( + "FRU_PART_NUMBER", + std::get<std::string>(properties.at(FRU_PART_NUMBER))); + } + + if (properties.find(SERIAL_NUMBER) != properties.end()) + { + interface->register_property( + "SERIAL_NUMBER", + std::get<std::string>(properties.at(SERIAL_NUMBER))); + } + + if (properties.find(MARKETING_NAME) != properties.end()) + { + interface->register_property( + "MARKETING_NAME", + std::get<std::string>(properties.at(MARKETING_NAME))); + } + + if (properties.find(BUILD_DATE) != properties.end()) + { + interface->register_property( + "BUILD_DATE", std::get<std::string>(properties.at(BUILD_DATE))); + } + + auto mctpUuid = utils::getUUIDFromEID(eidTable, nsmDevice->eid); + if (mctpUuid.has_value()) + { + nsmDevice->uuid = *mctpUuid; + } + + if (properties.find(DEVICE_GUID) != properties.end()) + { + interface->register_property( + "DEVICE_UUID", std::get<uuid_t>(properties.at(DEVICE_GUID))); + nsmDevice->deviceUuid = std::get<uuid_t>(properties.at(DEVICE_GUID)); + } + + interface->register_property("DEVICE_TYPE", nsmDevice->getDeviceType()); + interface->register_property("INSTANCE_NUMBER", + nsmDevice->getInstanceNumber()); + interface->register_property("UUID", nsmDevice->uuid); +} + } // namespace nsm
diff --git a/nsmd/nsmDevice.hpp b/nsmd/nsmDevice.hpp index aa496d9..119ce25 100644 --- a/nsmd/nsmDevice.hpp +++ b/nsmd/nsmDevice.hpp
@@ -19,6 +19,7 @@ #include "base.h" #include "device-capability-discovery.h" +#include "platform-environmental.h" #include "common/coroutineSemaphore.hpp" #include "common/types.hpp" @@ -38,6 +39,7 @@ #include <deque> #include <map> #include <ranges> // For ranges::find_if +#include <set> #define MAX_SENSOR_UPDATE_BATCH_SIZE 10 @@ -68,6 +70,37 @@ LongRunning, // Long running polling for long running sensors }; +struct FruInterfaceManager +{ + std::unique_ptr<sdbusplus::asio::dbus_interface> interface; + std::set<std::string> supportedProperties; + bool initialized = false; + + // Public method declarations only + bool needsRecreation(const std::set<std::string>& newProperties) const; + void markInitialized(const std::set<std::string>& properties); + bool isPropertySupported(const std::string& propertyName) const; + void reset(); + void createAndRegisterInterface( + sdbusplus::asio::object_server& objServer, uint8_t eid, + std::shared_ptr<NsmDevice> nsmDevice, + const InventoryProperties& properties, + const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>& + eidTable); + void updateAllPropertyValues( + std::shared_ptr<NsmDevice> nsmDevice, + const InventoryProperties& properties, + const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>& + eidTable); + + private: + void registerAllProperties( + std::shared_ptr<NsmDevice> nsmDevice, + const InventoryProperties& properties, + const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>& + eidTable); +}; + class NsmDevice : public StateChangeLogger { public: @@ -97,7 +130,7 @@ #endif } - std::unique_ptr<sdbusplus::asio::dbus_interface> fruDeviceIntf; + FruInterfaceManager fruDeviceManager; std::unique_ptr<void, std::function<void(void*)>> nsmRawCmdIntf; eid_t eid = 0;