Merge "Allow the other nic to allocate VMs post PCI-PT VM creation." into stable/newton
This commit is contained in:
commit
8cbcd74336
|
@ -62,6 +62,10 @@ class PciOsWrapper(object):
|
|||
vf_list.append((pci_slot, vf_index))
|
||||
return vf_list
|
||||
|
||||
@classmethod
|
||||
def pf_device_exists(cls, dev_name):
|
||||
return os.path.isdir(cls.DEVICE_PATH % dev_name)
|
||||
|
||||
@classmethod
|
||||
def is_assigned_vf(cls, dev_name, vf_index, ip_link_show_output):
|
||||
"""Check if VF is assigned.
|
||||
|
@ -75,12 +79,19 @@ class PciOsWrapper(object):
|
|||
@param vf_index: vf index
|
||||
@param ip_link_show_output: 'ip link show' output
|
||||
"""
|
||||
|
||||
if not cls.pf_device_exists(dev_name):
|
||||
# If the root PCI path does not exist, then the VF cannot
|
||||
# actually have been allocated and there is no way we can
|
||||
# manage it.
|
||||
return False
|
||||
|
||||
path = cls.PCI_PATH % (dev_name, vf_index)
|
||||
|
||||
try:
|
||||
ifname_list = os.listdir(path)
|
||||
except OSError:
|
||||
# PCI_PATH does not exist means that the DIRECT VF assigend
|
||||
# PCI_PATH does not exist means that the DIRECT VF assigned
|
||||
return True
|
||||
|
||||
# Note(moshele) kernel < 3.13 doesn't create symbolic link
|
||||
|
@ -351,6 +362,26 @@ class ESwitchManager(object):
|
|||
embedded_switch.set_device_spoofcheck(pci_slot,
|
||||
enabled)
|
||||
|
||||
def _process_emb_switch_map(self, phys_net, dev_name, exclude_devices):
|
||||
"""Process emb_switch_map
|
||||
@param phys_net: physical network
|
||||
@param dev_name: device name
|
||||
@param exclude_devices: PCI devices to ignore.
|
||||
"""
|
||||
emb_switches = self.emb_switches_map.get(phys_net, [])
|
||||
for switch in emb_switches:
|
||||
if switch.dev_name == dev_name:
|
||||
if not PciOsWrapper.pf_device_exists(dev_name):
|
||||
# If the device is given to the VM as PCI-PT
|
||||
# then delete the respective emb_switch from map
|
||||
self.emb_switches_map.get(phys_net).remove(switch)
|
||||
return
|
||||
|
||||
# We don't know about this device at the moment, so add to the map.
|
||||
if PciOsWrapper.pf_device_exists(dev_name):
|
||||
self._create_emb_switch(phys_net, dev_name,
|
||||
exclude_devices.get(dev_name, set()))
|
||||
|
||||
def discover_devices(self, device_mappings, exclude_devices):
|
||||
"""Discover which Virtual functions to manage.
|
||||
|
||||
|
@ -362,8 +393,8 @@ class ESwitchManager(object):
|
|||
exclude_devices = {}
|
||||
for phys_net, dev_names in six.iteritems(device_mappings):
|
||||
for dev_name in dev_names:
|
||||
self._create_emb_switch(phys_net, dev_name,
|
||||
exclude_devices.get(dev_name, set()))
|
||||
self._process_emb_switch_map(phys_net, dev_name,
|
||||
exclude_devices)
|
||||
|
||||
def _create_emb_switch(self, phys_net, dev_name, exclude_devices):
|
||||
embedded_switch = EmbSwitch(phys_net, dev_name, exclude_devices)
|
||||
|
|
|
@ -113,6 +113,8 @@ class SriovNicSwitchAgent(object):
|
|||
self.polling_interval = polling_interval
|
||||
self.network_ports = collections.defaultdict(list)
|
||||
self.conf = cfg.CONF
|
||||
self.device_mappings = physical_devices_mappings
|
||||
self.exclude_devices = exclude_devices
|
||||
self.setup_eswitch_mgr(physical_devices_mappings,
|
||||
exclude_devices)
|
||||
|
||||
|
@ -376,6 +378,8 @@ class SriovNicSwitchAgent(object):
|
|||
updated_devices_copy = self.updated_devices
|
||||
self.updated_devices = set()
|
||||
try:
|
||||
self.eswitch_mgr.discover_devices(self.device_mappings,
|
||||
self.exclude_devices)
|
||||
device_info = self.scan_devices(devices, updated_devices_copy)
|
||||
if self._device_info_has_changes(device_info):
|
||||
LOG.debug("Agent loop found changes! %s", device_info)
|
||||
|
|
|
@ -41,6 +41,9 @@ class TestCreateESwitchManager(base.BaseTestCase):
|
|||
"eswitch_manager.PciOsWrapper.scan_vf_devices",
|
||||
side_effect=exc.InvalidDeviceError(
|
||||
dev_name="p6p1", reason="device" " not found")),\
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.is_assigned_vf",
|
||||
return_value=True):
|
||||
|
@ -55,6 +58,9 @@ class TestCreateESwitchManager(base.BaseTestCase):
|
|||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.scan_vf_devices",
|
||||
return_value=self.SCANNED_DEVICES),\
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.is_assigned_vf",
|
||||
return_value=True):
|
||||
|
@ -91,11 +97,36 @@ class TestESwitchManagerApi(base.BaseTestCase):
|
|||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.scan_vf_devices",
|
||||
return_value=self.SCANNED_DEVICES), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.is_assigned_vf",
|
||||
return_value=True):
|
||||
eswitch_mgr.discover_devices(device_mappings, None)
|
||||
|
||||
def test_discover_devices_with_device(self):
|
||||
device_mappings = {'physnet1': ['p6p1', 'p6p2']}
|
||||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.ESwitchManager._create_emb_switch",
|
||||
) as emb_switch:
|
||||
self.eswitch_mgr.discover_devices(device_mappings, None)
|
||||
self.assertTrue(emb_switch.called)
|
||||
|
||||
def test_discover_devices_without_device(self):
|
||||
device_mappings = {'physnet1': ['p6p1', 'p6p2']}
|
||||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=False), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.ESwitchManager._create_emb_switch",
|
||||
) as emb_switch:
|
||||
self.eswitch_mgr.discover_devices(device_mappings, None)
|
||||
self.assertFalse(emb_switch.called)
|
||||
|
||||
def test_get_assigned_devices_info(self):
|
||||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.EmbSwitch.get_assigned_devices_info",
|
||||
|
@ -248,6 +279,36 @@ class TestESwitchManagerApi(base.BaseTestCase):
|
|||
'device_mac': self.WRONG_MAC})
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_process_emb_switch_without_device(self):
|
||||
device_mappings = {'physnet1': ['p6p1', 'p6p2']}
|
||||
phys_net = 'physnet1'
|
||||
dev_name = 'p6p1'
|
||||
self._set_eswitch_manager(self.eswitch_mgr, device_mappings)
|
||||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=False), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.ESwitchManager._create_emb_switch",
|
||||
) as emb_switch:
|
||||
self.eswitch_mgr._process_emb_switch_map(phys_net,
|
||||
dev_name, {})
|
||||
self.assertFalse(emb_switch.called)
|
||||
|
||||
def test_process_emb_switch_with_device(self):
|
||||
device_mappings = {'physnet1': ['p6p1', 'p6p2']}
|
||||
phys_net = 'physnet1'
|
||||
dev_name = 'p6p3'
|
||||
self._set_eswitch_manager(self.eswitch_mgr, device_mappings)
|
||||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.ESwitchManager._create_emb_switch",
|
||||
) as emb_switch:
|
||||
self.eswitch_mgr._process_emb_switch_map(phys_net,
|
||||
dev_name, {})
|
||||
self.assertTrue(emb_switch.called)
|
||||
|
||||
def _test_clear_rate(self, rate_type, pci_slot, passed, mac_address):
|
||||
with mock.patch('neutron.plugins.ml2.drivers.mech_sriov.agent.'
|
||||
'eswitch_manager.EmbSwitch.set_device_rate') \
|
||||
|
@ -257,7 +318,10 @@ class TestESwitchManagerApi(base.BaseTestCase):
|
|||
return_value=mac_address), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"pci_lib.PciDeviceIPWrapper.link_show",
|
||||
return_value=''):
|
||||
return_value=''), \
|
||||
mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True):
|
||||
self.eswitch_mgr.clear_rate(pci_slot, rate_type)
|
||||
if passed:
|
||||
set_rate_mock.assert_called_once_with(pci_slot, rate_type, 0)
|
||||
|
@ -557,9 +621,13 @@ class TestPciOsWrapper(base.BaseTestCase):
|
|||
|
||||
@mock.patch("os.listdir", side_effect=OSError())
|
||||
def test_is_assigned_vf_true(self, *args):
|
||||
self.assertTrue(esm.PciOsWrapper.is_assigned_vf(
|
||||
self.DEV_NAME, self.VF_INDEX, ''))
|
||||
with mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent."
|
||||
"eswitch_manager.PciOsWrapper.pf_device_exists",
|
||||
return_value=True):
|
||||
self.assertTrue(esm.PciOsWrapper.is_assigned_vf(
|
||||
self.DEV_NAME, self.VF_INDEX, ''))
|
||||
|
||||
@mock.patch("os.path.exists", return_value=True)
|
||||
@mock.patch("os.listdir", return_value=[DEV_NAME, "eth1"])
|
||||
@mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
|
||||
"PciDeviceIPWrapper.is_macvtap_assigned", return_value=False)
|
||||
|
@ -567,6 +635,7 @@ class TestPciOsWrapper(base.BaseTestCase):
|
|||
self.assertFalse(esm.PciOsWrapper.is_assigned_vf(
|
||||
self.DEV_NAME, self.VF_INDEX, ''))
|
||||
|
||||
@mock.patch("os.path.exists", return_value=True)
|
||||
@mock.patch("os.listdir", return_value=["eth0", "eth1"])
|
||||
@mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
|
||||
"PciDeviceIPWrapper.is_macvtap_assigned", return_value=True)
|
||||
|
@ -575,6 +644,7 @@ class TestPciOsWrapper(base.BaseTestCase):
|
|||
esm.PciOsWrapper.is_assigned_vf(self.DEV_NAME, self.VF_INDEX, '')
|
||||
mock_is_macvtap_assigned.called_with(self.VF_INDEX, "eth0")
|
||||
|
||||
@mock.patch("os.path.exists", return_value=True)
|
||||
@mock.patch("os.listdir", side_effect=OSError())
|
||||
@mock.patch("neutron.plugins.ml2.drivers.mech_sriov.agent.pci_lib."
|
||||
"PciDeviceIPWrapper.is_macvtap_assigned")
|
||||
|
@ -582,3 +652,18 @@ class TestPciOsWrapper(base.BaseTestCase):
|
|||
self, mock_is_macvtap_assigned, *args):
|
||||
esm.PciOsWrapper.is_assigned_vf(self.DEV_NAME, self.VF_INDEX, '')
|
||||
self.assertFalse(mock_is_macvtap_assigned.called)
|
||||
|
||||
@mock.patch("os.path.exists", return_value=False)
|
||||
@mock.patch("os.listdir", return_value=["eth0", "eth1"])
|
||||
def test_is_assigned_vf_pf_disappeared(self, list_dir_mock, *args):
|
||||
self.assertFalse(esm.PciOsWrapper.is_assigned_vf(
|
||||
self.DEV_NAME, self.VF_INDEX, ''))
|
||||
self.assertFalse(list_dir_mock.called)
|
||||
|
||||
def test_pf_device_exists_with_no_dir(self):
|
||||
with mock.patch("os.path.isdir", return_value=False):
|
||||
self.assertFalse(esm.PciOsWrapper.pf_device_exists('p6p1'))
|
||||
|
||||
def test_pf_device_exists_with_dir(self):
|
||||
with mock.patch("os.path.isdir", return_value=True):
|
||||
self.assertTrue(esm.PciOsWrapper.pf_device_exists('p6p1'))
|
||||
|
|
Loading…
Reference in New Issue