acd617f4ca
Add full support for DPDK; this includes a number of configuration options to allow the number of cores and memory allocated per NUMA node to be changed. By default, the first core and 1024MB of RAM of each NUMA node will be configured for DPDK use. When DPDK is enabled, OVS bridges are configured as datapath type 'netdev' rather than type 'system' to allow use of userspace DPDK packet processing; Security groups are also disabled, as iptables based rules cannot be applied against userspace sockets. DPDK device binding is undertaken using /etc/dpdk/interfaces and the dpdk init script provided as part of the DPDK package; device resolution is determined using the data-port configuration option using the <bridge:<mac address> format - MAC addresses are used to resolve underlying PCI device names for binding with DPDK. It's assumed that hugepage memory configuration is either done as part of system boot as kernel command line options (set via MAAS) or using the hugepages configuration option on the nova-compute charm. Change-Id: Ieb2ac522b07e495f1855e304d31eef59c316c0e4
95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
#!/usr/bin/python
|
|
import pci
|
|
from test_utils import patch_open
|
|
from mock import patch, MagicMock
|
|
import pci_responses
|
|
import os
|
|
|
|
|
|
def check_device(device, attr_dict):
|
|
equal = device.interface_name == attr_dict['interface_name'] and \
|
|
device.mac_address == attr_dict['mac_address'] and \
|
|
device.pci_address == attr_dict['pci_address'] and \
|
|
device.state == attr_dict['state']
|
|
return equal
|
|
|
|
|
|
def mocked_subprocess(subproc_map=None):
|
|
def _subproc(cmd, stdin=None):
|
|
for key in pci_responses.COMMANDS.keys():
|
|
if pci_responses.COMMANDS[key] == cmd:
|
|
return subproc_map[key]
|
|
elif pci_responses.COMMANDS[key] == cmd[:-1]:
|
|
return subproc_map[cmd[-1]][key]
|
|
|
|
if not subproc_map:
|
|
subproc_map = pci_responses.NET_SETUP
|
|
return _subproc
|
|
|
|
|
|
class mocked_filehandle(object):
|
|
def _setfilename(self, fname, omode):
|
|
self.FILENAME = fname
|
|
|
|
def _getfilecontents_read(self):
|
|
return pci_responses.FILE_CONTENTS[self.FILENAME]
|
|
|
|
def _getfilecontents_readlines(self):
|
|
return pci_responses.FILE_CONTENTS[self.FILENAME].split('\n')
|
|
|
|
|
|
def mocked_globs(path):
|
|
check_path = path.rstrip('*').rstrip('/')
|
|
dirs = []
|
|
for sdir in pci_responses.SYS_TREE:
|
|
if check_path in sdir:
|
|
dirs.append(sdir)
|
|
return dirs
|
|
|
|
|
|
def mocked_islink(link):
|
|
resolved_relpath = mocked_resolve_link(link)
|
|
if pci_responses.SYS_TREE.get(resolved_relpath):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def mocked_resolve_link(link):
|
|
resolved_relpath = None
|
|
for sdir in pci_responses.SYS_TREE:
|
|
if sdir in link:
|
|
rep_dir = "{}/{}".format(os.path.dirname(sdir),
|
|
pci_responses.SYS_TREE[sdir])
|
|
resolved_symlink = link.replace(sdir, rep_dir)
|
|
resolved_relpath = os.path.abspath(resolved_symlink)
|
|
return resolved_relpath
|
|
|
|
|
|
def mocked_realpath(link):
|
|
resolved_link = mocked_resolve_link(link)
|
|
return pci_responses.SYS_TREE[resolved_link]
|
|
|
|
|
|
@patch('pci.log')
|
|
@patch('pci.subprocess.Popen')
|
|
@patch('pci.subprocess.check_output')
|
|
@patch('pci.glob.glob')
|
|
@patch('pci.os.path.islink')
|
|
def pci_devs(_osislink, _glob, _check_output, _Popen, _log, subproc_map=None):
|
|
_glob.side_effect = mocked_globs
|
|
_osislink.side_effect = mocked_islink
|
|
_check_output.side_effect = mocked_subprocess(
|
|
subproc_map=subproc_map)
|
|
|
|
with patch_open() as (_open, _file), \
|
|
patch('pci.os.path.realpath') as _realpath:
|
|
super_fh = mocked_filehandle()
|
|
_file.readlines = MagicMock()
|
|
_open.side_effect = super_fh._setfilename
|
|
_file.read.side_effect = super_fh._getfilecontents_read
|
|
_file.readlines.side_effect = super_fh._getfilecontents_readlines
|
|
_realpath.side_effect = mocked_realpath
|
|
devices = pci.PCINetDevices()
|
|
return devices
|