summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Feist <james.feist@linux.intel.com>2019-10-08 02:34:06 +0300
committerFeist, James <james.feist@intel.com>2019-10-09 20:10:16 +0300
commitc1ba6721d6cb703fb1fd71651ef80f8cc287a1a9 (patch)
treea2e6bae7add0f160dc8723bee69fb2c544939cae
parentee5456f30fd5e655f306405df9af6e6026d3d1cc (diff)
downloadprovingground-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>
-rw-r--r--hsbp-manager/src/hsbp_manager.cpp71
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)
{