_bind_devices query only existing ports

If a port is deleted right before _bind_devices is called,
get_ports_attributes will throw an exception since the row
corresponding to the port doesn't exist in the OVS DB.
Avoid that setting if_exists to True. The port will be
processed as deleted by the agent in the following iteration.

Change-Id: Ia6590d76f8683e6cba562cde3c39b051549f6c04
Closes-bug: #1489014
This commit is contained in:
rossella 2015-08-26 16:06:25 +00:00
parent f4e980f7d5
commit 1b25e30800
2 changed files with 15 additions and 5 deletions

View File

@ -793,7 +793,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
devices_down = []
port_names = [p['vif_port'].port_name for p in need_binding_ports]
port_info = self.int_br.get_ports_attributes(
"Port", columns=["name", "tag"], ports=port_names)
"Port", columns=["name", "tag"], ports=port_names, if_exists=True)
tags_by_name = {x['name']: x['tag'] for x in port_info}
for port_detail in need_binding_ports:
lvm = self.local_vlan_map.get(port_detail['network_id'])
@ -805,6 +805,10 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
device = port_detail['device']
# Do not bind a port if it's already bound
cur_tag = tags_by_name.get(port.port_name)
if cur_tag is None:
LOG.info(_LI("Port %s was deleted concurrently, skipping it"),
port.port_name)
continue
if cur_tag != lvm.vlan:
self.int_br.delete_flows(in_port=port.ofport)
if self.prevent_arp_spoofing:

View File

@ -368,11 +368,17 @@ class TestOvsNeutronAgent(object):
devices_up = ['tap1']
devices_down = ['tap2']
self.agent.local_vlan_map["net1"] = mock.Mock()
ovs_db_list = [{'name': 'tap1', 'tag': []},
{'name': 'tap2', 'tag': []}]
vif_port1 = mock.Mock()
vif_port1.port_name = 'tap1'
vif_port2 = mock.Mock()
vif_port2.port_name = 'tap2'
port_details = [
{'network_id': 'net1', 'vif_port': mock.Mock(),
{'network_id': 'net1', 'vif_port': vif_port1,
'device': devices_up[0],
'admin_state_up': True},
{'network_id': 'net1', 'vif_port': mock.Mock(),
{'network_id': 'net1', 'vif_port': vif_port2,
'device': devices_down[0],
'admin_state_up': False}]
with mock.patch.object(
@ -383,7 +389,7 @@ class TestOvsNeutronAgent(object):
'failed_devices_down': []}) as update_devices, \
mock.patch.object(self.agent,
'int_br') as int_br:
int_br.db_list.return_value = []
int_br.get_ports_attributes.return_value = ovs_db_list
self.agent._bind_devices(port_details)
update_devices.assert_called_once_with(mock.ANY, devices_up,
devices_down,
@ -413,7 +419,7 @@ class TestOvsNeutronAgent(object):
mock.patch.object(
self.agent,
'setup_arp_spoofing_protection') as setup_arp:
int_br.db_list.return_value = ovs_db_list
int_br.get_ports_attributes.return_value = ovs_db_list
self.agent._bind_devices(need_binding_ports)
self.assertEqual(enable_prevent_arp_spoofing, setup_arp.called)