class FakePciDevice(object):
pci_dev_template = """<device>
- <name>pci_0000_81_%(slot)s_%(dev)d</name>
- <path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:%(slot)s.%(dev)d</path>
+ <name>pci_0000_81_%(slot)02x_%(dev)d</name>
+ <path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:%(slot)02x.%(dev)d</path>
<parent>pci_0000_80_01_0</parent>
<driver>
<name>%(driver)s</name>
<capability type='pci'>
<domain>0</domain>
<bus>129</bus>
- <slot>0</slot>
+ <slot>%(slot)d</slot>
<function>%(dev)d</function>
<product id='0x%(prod)d'>%(prod_name)s</product>
<vendor id='0x8086'>Intel Corporation</vendor>
%(functions)s
</capability>
<iommuGroup number='%(group_id)d'>
- <address domain='0x0000' bus='0x81' slot='0x%(slot)s' function='0x%(dev)d'/>
+ <address domain='0x0000' bus='0x81' slot='%(slot)#02x' function='0x%(dev)d'/>
</iommuGroup>
<numa node='%(numa_node)s'/>
<pci-express>
pf_caps = [addr_templ % {'dev': x, 'slot': VF_SLOT}
for x in range(dev * vf_ratio,
(dev + 1) * vf_ratio)]
+ slot = int(str(PF_SLOT), 16)
self.pci_dev = self.pci_dev_template % {'dev': dev,
'prod': product_id, 'group_id': group,
- 'functions': '\n'.join(pf_caps), 'slot': 0,
+ 'functions': '\n'.join(pf_caps), 'slot': slot,
'cap_type': PF_CAP_TYPE, 'prod_name': PF_PROD_NAME,
'driver': PF_DRIVER_NAME, 'numa_node': numa_node}
elif dev_type == 'VF':
vf_caps = [addr_templ % {'dev': int(dev / vf_ratio),
'slot': PF_SLOT}]
+ slot = int(str(VF_SLOT), 16)
self.pci_dev = self.pci_dev_template % {'dev': dev,
'prod': product_id, 'group_id': group,
- 'functions': '\n'.join(vf_caps), 'slot': VF_SLOT,
+ 'functions': '\n'.join(vf_caps), 'slot': slot,
'cap_type': VF_CAP_TYPE, 'prod_name': VF_PROD_NAME,
'driver': VF_DRIVER_NAME, 'numa_node': numa_node}
def _calc_numa_node(dev):
return dev % total_numa_nodes if numa_node is None else numa_node
- vf_ratio = num_vfs / num_pfs
+ vf_ratio = num_vfs // num_pfs
# Generate PFs
for dev in range(num_pfs):
from nova.objects import fields as obj_fields
from nova import test
import nova.tests.unit.virt.libvirt.fakelibvirt as libvirt
+from nova.virt.libvirt import config as vconfig
def get_vm_xml(name="testname", uuid=None, source_type='file',
kb_mem=15740000)
self.assertEqual(host_topology.to_xml(),
topology)
+
+ def test_pci_devices_generation(self):
+ def _cmp_pci_dev_addr(dev_xml, cmp_addr):
+ cfgdev = vconfig.LibvirtConfigNodeDevice()
+ cfgdev.parse_str(dev_xml)
+
+ address = "%04x:%02x:%02x.%1x" % (
+ cfgdev.pci_capability.domain,
+ cfgdev.pci_capability.bus,
+ cfgdev.pci_capability.slot,
+ cfgdev.pci_capability.function)
+ self.assertEqual(cmp_addr, address)
+
+ pf_xml = """<device>
+ <name>pci_0000_81_00_0</name>
+ <path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:00.0</path>
+ <parent>pci_0000_80_01_0</parent>
+ <driver>
+ <name>ixgbe</name>
+ </driver>
+ <capability type='pci'>
+ <domain>0</domain>
+ <bus>129</bus>
+ <slot>0</slot>
+ <function>0</function>
+ <product id='0x1528'>Ethernet Controller 10-Gigabit X540-AT2</product>
+ <vendor id='0x8086'>Intel Corporation</vendor>
+ <capability type='virt_functions'>
+ <address domain='0x0000' bus='0x81' slot='0x10' function='0x0'/>
+ </capability>
+ <iommuGroup number='48'>
+ <address domain='0x0000' bus='0x81' slot='0x0' function='0x0'/>
+ </iommuGroup>
+ <numa node='0'/>
+ <pci-express>
+ <link validity='cap' port='0' speed='5' width='8'/>
+ <link validity='sta' speed='5' width='8'/>
+ </pci-express>
+ </capability>
+</device>"""
+ vf_xml = """<device>
+ <name>pci_0000_81_10_0</name>
+ <path>/sys/devices/pci0000:80/0000:80:01.0/0000:81:10.0</path>
+ <parent>pci_0000_80_01_0</parent>
+ <driver>
+ <name>ixgbevf</name>
+ </driver>
+ <capability type='pci'>
+ <domain>0</domain>
+ <bus>129</bus>
+ <slot>16</slot>
+ <function>0</function>
+ <product id='0x1515'>X540 Ethernet Controller Virtual Function</product>
+ <vendor id='0x8086'>Intel Corporation</vendor>
+ <capability type='phys_function'>
+ <address domain='0x0000' bus='0x81' slot='0x00' function='0x0'/>
+ </capability>
+ <iommuGroup number='48'>
+ <address domain='0x0000' bus='0x81' slot='0x10' function='0x0'/>
+ </iommuGroup>
+ <numa node='0'/>
+ <pci-express>
+ <link validity='cap' port='0' speed='5' width='8'/>
+ <link validity='sta' speed='5' width='8'/>
+ </pci-express>
+ </capability>
+</device>"""
+
+ # create fake pci devices
+ pci_info = libvirt.HostPciSRIOVDevicesInfo()
+ pci_info.create_pci_devices(num_pfs=1, num_vfs=1)
+
+ # generate xml for the created pci devices
+ gen_pf = pci_info.get_device_by_name('pci_0000_81_00_0')
+ gen_vf = pci_info.get_device_by_name('pci_0000_81_10_0')
+
+ self.assertEqual(gen_pf.XMLDesc(0), pf_xml)
+ self.assertEqual(gen_vf.XMLDesc(0), vf_xml)
+
+ # parse the generated xml with a libvirt config class and compare
+ # device address
+ _cmp_pci_dev_addr(pf_xml, '0000:81:00.0')
+ _cmp_pci_dev_addr(vf_xml, '0000:81:10.0')