From: Ondrej Lichtner olichtne@redhat.com
After creating all the soft interfaces specified in the recipe, the Controller will now wait until the associated Device object on the Slave is initialized - this means waiting until there are no more devices left in the _tmp_mapping dictionary of InterfaceManager.
To do this we introduced a new NetTestSlave method - wait_interface_init that only returns after the InterfaceManager is ready.
This method is also called every time you create a device from inside a python task.
This should avoid potential race conditions that we've experienced.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com Tested-by: Jiri Pirko jiri@mellanox.com --- lnst/Controller/Machine.py | 3 +++ lnst/Controller/NetTestController.py | 2 ++ lnst/Controller/Task.py | 3 +++ lnst/Slave/InterfaceManager.py | 12 ++++++++++++ lnst/Slave/NetTestSlave.py | 4 ++++ 5 files changed, 24 insertions(+)
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py index d0e5b1b..755a2dd 100644 --- a/lnst/Controller/Machine.py +++ b/lnst/Controller/Machine.py @@ -500,6 +500,9 @@ class Machine(object): self._namespaces = [] return True
+ def wait_interface_init(self): + return self._rpc_call("wait_interface_init") + class Interface(object): """ Abstraction of a test network interface on a slave machine
diff --git a/lnst/Controller/NetTestController.py b/lnst/Controller/NetTestController.py index 04aa473..1e90688 100644 --- a/lnst/Controller/NetTestController.py +++ b/lnst/Controller/NetTestController.py @@ -223,6 +223,8 @@ class NetTestController: for iface in ifaces: iface.up()
+ m.wait_interface_init() + def provision_machines(self): sp = self._slave_pool machines = self._machines diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py index e354180..9aac8c4 100644 --- a/lnst/Controller/Task.py +++ b/lnst/Controller/Task.py @@ -404,6 +404,9 @@ class HostAPI(object):
interface.configure() interface.up() + + self._m.wait_interface_init() + return iface
def _remove_iface(self, iface): diff --git a/lnst/Slave/InterfaceManager.py b/lnst/Slave/InterfaceManager.py index dfc2d10..144f5a7 100644 --- a/lnst/Slave/InterfaceManager.py +++ b/lnst/Slave/InterfaceManager.py @@ -13,11 +13,13 @@ olichtne@redhat.com (Ondrej Lichtner) """
import re +import select from lnst.Slave.NetConfigDevice import NetConfigDevice from lnst.Slave.NetConfigCommon import get_option 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 pyroute2 import IPRSocket try: from pyroute2.netlink.iproute import RTM_NEWLINK @@ -210,6 +212,16 @@ class InterfaceManager(object): self._tmp_mapping[if_id2] = device2 return name1, name2
+ def wait_interface_init(self): + while len(self._tmp_mapping) > 0: + rl, wl, xl = select.select([self._nl_socket], [], [], 1) + + if len(rl) == 0: + continue + + msgs = recv_data(self._nl_socket)["data"] + self.handle_netlink_msgs(msgs) + def _is_name_used(self, name): for device in self._devices.itervalues(): if name == device.get_name(): diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py index 12b3381..5569f07 100644 --- a/lnst/Slave/NetTestSlave.py +++ b/lnst/Slave/NetTestSlave.py @@ -763,6 +763,10 @@ class SlaveMethods: return False return True
+ def wait_interface_init(self): + self._if_manager.wait_interface_init() + return True + class ServerHandler(ConnectionHandler): def __init__(self, addr): super(ServerHandler, self).__init__()
Tue, Jan 19, 2016 at 03:09:57PM IST, olichtne@redhat.com wrote:
From: Ondrej Lichtner olichtne@redhat.com
After creating all the soft interfaces specified in the recipe, the Controller will now wait until the associated Device object on the Slave is initialized - this means waiting until there are no more devices left in the _tmp_mapping dictionary of InterfaceManager.
To do this we introduced a new NetTestSlave method - wait_interface_init that only returns after the InterfaceManager is ready.
This method is also called every time you create a device from inside a python task.
This should avoid potential race conditions that we've experienced.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com Tested-by: Jiri Pirko jiri@mellanox.com
Thanks for taking care of this Ondrej!
Tue, Jan 19, 2016 at 02:09:57PM CET, olichtne@redhat.com wrote:
From: Ondrej Lichtner olichtne@redhat.com
After creating all the soft interfaces specified in the recipe, the Controller will now wait until the associated Device object on the Slave is initialized - this means waiting until there are no more devices left in the _tmp_mapping dictionary of InterfaceManager.
To do this we introduced a new NetTestSlave method - wait_interface_init that only returns after the InterfaceManager is ready.
This method is also called every time you create a device from inside a python task.
This should avoid potential race conditions that we've experienced.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com Tested-by: Jiri Pirko jiri@mellanox.com
applied, thanks!
lnst-developers@lists.fedorahosted.org