Fri, Jul 15, 2016 at 10:38:37AM CEST, olichtne(a)redhat.com wrote:
On Fri, Jul 15, 2016 at 10:22:51AM +0200, Jiri Pirko wrote:
> Fri, Jul 15, 2016 at 10:12:09AM CEST, olichtne(a)redhat.com wrote:
> >On Thu, Jul 14, 2016 at 05:43:03PM +0200, Jiri Pirko wrote:
> >> From: Jiri Pirko <jiri(a)mellanox.com>
> >>
> >> Use pyroute2 to get list of devlink ports.
> >>
> >> Signed-off-by: Jiri Pirko <jiri(a)mellanox.com>
> >> ---
> >> lnst/Slave/DevlinkManager.py | 63
++++++++++++++++++++++++++++++++++++++++++
> >> lnst/Slave/InterfaceManager.py | 16 ++++++++++-
> >> 2 files changed, 78 insertions(+), 1 deletion(-)
> >> create mode 100644 lnst/Slave/DevlinkManager.py
> >>
> >> diff --git a/lnst/Slave/DevlinkManager.py b/lnst/Slave/DevlinkManager.py
> >> new file mode 100644
> >> index 0000000..13662bc
> >> --- /dev/null
> >> +++ b/lnst/Slave/DevlinkManager.py
> >> @@ -0,0 +1,63 @@
> >> +"""
> >> +This module defines the DevlinkManager class that contains a database of
> >> +the available devlink devices, handles netlink messages updating these
devices.
> >> +
> >> +Copyright 2016 Mellanox Technologies. All rights reserved.
> >> +Licensed under the GNU General Public License, version 2 as
> >> +published by the Free Software Foundation; see COPYING for details.
> >> +"""
> >> +
> >> +__author__ = """
> >> +jiri(a)mellanox.com (Jiri Pirko)
> >> +"""
> >> +
> >> +try:
> >> + from pyroute2 import DL
> >> + from pyroute2.netlink.exceptions import NetlinkError
> >> +
> >> + def dl_open():
> >> + try:
> >> + return DL()
> >> + except NetlinkError:
> >> + return None
> >> +
> >> +except ImportError:
> >> + class DL(object):
> >> + def port_list(self):
> >> + return []
> >> +
> >> + def close(self):
> >> + return
> >> +
> >> + def dl_open():
> >> + return DL()
> >> +
> >> +class DevlinkManager(object):
> >> + def __init__(self):
> >> + self.rescan_ports()
> >> +
> >> + def rescan_ports(self):
> >> + self._ports = []
> >> +
> >> + dl = dl_open()
> >> + if not dl:
> >> + return
> >> +
> >> + try:
> >> + for q in dl.port_list():
> >> + dl_port = {}
> >> + dl_port["bus_name"] =
q.get_attr('DEVLINK_ATTR_BUS_NAME')
> >> + dl_port["dev_name"] =
q.get_attr('DEVLINK_ATTR_DEV_NAME')
> >> + dl_port["port_index"] =
q.get_attr('DEVLINK_ATTR_PORT_INDEX')
> >> + dl_port["port_netdev_name"] =
q.get_attr('DEVLINK_ATTR_PORT_NETDEV_NAME')
> >> + self._ports.append(dl_port)
> >> + except:
> >> + raise
> >> + finally:
> >> + dl.close()
> >> +
> >> + def get_port(self, ifname):
> >> + for dl_port in self._ports:
> >> + if dl_port["port_netdev_name"] == ifname:
> >> + return dl_port
> >> + return None
> >> diff --git a/lnst/Slave/InterfaceManager.py
b/lnst/Slave/InterfaceManager.py
> >> index 5852254..d3e903b 100644
> >> --- a/lnst/Slave/InterfaceManager.py
> >> +++ b/lnst/Slave/InterfaceManager.py
> >> @@ -21,6 +21,7 @@ from lnst.Common.NetUtils import normalize_hwaddr
> >> from lnst.Common.NetUtils import scan_netdevs
> >> from lnst.Common.ExecCmd import exec_cmd
> >> from lnst.Common.ConnectionHandler import recv_data
> >> +from lnst.Slave.DevlinkManager import DevlinkManager
> >> from pyroute2 import IPRSocket
> >> from pyroute2.netlink.rtnl import RTNLGRP_IPV4_IFADDR
> >> from pyroute2.netlink.rtnl import RTNLGRP_IPV6_IFADDR
> >> @@ -50,6 +51,8 @@ class InterfaceManager(object):
> >> self._nl_socket = IPRSocket()
> >> self._nl_socket.bind(groups=NL_GROUPS)
> >>
> >> + self._dl_manager = DevlinkManager()
> >> +
> >> self.rescan_devices()
> >>
> >> self._server_handler = server_handler
> >> @@ -129,6 +132,12 @@ class InterfaceManager(object):
> >> self._server_handler.send_data_to_ctl(del_msg)
> >> del self._devices[i]
> >>
> >> + self._dl_manager.rescan_ports()
> >> + for key in self._devices:
> >> + device = self._devices[key]
> >
> >You can just do this:
> >for device in self._devices.values():
> >
> >or:
> >for key, device in self._devices.items():
>
> Ok.
>
>
> >
> >
> >In addition to that... is it enough for you to scan devlink only when we
> >call rescan_devices()? The InterfaceManager also listens fo Netlink
> >updates and reacts to them, rescan_devices() is called less often and
> >technically isn't guaranteed to be called during task execution. It
> >get's called when you "get_device" or when you're creating new
> >interfaces but unless you're doing that periodically (on the controller)
> >it might never get called.
>
> Okay, could you suggest a place from where to call it?
With the InterfaceManager I put it's Netlink socket into the
ServerHandler in the NetTestSlave module so it's part of the main
select() loop. The messages are then handled by the InterfaceManager
class. I'd say this would be the ideal solution but it's a bit more
complicated and will require a bit more coding.
An easier solution would be to also put the rescan_ports() call inside
the handle_netlink_msgs() method and then add the set_devlink() call to
the _handle_netlink_msg() method into branche that handles the
RTM_NEWLINK messages.
This will ensure that the devlink related info is updated every time
anything regarding interfaces is updated. If you want the devlink info
updated every time the kernel sends an devlink update message through
Netlink then you'll need the first solution.
Will check it. Thanks.
>
>>
>>
>> >
>> >
>> >Other than that I the patches look fine.
>> >
>> >> + dl_port = self._dl_manager.get_port(device.get_name())
>> >> + device.set_devlink(dl_port)
>> >> +
>> >> def handle_netlink_msgs(self, msgs):
>> >> for msg in msgs:
>> >> self._handle_netlink_msg(msg)
>> >> @@ -354,9 +363,13 @@ class Device(object):
>> >> self._peer = None
>> >> self._mtu = None
>> >> self._driver = None
>> >> + self._devlink = None
>> >>
>> >> self._if_manager = if_manager
>> >>
>> >> + def set_devlink(self, devlink_port_data):
>> >> + self._devlink = devlink_port_data
>> >> +
>> >> def init_netlink(self, nl_msg):
>> >> self._if_index = nl_msg['index']
>> >> self._ifi_type = nl_msg['ifi_type']
>> >> @@ -672,7 +685,8 @@ class Device(object):
>> >> "netns": self._netns,
>> >> "peer": self._peer.get_if_index() if
self._peer else None,
>> >> "mtu": self._mtu,
>> >> - "driver": self._driver}
>> >> + "driver": self._driver,
>> >> + "devlink": self._devlink}
>> >> return if_data
>> >>
>> >> def set_speed(self, speed):
>> >> --
>> >> 2.5.5
>> >> _______________________________________________
>> >> LNST-developers mailing list
>> >> lnst-developers(a)lists.fedorahosted.org
>> >>
https://lists.fedorahosted.org/admin/lists/lnst-developers@lists.fedoraho...