Merge "Avoid race with udev during ovs agent startup"
This commit is contained in:
commit
caf9f8dc41
@ -32,6 +32,7 @@ from oslo.config import cfg
|
|||||||
from neutron.agent import l2population_rpc
|
from neutron.agent import l2population_rpc
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
from neutron.agent.linux import ovs_lib
|
from neutron.agent.linux import ovs_lib
|
||||||
|
from neutron.agent.linux import utils
|
||||||
from neutron.agent import rpc as agent_rpc
|
from neutron.agent import rpc as agent_rpc
|
||||||
from neutron.agent import securitygroups_rpc as sg_rpc
|
from neutron.agent import securitygroups_rpc as sg_rpc
|
||||||
from neutron.common import config as logging_config
|
from neutron.common import config as logging_config
|
||||||
@ -778,6 +779,10 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||||||
br.delete_port(phys_veth_name)
|
br.delete_port(phys_veth_name)
|
||||||
if ip_lib.device_exists(int_veth_name, self.root_helper):
|
if ip_lib.device_exists(int_veth_name, self.root_helper):
|
||||||
ip_lib.IPDevice(int_veth_name, self.root_helper).link.delete()
|
ip_lib.IPDevice(int_veth_name, self.root_helper).link.delete()
|
||||||
|
# Give udev a chance to process its rules here, to avoid
|
||||||
|
# race conditions between commands launched by udev rules
|
||||||
|
# and the subsequent call to ip_wrapper.add_veth
|
||||||
|
utils.execute(['/sbin/udevadm', 'settle', '--timeout=10'])
|
||||||
int_veth, phys_veth = ip_wrapper.add_veth(int_veth_name,
|
int_veth, phys_veth = ip_wrapper.add_veth(int_veth_name,
|
||||||
phys_veth_name)
|
phys_veth_name)
|
||||||
self.int_ofports[physical_network] = self.int_br.add_port(int_veth)
|
self.int_ofports[physical_network] = self.int_br.add_port(int_veth)
|
||||||
|
@ -23,6 +23,7 @@ import testtools
|
|||||||
|
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
from neutron.agent.linux import ovs_lib
|
from neutron.agent.linux import ovs_lib
|
||||||
|
from neutron.agent.linux import utils
|
||||||
from neutron.common import constants as n_const
|
from neutron.common import constants as n_const
|
||||||
from neutron.openstack.common.rpc import common as rpc_common
|
from neutron.openstack.common.rpc import common as rpc_common
|
||||||
from neutron.plugins.openvswitch.agent import ovs_neutron_agent
|
from neutron.plugins.openvswitch.agent import ovs_neutron_agent
|
||||||
@ -327,6 +328,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
with contextlib.nested(
|
with contextlib.nested(
|
||||||
mock.patch.object(ip_lib, "device_exists"),
|
mock.patch.object(ip_lib, "device_exists"),
|
||||||
mock.patch.object(sys, "exit"),
|
mock.patch.object(sys, "exit"),
|
||||||
|
mock.patch.object(utils, "execute"),
|
||||||
mock.patch.object(ovs_lib.OVSBridge, "remove_all_flows"),
|
mock.patch.object(ovs_lib.OVSBridge, "remove_all_flows"),
|
||||||
mock.patch.object(ovs_lib.OVSBridge, "add_flow"),
|
mock.patch.object(ovs_lib.OVSBridge, "add_flow"),
|
||||||
mock.patch.object(ovs_lib.OVSBridge, "add_port"),
|
mock.patch.object(ovs_lib.OVSBridge, "add_port"),
|
||||||
@ -337,15 +339,26 @@ class TestOvsNeutronAgent(base.BaseTestCase):
|
|||||||
mock.patch.object(ip_lib.IpLinkCommand, "delete"),
|
mock.patch.object(ip_lib.IpLinkCommand, "delete"),
|
||||||
mock.patch.object(ip_lib.IpLinkCommand, "set_up"),
|
mock.patch.object(ip_lib.IpLinkCommand, "set_up"),
|
||||||
mock.patch.object(ip_lib.IpLinkCommand, "set_mtu")
|
mock.patch.object(ip_lib.IpLinkCommand, "set_mtu")
|
||||||
) as (devex_fn, sysexit_fn, remflows_fn, ovs_addfl_fn,
|
) as (devex_fn, sysexit_fn, utilsexec_fn, remflows_fn, ovs_addfl_fn,
|
||||||
ovs_addport_fn, ovs_delport_fn, br_addport_fn,
|
ovs_addport_fn, ovs_delport_fn, br_addport_fn,
|
||||||
br_delport_fn, addveth_fn, linkdel_fn, linkset_fn, linkmtu_fn):
|
br_delport_fn, addveth_fn, linkdel_fn, linkset_fn, linkmtu_fn):
|
||||||
devex_fn.return_value = True
|
devex_fn.return_value = True
|
||||||
|
parent = mock.MagicMock()
|
||||||
|
parent.attach_mock(utilsexec_fn, 'utils_execute')
|
||||||
|
parent.attach_mock(linkdel_fn, 'link_delete')
|
||||||
|
parent.attach_mock(addveth_fn, 'add_veth')
|
||||||
addveth_fn.return_value = (ip_lib.IPDevice("int-br-eth1"),
|
addveth_fn.return_value = (ip_lib.IPDevice("int-br-eth1"),
|
||||||
ip_lib.IPDevice("phy-br-eth1"))
|
ip_lib.IPDevice("phy-br-eth1"))
|
||||||
ovs_addport_fn.return_value = "int_ofport"
|
ovs_addport_fn.return_value = "int_ofport"
|
||||||
br_addport_fn.return_value = "phys_veth"
|
br_addport_fn.return_value = "phys_veth"
|
||||||
self.agent.setup_physical_bridges({"physnet1": "br-eth"})
|
self.agent.setup_physical_bridges({"physnet1": "br-eth"})
|
||||||
|
expected_calls = [mock.call.link_delete(),
|
||||||
|
mock.call.utils_execute(['/sbin/udevadm',
|
||||||
|
'settle',
|
||||||
|
'--timeout=10']),
|
||||||
|
mock.call.add_veth('int-br-eth',
|
||||||
|
'phy-br-eth')]
|
||||||
|
parent.assert_has_calls(expected_calls, any_order=False)
|
||||||
self.assertEqual(self.agent.int_ofports["physnet1"],
|
self.assertEqual(self.agent.int_ofports["physnet1"],
|
||||||
"phys_veth")
|
"phys_veth")
|
||||||
self.assertEqual(self.agent.phys_ofports["physnet1"],
|
self.assertEqual(self.agent.phys_ofports["physnet1"],
|
||||||
|
Loading…
Reference in New Issue
Block a user