From e2c2f29fd171a688cc5bc6a73cdf7fec38aedd67 Mon Sep 17 00:00:00 2001 From: Saravanan KR Date: Wed, 14 Sep 2016 15:55:26 +0530 Subject: Add mac address to the DPDK mapping file When using mapping file with mac address, mapping logic will try to fetch the mac address of the interface, which will fail. Storing the mac address also in the DPDK mapping file so that we can satisfy mapping logic. Closes-Bug: #1619330 Change-Id: I92ba7f589c8d848feb083f07c3f937b50aca388e --- os_net_config/tests/test_utils.py | 49 ++++++++++++++++++++++++++------------- os_net_config/utils.py | 29 +++++++++++++++++++++-- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/os_net_config/tests/test_utils.py b/os_net_config/tests/test_utils.py index a2d5cc4..b766384 100644 --- a/os_net_config/tests/test_utils.py +++ b/os_net_config/tests/test_utils.py @@ -109,7 +109,13 @@ class TestUtils(base.TestCase): return out, None if 'driverctl' in name: return None, None + + def test_get_dpdk_mac_address(name): + return '01:02:03:04:05:06' self.stubs.Set(processutils, 'execute', test_execute) + self.stubs.Set(utils, '_get_dpdk_mac_address', + test_get_dpdk_mac_address) + utils.bind_dpdk_interfaces('nic2', 'vfio-pci', False) def test_bind_dpdk_interfaces_fail(self): @@ -119,34 +125,38 @@ class TestUtils(base.TestCase): return out, None if 'driverctl' in name: return None, 'Error' + + def test_get_dpdk_mac_address(name): + return '01:02:03:04:05:06' self.stubs.Set(processutils, 'execute', test_execute) + self.stubs.Set(utils, '_get_dpdk_mac_address', + test_get_dpdk_mac_address) + self.assertRaises(utils.OvsDpdkBindException, - utils.bind_dpdk_interfaces, 'nic2', 'vfio-pci', + utils.bind_dpdk_interfaces, 'eth1', 'vfio-pci', False) - def test_update_dpdk_map_new(self): - utils._update_dpdk_map('eth1', '0000:03:00.0', 'vfio-pci') - try: - contents = utils.get_file_data(utils._DPDK_MAPPING_FILE) - except IOError: - pass + def test__update_dpdk_map_new(self): + utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06', + 'vfio-pci') + contents = utils.get_file_data(utils._DPDK_MAPPING_FILE) dpdk_map = yaml.load(contents) if contents else [] self.assertEqual(1, len(dpdk_map)) dpdk_test = [{'name': 'eth1', 'pci_address': '0000:03:00.0', + 'mac_address': '01:02:03:04:05:06', 'driver': 'vfio-pci'}] self.assertListEqual(dpdk_test, dpdk_map) def test_update_dpdk_map_exist(self): dpdk_test = [{'name': 'eth1', 'pci_address': '0000:03:00.0', + 'mac_address': '01:02:03:04:05:06', 'driver': 'vfio-pci'}] utils.write_yaml_config(utils._DPDK_MAPPING_FILE, dpdk_test) - utils._update_dpdk_map('eth1', '0000:03:00.0', 'vfio-pci') - try: - contents = utils.get_file_data(utils._DPDK_MAPPING_FILE) - except IOError: - pass + utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06', + 'vfio-pci') + contents = utils.get_file_data(utils._DPDK_MAPPING_FILE) dpdk_map = yaml.load(contents) if contents else [] self.assertEqual(1, len(dpdk_map)) @@ -158,8 +168,10 @@ class TestUtils(base.TestCase): utils.write_yaml_config(utils._DPDK_MAPPING_FILE, dpdk_test) dpdk_test = [{'name': 'eth1', 'pci_address': '0000:03:00.0', - 'driver': 'igb_uio'}] - utils._update_dpdk_map('eth1', '0000:03:00.0', 'igb_uio') + 'mac_address': '01:02:03:04:05:06', + 'driver': 'vfio-pci'}] + utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06', + 'vfio-pci') try: contents = utils.get_file_data(utils._DPDK_MAPPING_FILE) except IOError: @@ -183,8 +195,10 @@ class TestUtils(base.TestCase): with open(os.path.join(tmpdir, nic), 'w') as f: f.write(nic) - utils._update_dpdk_map('eth1', '0000:03:00.0', 'igb_uio') - utils._update_dpdk_map('p3p1', '0000:04:00.0', 'igb_uio') + utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06', + 'vfio-pci') + utils._update_dpdk_map('p3p1', '0000:04:00.0', '01:02:03:04:05:07', + 'igb_uio') nics = utils.ordered_active_nics() @@ -200,3 +214,6 @@ class TestUtils(base.TestCase): self.assertEqual('z1', nics[9]) shutil.rmtree(tmpdir) + + def test_interface_mac_raises(self): + self.assertRaises(IOError, utils.interface_mac, 'ens20f2p3') diff --git a/os_net_config/utils.py b/os_net_config/utils.py index 95325a3..af359d5 100644 --- a/os_net_config/utils.py +++ b/os_net_config/utils.py @@ -25,6 +25,14 @@ from oslo_concurrency import processutils logger = logging.getLogger(__name__) _SYS_CLASS_NET = '/sys/class/net' +# File to contain the DPDK mapped nics, as nic name will not be available after +# binding driver, which is required for correct nic numbering. +# Format of the file (list mapped nic's details): +# - +# name: eth1 +# pci_address: 0000:02:00.0 +# mac_address: 01:02:03:04:05:06 +# driver: vfio-pci _DPDK_MAPPING_FILE = '/var/lib/os-net-config/dpdk_mapping.yaml' @@ -73,6 +81,12 @@ def interface_mac(name): with open('/sys/class/net/%s/address' % name, 'r') as f: return f.read().rstrip() except IOError: + # If the interface is bound to a DPDK driver, get the mac address from + # the dpdk mapping file as /sys files will be removed after binding. + dpdk_mac_address = _get_dpdk_mac_address(name) + if dpdk_mac_address: + return dpdk_mac_address + logger.error("Unable to read mac address: %s" % name) raise @@ -176,6 +190,7 @@ def bind_dpdk_interfaces(ifname, driver, noop): msg = "Failed to modprobe vfio-pci module" raise OvsDpdkBindException(msg) + mac_address = interface_mac(ifname) try: out, err = processutils.execute('driverctl', 'set-override', pci_address, driver) @@ -183,7 +198,7 @@ def bind_dpdk_interfaces(ifname, driver, noop): msg = "Failed to bind dpdk interface err - %s" % err raise OvsDpdkBindException(msg) else: - _update_dpdk_map(ifname, pci_address, driver) + _update_dpdk_map(ifname, pci_address, mac_address, driver) except processutils.ProcessExecutionError: msg = "Failed to bind interface %s with dpdk" % ifname @@ -219,19 +234,29 @@ def _get_pci_address(ifname, noop): # way to identify the nic name after it is bound. So, the DPDK bound nic info # is stored persistently in a file and is used to for nic numbering on # subsequent runs of os-net-config. -def _update_dpdk_map(ifname, pci_address, driver): +def _update_dpdk_map(ifname, pci_address, mac_address, driver): contents = get_file_data(_DPDK_MAPPING_FILE) dpdk_map = yaml.load(contents) if contents else [] for item in dpdk_map: if item['pci_address'] == pci_address: item['name'] = ifname + item['mac_address'] = mac_address item['driver'] = driver break else: new_item = {} new_item['pci_address'] = pci_address new_item['name'] = ifname + new_item['mac_address'] = mac_address new_item['driver'] = driver dpdk_map.append(new_item) write_yaml_config(_DPDK_MAPPING_FILE, dpdk_map) + + +def _get_dpdk_mac_address(name): + contents = get_file_data(_DPDK_MAPPING_FILE) + dpdk_map = yaml.load(contents) if contents else [] + for item in dpdk_map: + if item['name'] == name: + return item['mac_address'] -- cgit 1.2.3-korg