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:
parent
8be878808e
commit
8b57a6d3fb
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue