From: Jiri Pirko jiri@mellanox.com
Use pyroute2 to get list of devlink ports.
Signed-off-by: Jiri Pirko jiri@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@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] + 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):
From: Jiri Pirko jiri@mellanox.com
Allow tasks to get devlink and devlink port name.
Signed-off-by: Jiri Pirko jiri@mellanox.com --- lnst/Controller/Machine.py | 30 ++++++++++++++++++++++++++++++ lnst/Controller/Task.py | 12 ++++++++++++ 2 files changed, 42 insertions(+)
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py index 3e730bd..3725de6 100644 --- a/lnst/Controller/Machine.py +++ b/lnst/Controller/Machine.py @@ -606,6 +606,7 @@ class Interface(object): self._peer = None self._mtu = None self._driver = None + self._devlink = None
def get_id(self): return self._id @@ -779,6 +780,7 @@ class Interface(object): self.set_devname(if_data["name"]) self._mtu = if_data["mtu"] self._driver = if_data["driver"] + self._devlink = if_data["devlink"]
def get_config(self): config = {"id": self._id, @@ -921,6 +923,18 @@ class Interface(object): self.del_slave(self._machine.get_interface(if_id)) self._machine._rpc_call_x(self._netns, "slave_del", self._id, if_id)
+ def get_devlink_name(self): + if self._devlink: + return "%s/%s" % (self._devlink["bus_name"], + self._devlink["dev_name"]) + return None + + def get_devlink_port_name(self): + if self._devlink: + return "%s/%u" % (self.get_devlink_name(), + self._devlink["port_index"]) + return None + class StaticInterface(Interface): """ Static interface
@@ -1200,6 +1214,7 @@ class Device(object): self._peer = None self._mtu = None self._driver = None + self._devlink = None
self._machine = machine
@@ -1220,6 +1235,7 @@ class Device(object): self._peer = data["peer"] self._mtu = data["mtu"] self._driver = data["driver"] + self._devlink = data["driver"] return True
def slave_update(self): @@ -1298,3 +1314,17 @@ class Device(object): @pre_call_decorate def get_driver(self): return self._driver + + @pre_call_decorate + def get_devlink_name(self): + if self._devlink: + return "%s/%s" % (self._devlink["bus_name"], + self._devlink["dev_name"]) + return None + + @pre_call_decorate + def get_devlink_port_name(self): + if self._devlink: + return "%s/%u" % (self.get_devlink_name(), + self._devlink["port_index"]) + return None diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py index 178d774..6f36e86 100644 --- a/lnst/Controller/Task.py +++ b/lnst/Controller/Task.py @@ -532,6 +532,12 @@ class DeviceAPI(object): def get_driver(self): return self._dev.get_driver()
+ def get_devlink_name(self): + return self._dev.get_devlink_name() + + def get_devlink_port_name(self): + return self._dev.get_devlink_port_name() + class InterfaceAPI(object): def __init__(self, interface, host): self._if = interface @@ -673,6 +679,12 @@ class InterfaceAPI(object): def slave_del(self, slave_id): return self._if.slave_del(slave_id)
+ def get_devlink_name(self): + return self._if.get_devlink_name() + + def get_devlink_port_name(self): + return self._if.get_devlink_port_name() + class ModuleAPI(object): """ An API class representing a module. """
On Thu, Jul 14, 2016 at 05:43:03PM +0200, Jiri Pirko wrote:
From: Jiri Pirko jiri@mellanox.com
Use pyroute2 to get list of devlink ports.
Signed-off-by: Jiri Pirko jiri@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@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():
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.
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@lists.fedorahosted.org https://lists.fedorahosted.org/admin/lists/lnst-developers@lists.fedorahoste...
Fri, Jul 15, 2016 at 10:12:09AM CEST, olichtne@redhat.com wrote:
On Thu, Jul 14, 2016 at 05:43:03PM +0200, Jiri Pirko wrote:
From: Jiri Pirko jiri@mellanox.com
Use pyroute2 to get list of devlink ports.
Signed-off-by: Jiri Pirko jiri@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@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?
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@lists.fedorahosted.org https://lists.fedorahosted.org/admin/lists/lnst-developers@lists.fedorahoste...
On Fri, Jul 15, 2016 at 10:22:51AM +0200, Jiri Pirko wrote:
Fri, Jul 15, 2016 at 10:12:09AM CEST, olichtne@redhat.com wrote:
On Thu, Jul 14, 2016 at 05:43:03PM +0200, Jiri Pirko wrote:
From: Jiri Pirko jiri@mellanox.com
Use pyroute2 to get list of devlink ports.
Signed-off-by: Jiri Pirko jiri@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@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.
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@lists.fedorahosted.org https://lists.fedorahosted.org/admin/lists/lnst-developers@lists.fedorahoste...
Fri, Jul 15, 2016 at 10:38:37AM CEST, olichtne@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@redhat.com wrote:
On Thu, Jul 14, 2016 at 05:43:03PM +0200, Jiri Pirko wrote:
From: Jiri Pirko jiri@mellanox.com
Use pyroute2 to get list of devlink ports.
Signed-off-by: Jiri Pirko jiri@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@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@lists.fedorahosted.org https://lists.fedorahosted.org/admin/lists/lnst-developers@lists.fedorahoste...
lnst-developers@lists.fedorahosted.org