utilities/utilities/pci-irq-affinity-agent/files/nova-sriov

118 lines
3.4 KiB
Python
Executable File

#! /usr/bin/python
#
# Copyright (c) 2015 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import sys
import os
import json
import fnmatch
def usage():
argv0 = os.path.basename(sys.argv[0])
print """
Usage:
------
%(argv0)s pci_pt_whitelist pci_sriov_whitelist
Where pci_pt_whitelist is a list of passthrough devices and the
pci_sriov_whitelist is a list of SR-IOV interfaces. The format of the lists
are as follows:
pci_pt_whitelist:
[{"address": "0000:09:00.0"}, ..]
pci_sriov_whitelist:
[{"sriov_numvfs": 16, "physical_network": "group0-nic0",
"address": "0000:02:00.0"}, ..]
""" % locals() # replace items from local variables
def get_vf_whitelist(sriov_if):
'''For the given PF PCI address and provider network, generate the list of VF
PCI addresses to create a VF based whitelist'''
pf_addr = sriov_if.get('address')
dirpcidev = '/sys/bus/pci/devices/' + pf_addr
# Attempt to configure the requested number of VFs if the device supports
# setting the number of VFs via sysfs
# Need to write 0 to sriov_numvfs before writing a new value.
numvfs = sriov_if.get('sriov_numvfs')
if numvfs is not None:
numvfs_path = os.path.join(dirpcidev, 'sriov_numvfs')
if os.path.isfile(numvfs_path):
with open(numvfs_path, 'w') as f:
f.write('0')
f.flush()
f.write(str(numvfs))
virtfn_links = len(fnmatch.filter(os.listdir(dirpcidev), 'virtfn*'))
# Some devices (for e.g. Coleto Creek) don't support configuration of the
# number of VFs. Use all the VFs present in this case.
if numvfs is not None:
if virtfn_links != numvfs:
print 'Configured number of VFs is different than the present ones', \
'(if:%s conf:%d present:%d)' % (pf_addr, numvfs, virtfn_links)
exit(1)
else:
numvfs = virtfn_links
pci_sriov_vf_whitelist = []
i = 0
while i < int(numvfs):
lvf = dirpcidev + '/virtfn' + str(i)
try:
vf_addr = os.path.basename(os.readlink(lvf))
except:
print("virtfn link %s non-existent (numvfs=%s)" % (lvf, numvfs))
sys.exit(1)
device = {'address': vf_addr}
# Some devices (for e.g. Coleto Creek) are not associated with a
# physical network.
providernets = sriov_if.get('physical_network')
if providernets:
device.update({'physical_network': providernets})
pci_sriov_vf_whitelist.append(device)
i += 1
return pci_sriov_vf_whitelist
def main():
''' The goal of this script is to properly discover SR-IOV VF PCI addresses
for interfaces that were configured for SR-IOV. It is used by the
nova-compute puppet manifest and is run at manifest application time. This
script should be run after the VF driver is loaded and the VF PCI addresses
are visible in the system.'''
if len(sys.argv) < 3:
usage()
sys.exit(1)
try:
pci_pt_whitelist = json.loads(sys.argv[1])
pci_sriov_whitelist = json.loads(sys.argv[2])
except:
usage()
exit(1)
for sriov_if in pci_sriov_whitelist:
pci_sriov_vf_whitelist = get_vf_whitelist(sriov_if)
pci_pt_whitelist.extend(pci_sriov_vf_whitelist)
return pci_pt_whitelist
if __name__ == "__main__":
print json.dumps(main())