summaryrefslogtreecommitdiff
path: root/hsbp-manager/src/hsbp_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hsbp-manager/src/hsbp_manager.cpp')
-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)
{