entity-manager: fix missed update from DevicePresence
The gpio-presence service updates DevicePresence whenever the GPIO
level changes, but entity-manager does not detect the update and
fails to re-probe the leak cable [1].
Root cause:
The InterfacesAdded/InterfacesRemoved listeners misused
std::set_intersection to filter signals of interest. The probeInterfaces
were stored in an unordered_set, which cannot be used
with std::set_intersection and caused unexpected results [2].
Fix:
Rework the filter implementation to avoid using std::set_intersection
with unordered_set.
[1] https://github.com/openbmc/docs/blob/master/designs/inventory/gpio-based-hardware-inventory.md
[2] https://en.cppreference.com/w/cpp/algorithm/set_intersection.html
Change-Id: I299a3c13fe2b5fdaf0b1eb4acf25f445280d247d
Signed-off-by: Eldin Lee <eldin.lee@quantatw.com>
diff --git a/src/entity_manager/entity_manager.cpp b/src/entity_manager/entity_manager.cpp
index 4623141..d17d21a 100644
--- a/src/entity_manager/entity_manager.cpp
+++ b/src/entity_manager/entity_manager.cpp
@@ -546,20 +546,11 @@
{
sdbusplus::message::object_path path;
DBusObject interfaces;
- std::set<std::string> interfaceSet;
- std::set<std::string> intersect;
-
msg.read(path, interfaces);
-
- std::for_each(interfaces.begin(), interfaces.end(),
- [&interfaceSet](const auto& iface) {
- interfaceSet.insert(iface.first);
- });
-
- std::set_intersection(interfaceSet.begin(), interfaceSet.end(),
- probeInterfaces.begin(), probeInterfaces.end(),
- std::inserter(intersect, intersect.end()));
- return !intersect.empty();
+ return std::ranges::any_of(interfaces | std::views::keys,
+ [&probeInterfaces](const auto& ifaceName) {
+ return probeInterfaces.contains(ifaceName);
+ });
}
// Check if InterfacesRemoved payload contains an iface that needs probing.
@@ -568,15 +559,12 @@
const std::unordered_set<std::string>& probeInterfaces)
{
sdbusplus::message::object_path path;
- std::set<std::string> interfaces;
- std::set<std::string> intersect;
-
+ std::vector<std::string> interfaces;
msg.read(path, interfaces);
-
- std::set_intersection(interfaces.begin(), interfaces.end(),
- probeInterfaces.begin(), probeInterfaces.end(),
- std::inserter(intersect, intersect.end()));
- return !intersect.empty();
+ return std::ranges::any_of(interfaces,
+ [&probeInterfaces](const auto& ifaceName) {
+ return probeInterfaces.contains(ifaceName);
+ });
}
void EntityManager::handleCurrentConfigurationJson()