Plugging a device usually involves checking for the existence of the
device twice, once before calling plug and once after. It turns out
that these calls are expensive, often taking a half second or more
each. For that reason, it is worth the effort to make sure we check
only once.
The device driver is now responsible for cleanly plugging/unplugging
the device without knowing whether it exists or not. Pushing this
responsibility to the device driver allows implementing it more
efficiently in terms of calls made out to the operating system.
This is targetted at the neutron-tempest-parallel bp because it shaves
time off the time to set up a router, something that hinders parallel
performance.
Change-Id: I391fafe68b76e1c620d2b25e8613ba507fd25dfd
Partial-Bug: #
1287824
def external_gateway_added(self, ri, ex_gw_port,
interface_name, internal_cidrs):
- if not ip_lib.device_exists(interface_name,
- root_helper=self.root_helper,
- namespace=ri.ns_name()):
- self.driver.plug(ex_gw_port['network_id'],
- ex_gw_port['id'], interface_name,
- ex_gw_port['mac_address'],
- bridge=self.conf.external_network_bridge,
- namespace=ri.ns_name(),
- prefix=EXTERNAL_DEV_PREFIX)
+ self.driver.plug(ex_gw_port['network_id'],
+ ex_gw_port['id'], interface_name,
+ ex_gw_port['mac_address'],
+ bridge=self.conf.external_network_bridge,
+ namespace=ri.ns_name(),
+ prefix=EXTERNAL_DEV_PREFIX)
# Compute a list of addresses this router is supposed to have.
# This avoids unnecessarily removing those addresses and
def external_gateway_removed(self, ri, ex_gw_port,
interface_name, internal_cidrs):
- if ip_lib.device_exists(interface_name,
- root_helper=self.root_helper,
- namespace=ri.ns_name()):
- self.driver.unplug(interface_name,
- bridge=self.conf.external_network_bridge,
- namespace=ri.ns_name(),
- prefix=EXTERNAL_DEV_PREFIX)
+ self.driver.unplug(interface_name,
+ bridge=self.conf.external_network_bridge,
+ namespace=ri.ns_name(),
+ prefix=EXTERNAL_DEV_PREFIX)
def metadata_filter_rules(self):
rules = []
if not bridge:
bridge = self.conf.ovs_integration_bridge
- self.check_bridge_exists(bridge)
-
if not ip_lib.device_exists(device_name,
self.root_helper,
namespace=namespace):
+ self.check_bridge_exists(bridge)
+
ip = ip_lib.IPWrapper(self.root_helper)
tap_name = self._get_tap_name(device_name, prefix)
if self.conf.ovs_use_veth:
root_dev.link.set_up()
else:
- LOG.warn(_("Device %s already exists"), device_name)
+ LOG.info(_("Device %s already exists"), device_name)
def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
"""Unplug the interface."""
utils.execute(cmd, self.root_helper)
else:
- LOG.warn(_("Device %s already exists"), device_name)
+ LOG.info(_("Device %s already exists"), device_name)
def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
# the port will be deleted by the dhcp agent that will call the plugin
device = ip_lib.IPDevice(device_name,
self.root_helper,
namespace)
- device.link.delete()
+ try:
+ device.link.delete()
+ except RuntimeError:
+ LOG.error(_("Failed unplugging interface '%s'"), device_name)
LOG.debug(_("Unplugged interface '%s'"), device_name)
ip_lib.IPWrapper(
ns_dev.link.set_up()
root_dev.link.set_up()
else:
- LOG.warn(_("Device %s already exists"), device_name)
+ LOG.info(_("Device %s already exists"), device_name)
def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
"""Unplug the interface."""
ns_veth.link.set_up()
else:
- LOG.warn(_("Device %s already exists"), device_name)
+ LOG.info(_("Device %s already exists"), device_name)
def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
"""Unplug the interface."""
agent.process_router_floating_ip_nat_rules = mock.Mock()
agent.process_router_floating_ip_addresses.return_value = {
fake_fip_id: 'ACTIVE'}
+ agent.external_gateway_added = mock.Mock()
router = self._prepare_router_data()
fake_floatingips1 = {'floatingips': [
{'id': fake_fip_id,
router = self._prepare_router_data(enable_snat=True)
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
# Process with NAT
agent.process_router(ri)
orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
router = self._prepare_router_data(enable_snat=False)
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
# Process without NAT
agent.process_router(ri)
orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
router = self._prepare_router_data()
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
# Process with NAT
agent.process_router(ri)
orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
router = self._prepare_router_data(num_internal_ports=2)
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
# Process with NAT
agent.process_router(ri)
orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
router = self._prepare_router_data()
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
with mock.patch.object(
l3_agent.L3NATAgent,
'internal_network_added') as internal_network_added:
router = self._prepare_router_data()
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
# add an internal port
agent.process_router(ri)
ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
self.conf.use_namespaces, router=router)
+ agent.external_gateway_added = mock.Mock()
agent.process_router(ri)
# Assess the call for putting the floating IP up was performed
mock_update_fip_status.assert_called_once_with(
def test_plug_dev_exists(self):
self.device_exists.return_value = True
- with mock.patch('neutron.agent.linux.interface.LOG.warn') as log:
+ with mock.patch('neutron.agent.linux.interface.LOG.info') as log:
br = interface.BridgeInterfaceDriver(self.conf)
br.plug('01234567-1234-1234-99',
'port-1234',