Fix corner case in failure assigning MAC to SR-IOV NIC

Sometimes due to NIC driver incorrect behavior, VFs might be
missing in 'ip link show' output.  This may lead to a VM boot
failure as agent will just skip such missing devices.

Make the agent do a resync in case a newly added device
'disappears' during processing, which should cause a MAC to
get assigned.

Co-authored-by: Oleg Bondarev <obondarev@mirantis.com>

Change-Id: I148b5a025fc388821fd1269d02908cc8ce1882fe
Closes-bug: #1784484
(cherry picked from commit eea5aaac4f)
This commit is contained in:
Brian Haley 2018-09-20 14:15:49 -04:00 committed by Brian Haley
parent 8be878808e
commit 8b57a6d3fb
2 changed files with 33 additions and 1 deletions

View File

@ -289,6 +289,7 @@ class SriovNicSwitchAgent(object):
devices_up = set()
devices_down = set()
resync = False
for device_details in devices_details_list:
device = device_details['device']
LOG.debug("Port with MAC address %s is added", device)
@ -307,6 +308,8 @@ class SriovNicSwitchAgent(object):
devices_up.add(device)
else:
devices_down.add(device)
else:
resync = True
self._update_network_ports(device_details['network_id'],
port_id,
(device, profile.get('pci_slot')))
@ -319,7 +322,7 @@ class SriovNicSwitchAgent(object):
devices_down,
self.agent_id,
self.conf.host)
return False
return resync
def treat_devices_removed(self, devices):
resync = False

View File

@ -428,6 +428,15 @@ class TestSriovAgent(base.BaseTestCase):
self.assertFalse(agent.treat_device('aa:bb:cc:dd:ee:ff', '1:2:3:0',
admin_state_up=True))
def test_treat_device_no_device_found(self):
agent = self.agent
agent.plugin_rpc = mock.Mock()
agent.eswitch_mgr = mock.Mock()
agent.eswitch_mgr.device_exists.return_value = False
self.assertFalse(agent.treat_device('aa:bb:cc:dd:ee:ff', '1:2:3:0',
admin_state_up=True))
def test_treat_devices_added_updated_admin_state_up_false(self):
agent = self.agent
mock_details = {'device': 'aa:bb:cc:dd:ee:ff',
@ -453,6 +462,26 @@ class TestSriovAgent(base.BaseTestCase):
mock.ANY,
mock.ANY)
def test_treat_devices_added_updated_no_device_found(self):
agent = self.agent
mock_details = {'device': 'aa:bb:cc:dd:ee:ff',
'port_id': 'port123',
'network_id': 'net123',
'admin_state_up': True,
'network_type': 'vlan',
'segmentation_id': 100,
'profile': {'pci_slot': '1:2:3.0'},
'physical_network': 'physnet1'}
agent.plugin_rpc = mock.Mock()
agent.plugin_rpc.get_devices_details_list.return_value = [mock_details]
agent.remove_port_binding = mock.Mock()
agent.eswitch_mgr = mock.Mock()
agent.eswitch_mgr.device_exists.return_value = False
resync_needed = agent.treat_devices_added_updated(
set(['aa:bb:cc:dd:ee:ff']))
self.assertTrue(resync_needed)
self.assertFalse(agent.plugin_rpc.update_device_up.called)
def test_update_and_clean_network_ports(self):
network_id1 = 'network_id1'
network_id2 = 'network_id2'