[PATCH phosphor-objmgr] Avoid introspection during discovery
OpenBMC Patches
openbmc-patches at stwcx.xyz
Tue May 17 08:20:42 AEST 2016
From: Brad Bishop <bradleyb at fuzziesquirrel.com>
Speed up discovery by calling GetManagedObjects on any ObjectManagers.
Fall back on introspection for parent elements or services that don't
implement one.
---
phosphor-mapper | 90 ++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 77 insertions(+), 13 deletions(-)
diff --git a/phosphor-mapper b/phosphor-mapper
index 675ad40..944f6d4 100644
--- a/phosphor-mapper
+++ b/phosphor-mapper
@@ -21,7 +21,7 @@ import dbus.service
import dbus.exceptions
import dbus.mainloop.glib
import gobject
-from obmc.dbuslib.introspection import IntrospectionParser
+import xml.etree.ElementTree as ET
import obmc.utils.pathtree
import obmc.utils.misc
import obmc.mapper
@@ -37,6 +37,71 @@ class MapperNotFoundException(dbus.exceptions.DBusException):
"path or object not found: %s" % path)
+def find_dbus_interfaces(conn, service, path, match):
+ class __FindInterfaces(object):
+ def __init__(self):
+ self.results = {}
+
+ @staticmethod
+ def __introspect(service, path):
+ obj = conn.get_object(service, path, introspect=False)
+ iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
+ return iface.Introspect()
+
+ @staticmethod
+ def __get_managed_objects(service, om):
+ obj = conn.get_object(service, om, introspect=False)
+ iface = dbus.Interface(
+ obj, dbus.BUS_DAEMON_IFACE + '.ObjectManager')
+ return iface.GetManagedObjects()
+
+ @staticmethod
+ def __to_path(elements):
+ return '/' + '/'.join(elements)
+
+ @staticmethod
+ def __to_path_elements(path):
+ return filter(bool, path.split('/'))
+
+ def __call__(self, service, path):
+ self.results = {}
+ self.__find_interfaces(service, path)
+ return self.results
+
+ @staticmethod
+ def __match(iface):
+ return iface == dbus.BUS_DAEMON_IFACE + '.ObjectManager' \
+ or match(iface)
+
+ def __find_interfaces(self, service, path):
+ path_elements = self.__to_path_elements(path)
+ path = self.__to_path(path_elements)
+ root = ET.fromstring(self.__introspect(service, path))
+
+ ifaces = filter(
+ self.__match,
+ [x.attrib.get('name') for x in root.findall('interface')])
+ self.results[path] = ifaces
+
+ if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in ifaces:
+ objs = self.__get_managed_objects(service, path)
+ for k, v in objs.iteritems():
+ self.results[k] = v.keys()
+ else:
+ children = filter(
+ bool,
+ [x.attrib.get('name') for x in root.findall('node')])
+ children = [
+ self.__to_path(
+ path_elements + self.__to_path_elements(x))
+ for x in children]
+ for child in children:
+ if child not in self.results:
+ self.__find_interfaces(service, child)
+
+ return __FindInterfaces()(service, path)
+
+
class Association(dbus.service.Object):
def __init__(self, bus, path, endpoints):
super(Association, self).__init__(bus, path)
@@ -196,10 +261,12 @@ class ObjectMapper(dbus.service.Object):
def process_new_owner(self, owner):
# unique name
- return self.discover([IntrospectionParser(owner,
- self.bus.dbus,
- self.tag_match,
- self.intf_match)])
+ try:
+ return self.discover([owner])
+ except dbus.exceptions.DBusException, e:
+ if obmc.dbuslib.enums.DBUS_UNKNOWN_SERVICE \
+ not in e.get_dbus_name():
+ raise
def process_old_owner(self, owner):
for path, item in self.cache.dataitems():
@@ -240,7 +307,7 @@ class ObjectMapper(dbus.service.Object):
def add_items(self, owner, bus_items):
for path, items in bus_items.iteritems():
# convert dbus types to native.
- interfaces = [str(i) for i in items.get('interfaces', [])]
+ interfaces = [str(i) for i in items]
self.update_interfaces(path, str(owner), old=[], new=interfaces)
def discover(self, owners=[]):
@@ -248,14 +315,11 @@ class ObjectMapper(dbus.service.Object):
return iface == dbus.BUS_DAEMON_IFACE + '.ObjectManager' or \
self.intf_match(iface)
if not owners:
- owners = [
- IntrospectionParser(
- x, self.bus.dbus,
- self.tag_match,
- match)
- for x in self.bus.get_owner_names(self.bus_match)]
+ owners = self.bus.get_owner_names(self.bus_match)
for o in owners:
- self.add_items(o.name, o.introspect())
+ self.add_items(
+ o,
+ find_dbus_interfaces(self.bus.dbus, o, '/', self.intf_match))
if self.discovery_pending():
# add my object mananger instance
--
2.8.2
More information about the openbmc
mailing list