From c1ba6721d6cb703fb1fd71651ef80f8cc287a1a9 Mon Sep 17 00:00:00 2001 From: James Feist Date: Mon, 7 Oct 2019 16:34:06 -0700 Subject: hsbp-manager: Add drive interface to fru-less drives Some drives don't have frus, but should still show up in redfish. For this reason we need to populate the drive interface when it is not available in entity-manager. Tested: All drives showed up in redfish Change-Id: If3bfa1e3e9c03146a77c896a5c983fbdaff3f4f5 Signed-off-by: James Feist --- hsbp-manager/src/hsbp_manager.cpp | 71 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/hsbp-manager/src/hsbp_manager.cpp b/hsbp-manager/src/hsbp_manager.cpp index 56469dd..5b34872 100644 --- a/hsbp-manager/src/hsbp_manager.cpp +++ b/hsbp-manager/src/hsbp_manager.cpp @@ -33,6 +33,7 @@ extern "C" { constexpr const char* configType = "xyz.openbmc_project.Configuration.Intel_HSBP_CPLD"; +constexpr const char* busName = "xyz.openbmc_project.HsbpManager"; constexpr size_t scanRateSeconds = 5; constexpr size_t maxDrives = 8; // only 1 byte alloted @@ -86,6 +87,7 @@ struct Drive objServer.remove_interface(operationalIface); objServer.remove_interface(rebuildingIface); objServer.remove_interface(associationIface); + objServer.remove_interface(driveIface); } void createAssociation(const std::string& path) @@ -103,10 +105,35 @@ struct Drive associationIface->initialize(); } + void removeDriveIface() + { + objServer.remove_interface(driveIface); + } + + void createDriveIface() + { + if (associationIface != nullptr || driveIface != nullptr) + { + // this shouldn't be used if we found another provider of the drive + // interface, or if we already created one + return; + } + driveIface = + objServer.add_interface(itemIface->get_object_path(), + "xyz.openbmc_project.Inventory.Item.Drive"); + driveIface->initialize(); + createAssociation(itemIface->get_object_path()); + } + std::shared_ptr itemIface; std::shared_ptr operationalIface; std::shared_ptr rebuildingIface; std::shared_ptr associationIface; + + // if something else doesn't expose a driveInterface for this, we need to + // export it ourselves + std::shared_ptr driveIface; + bool isNvme; }; @@ -407,6 +434,21 @@ struct Backplane std::unordered_map backplanes; +void createDriveInterfaces(size_t referenceCount) +{ + if (referenceCount != 1) + { + return; + } + for (auto& [name, backplane] : backplanes) + { + for (Drive& drive : backplane.drives) + { + drive.createDriveIface(); + } + } +} + void updateAssociations() { constexpr const char* driveType = @@ -427,15 +469,23 @@ void updateAssociations() } const std::string& owner = objDict.begin()->first; + // we export this interface too + if (owner == busName) + { + continue; + } + std::shared_ptr referenceCount = std::make_shared(); conn->async_method_call( - [path](const boost::system::error_code ec2, - const boost::container::flat_map< - std::string, std::variant>& values) { + [path, referenceCount]( + const boost::system::error_code ec2, + const boost::container::flat_map< + std::string, std::variant>& values) { if (ec2) { std::cerr << "Error Getting Config " << ec2.message() << " " << __FUNCTION__ << "\n"; + createDriveInterfaces(referenceCount.use_count()); return; } auto findBus = values.find("Bus"); @@ -446,6 +496,7 @@ void updateAssociations() { std::cerr << "Illegal interface at " << path << "\n"; + createDriveInterfaces(referenceCount.use_count()); return; } @@ -459,6 +510,7 @@ void updateAssociations() if (!std::filesystem::is_symlink(muxPath)) { std::cerr << path << " mux does not exist\n"; + createDriveInterfaces(referenceCount.use_count()); return; } @@ -472,6 +524,7 @@ void updateAssociations() findDash + 1 >= fname.size()) { std::cerr << path << " mux path invalid\n"; + createDriveInterfaces(referenceCount.use_count()); return; } @@ -497,6 +550,7 @@ void updateAssociations() { std::cerr << "Failed to find mux at bus " << bus << ", addr " << addr << "\n"; + createDriveInterfaces(referenceCount.use_count()); return; } if (parent->drives.size() <= driveIndex) @@ -504,10 +558,13 @@ void updateAssociations() std::cerr << "Illegal drive index at " << path << " " << driveIndex << "\n"; + createDriveInterfaces(referenceCount.use_count()); return; } Drive& drive = parent->drives[driveIndex]; + drive.removeDriveIface(); drive.createAssociation(path); + createDriveInterfaces(referenceCount.use_count()); }, owner, path, "org.freedesktop.DBus.Properties", "GetAll", "xyz.openbmc_project.Inventory.Item.Drive"); @@ -679,7 +736,7 @@ int main() { boost::asio::steady_timer callbackTimer(io); - conn->request_name("xyz.openbmc_project.HsbpManager"); + conn->request_name(busName); sdbusplus::bus::match::match match( *conn, @@ -706,8 +763,12 @@ int main() *conn, "type='signal',member='PropertiesChanged',arg0='xyz.openbmc_project." "Inventory.Item.Drive'", - [&callbackTimer](sdbusplus::message::message&) { + [&callbackTimer](sdbusplus::message::message& message) { callbackTimer.expires_after(std::chrono::seconds(2)); + if (message.get_sender() == conn->get_unique_name()) + { + return; + } callbackTimer.async_wait([](const boost::system::error_code ec) { if (ec == boost::asio::error::operation_aborted) { -- cgit v1.2.3