Change in vdsm[master]: libnl_wrapper: avoid getting link_cache just for getting ifa...

asegurap at redhat.com asegurap at redhat.com
Mon Sep 15 15:24:01 UTC 2014


Antoni Segura Puimedon has uploaded a new change for review.

Change subject: libnl_wrapper: avoid getting link_cache just for getting iface label
......................................................................

libnl_wrapper: avoid getting link_cache just for getting iface label

Change-Id: I0e6aaac0bdb58a0052b25f588e11de03bde3e12f
Signed-off-by: Antoni S. Puimedon <asegurap at redhat.com>
---
M lib/vdsm/netlink/addr.py
M lib/vdsm/netlink/link.py
2 files changed, 64 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/49/32949/1

diff --git a/lib/vdsm/netlink/addr.py b/lib/vdsm/netlink/addr.py
index 960f4ee..031a9ee 100644
--- a/lib/vdsm/netlink/addr.py
+++ b/lib/vdsm/netlink/addr.py
@@ -23,7 +23,7 @@
 from . import _char_proto, _int_char_proto, _int_proto, _void_proto
 from . import LIBNL, LIBNL_ROUTE, _nl_geterror, _pool
 from . import _addr_to_str, _af_to_str, _scope_to_str, CHARBUFFSIZE
-from .link import _nl_link_cache, _link_index_to_name
+from .link import _get_link_name_from_index
 
 
 def iter_addrs():
@@ -31,19 +31,18 @@
     in the system."""
     with _pool.socket() as sock:
         with _nl_addr_cache(sock) as addr_cache:
-            with _nl_link_cache(sock) as link_cache:  # for index to label
-                addr = _nl_cache_get_first(addr_cache)
-                while addr:
-                    yield _addr_info(link_cache, addr)
-                    addr = _nl_cache_get_next(addr)
+            _index_to_name = partial(_get_link_name_from_index, sock=sock)
+            addr = _nl_cache_get_first(addr_cache)
+            while addr:
+                yield _addr_info(addr, _index_to_name)
+                addr = _nl_cache_get_next(addr)
 
 
-def _addr_info(link_cache, addr):
+def _addr_info(addr, _index_to_name):
     """Returns a dictionary with the address information."""
     index = _rtnl_addr_get_ifindex(addr)
     return {
-        'label': (_rtnl_addr_get_label(addr) or
-                  _link_index_to_name(link_cache, index)),
+        'label': _index_to_name(index),
         'index': index,
         'family': _af_to_str(_rtnl_addr_get_family(addr)),
         'prefixlen': _rtnl_addr_get_prefixlen(addr),
diff --git a/lib/vdsm/netlink/link.py b/lib/vdsm/netlink/link.py
index 13d00c4..b25a083 100644
--- a/lib/vdsm/netlink/link.py
+++ b/lib/vdsm/netlink/link.py
@@ -31,12 +31,11 @@
 def get_link(name):
     """Returns the information dictionary of the name specified link."""
     with _pool.socket() as sock:
-        with _nl_link_cache(sock) as cache:
-            link = _rtnl_link_get_by_name(cache, name)
-            if not link:
-                raise IOError(errno.ENODEV, '%s is not present in the system' %
-                              name)
-            return _link_info(cache, link)
+        link = _get_link(sock, name)
+        if not link:
+            raise IOError(errno.ENODEV, '%s is not present in the system' %
+                          name)
+        return _link_info(cache, link)
 
 
 def iter_links():
@@ -97,6 +96,14 @@
     return _rtnl_link_operstate2str(state, operstate, sizeof(operstate))
 
 
+def _get_link_name_from_index(index, sock=None):
+    link = _get_link(index=index, sock=sock)
+    if link is None:
+        raise IOError(errno.ENODEV, 'Dev with index %s is not present in the '
+                      'system' % index)
+    return _rtnl_link_get_name(link)
+
+
 # C function prototypes
 # http://docs.python.org/2/library/ctypes.html#function-prototypes
 # This helps ctypes know the calling conventions it should use to communicate
@@ -108,6 +115,9 @@
     _link_is_vlan = _int_proto(('rtnl_link_is_vlan', LIBNL_ROUTE))
     _vlan_get_id = _int_proto(('rtnl_link_vlan_get_id', LIBNL_ROUTE))
     _rtnl_link_get_type = _char_proto(('rtnl_link_get_type', LIBNL_ROUTE))
+    _rtnl_link_get_kernel = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p,
+                                      c_void_p)(('rtnl_link_get_kernel',
+                                                 LIBNL_ROUTE))
 
     def _rtnl_link_alloc_cache(sock):
         """Wraps the new link alloc cache to expose the libnl1 signature"""
@@ -123,14 +133,54 @@
             return _vlan_get_id(link)
         else:
             return -1
+
+    def _get_link(name=None, index=0, sock=None):
+        if name is None and index == 0:
+            raise ValueError('Must specify either a name or an index')
+        link = c_void_p()
+        if sock is None:
+            with _pool.socket() as sock:
+                if name is None:
+                    err = _rtnl_link_get_kernel(sock, index, name, byref(link))
+                else:
+                    err = _rtnl_link_get_kernel(sock, index, name, byref(link))
+        else:
+            if name is None:
+                err = _rtnl_link_get_kernel(sock, index, name, byref(link))
+            else:
+                err = _rtnl_link_get_kernel(sock, index, name, byref(link))
+        if err:
+            raise IOError(-err, _nl_geterror())
+        return link
 else:
     from . import _alloc_cache
     _link_alloc_cache = _void_proto(('rtnl_link_alloc_cache', LIBNL_ROUTE))
     _rtnl_link_alloc_cache = partial(_alloc_cache, _link_alloc_cache)
     _rtnl_link_vlan_get_id = _int_proto(('rtnl_link_vlan_get_id', LIBNL_ROUTE))
 
+    def _get_link(name=None, index=None, sock=None):
+        if name is None and index is None:
+            raise ValueError('Must specify either a name or an index')
+        if sock is None:
+            with _pool.socket() as sock:
+                with _nl_link_cache(sock) as cache:
+                    if name is None:
+                        link = _rtnl_link_get(cache, index)
+                    else:
+                        link = _rtnl_link_get_by_name(cache, name)
+        else:
+            with _nl_link_cache(sock) as cache:
+                if name is None:
+                    link = _rtnl_link_get(cache, index)
+                else:
+                    link = _rtnl_link_get_by_name(cache, name)
+        return link
+
+
 _nl_link_cache = partial(_cache_manager, _rtnl_link_alloc_cache)
 
+_rtnl_link_get = CFUNCTYPE(c_void_p, c_void_p, c_int)((
+    'rtnl_link_get', LIBNL_ROUTE))
 _rtnl_link_get_addr = _void_proto(('rtnl_link_get_addr', LIBNL_ROUTE))
 _rtnl_link_get_flags = _int_proto(('rtnl_link_get_flags', LIBNL_ROUTE))
 _rtnl_link_get_ifindex = _int_proto(('rtnl_link_get_ifindex', LIBNL_ROUTE))


-- 
To view, visit http://gerrit.ovirt.org/32949
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0e6aaac0bdb58a0052b25f588e11de03bde3e12f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap at redhat.com>


More information about the vdsm-patches mailing list