summaryrefslogtreecommitdiffstats
path: root/src/associations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/associations.cpp')
-rw-r--r--src/associations.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/associations.cpp b/src/associations.cpp
new file mode 100644
index 0000000..3ae7db4
--- /dev/null
+++ b/src/associations.cpp
@@ -0,0 +1,76 @@
+#include "associations.hpp"
+
+void removeAssociation(const std::string& sourcePath, const std::string& owner,
+ sdbusplus::asio::object_server& server,
+ AssociationOwnersType& assocOwners,
+ AssociationInterfaces& assocInterfaces)
+{
+ // Use associationOwners to find the association paths and endpoints
+ // that the passed in object path and service own. Remove all of
+ // these endpoints from the actual association D-Bus objects, and if
+ // the endpoints property is then empty, the whole association object
+ // can be removed. Note there can be multiple services that own an
+ // association, and also that sourcePath is the path of the object
+ // that contains the org.openbmc.Associations interface and not the
+ // association path itself.
+
+ // Find the services that have associations for this object path
+ auto owners = assocOwners.find(sourcePath);
+ if (owners == assocOwners.end())
+ {
+ return;
+ }
+
+ // Find the association paths and endpoints owned by this object
+ // path for this service.
+ auto assocs = owners->second.find(owner);
+ if (assocs == owners->second.end())
+ {
+ return;
+ }
+
+ for (const auto& [assocPath, endpointsToRemove] : assocs->second)
+ {
+ // Get the association D-Bus object for this assocPath
+ auto target = assocInterfaces.find(assocPath);
+ if (target == assocInterfaces.end())
+ {
+ continue;
+ }
+
+ // Remove the entries in the endpoints D-Bus property for this
+ // path/owner/association-path.
+ auto& existingEndpoints = std::get<endpointsPos>(target->second);
+ for (const auto& endpointToRemove : endpointsToRemove)
+ {
+ auto e = std::find(existingEndpoints.begin(),
+ existingEndpoints.end(), endpointToRemove);
+
+ if (e != existingEndpoints.end())
+ {
+ existingEndpoints.erase(e);
+ }
+ }
+
+ // Remove the association from D-Bus if there are no more endpoints,
+ // otherwise just update the endpoints property.
+ if (existingEndpoints.empty())
+ {
+ server.remove_interface(std::get<ifacePos>(target->second));
+ std::get<ifacePos>(target->second) = nullptr;
+ std::get<endpointsPos>(target->second).clear();
+ }
+ else
+ {
+ std::get<ifacePos>(target->second)
+ ->set_property("endpoints", existingEndpoints);
+ }
+ }
+
+ // Remove the associationOwners entries for this owning path/service.
+ owners->second.erase(assocs);
+ if (owners->second.empty())
+ {
+ assocOwners.erase(owners);
+ }
+}
OpenPOWER on IntegriCloud