diff options
author | James Feist <james.feist@linux.intel.com> | 2019-10-08 02:34:06 +0300 |
---|---|---|
committer | Feist, James <james.feist@intel.com> | 2019-10-09 20:10:16 +0300 |
commit | c1ba6721d6cb703fb1fd71651ef80f8cc287a1a9 (patch) | |
tree | a2e6bae7add0f160dc8723bee69fb2c544939cae /hsbp-manager | |
parent | ee5456f30fd5e655f306405df9af6e6026d3d1cc (diff) | |
download | provingground-c1ba6721d6cb703fb1fd71651ef80f8cc287a1a9.tar.xz |
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 <james.feist@linux.intel.com>
Diffstat (limited to 'hsbp-manager')
-rw-r--r-- | hsbp-manager/src/hsbp_manager.cpp | 71 |
1 files 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<sdbusplus::asio::dbus_interface> itemIface; std::shared_ptr<sdbusplus::asio::dbus_interface> operationalIface; std::shared_ptr<sdbusplus::asio::dbus_interface> rebuildingIface; std::shared_ptr<sdbusplus::asio::dbus_interface> associationIface; + + // if something else doesn't expose a driveInterface for this, we need to + // export it ourselves + std::shared_ptr<sdbusplus::asio::dbus_interface> driveIface; + bool isNvme; }; @@ -407,6 +434,21 @@ struct Backplane std::unordered_map<std::string, Backplane> 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<bool> referenceCount = std::make_shared<bool>(); conn->async_method_call( - [path](const boost::system::error_code ec2, - const boost::container::flat_map< - std::string, std::variant<uint64_t>>& values) { + [path, referenceCount]( + const boost::system::error_code ec2, + const boost::container::flat_map< + std::string, std::variant<uint64_t>>& 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) { |