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
This commit is contained in:
Saravanan KR 2016-09-14 15:55:26 +05:30
parent c82cc95598
commit e2c2f29fd1
2 changed files with 60 additions and 18 deletions

View File

@ -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')

View File

@ -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']