- This commit adds a new field in the PCI device data structure to
notify the client that such PCI is a multi-function device. The
goal is to make it easy to identify whether a given device is
multi-function or not in the client side.
Signed-off-by: Jose Ricardo Ziviani <joserz(a)linux.vnet.ibm.com>
---
docs/API.md | 1 +
model/host.py | 33 ++++++++++++++++++++++++++++++++-
model/vmhostdevs.py | 3 ++-
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index 1c4ee50..9593f6b 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -870,6 +870,7 @@ List of available groups.
* description: Product description of a "pci" device.
* iommuGroup: IOMMU group number of a "pci" device. Would be None/null if
host does not enable IOMMU support.
+ * multifunction: True if the device belongs to a multi-function adapter.
### Sub-collection: VMs with the device assigned.
diff --git a/model/host.py b/model/host.py
index 628ae71..583accd 100644
--- a/model/host.py
+++ b/model/host.py
@@ -18,6 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import libvirt
+from collections import defaultdict
from lxml import objectify
from wok.exception import InvalidParameter
@@ -144,6 +145,27 @@ class DevicesModel(object):
class DeviceModel(object):
def __init__(self, **kargs):
self.conn = kargs['conn']
+ self.iommu_groups = self._get_iommu_groups()
+
+ def _get_iommu_groups(self):
+ iommu_groups = defaultdict(list)
+ conn = self.conn
+
+ try:
+ devices = DevicesModel(conn=conn).get_list()
+
+ except:
+ return iommu_groups
+
+ for device in devices:
+ info = hostdev.get_dev_info(
+ conn.get().nodeDeviceLookupByName(device))
+ if 'iommuGroup' not in info:
+ continue
+ iommu_group_nr = int(info['iommuGroup'])
+ iommu_groups[iommu_group_nr].append(device)
+
+ return iommu_groups
def lookup(self, nodedev_name):
conn = self.conn.get()
@@ -151,7 +173,16 @@ class DeviceModel(object):
dev = conn.nodeDeviceLookupByName(nodedev_name)
except:
raise NotFoundError('KCHHOST0003E', {'name': nodedev_name})
- return hostdev.get_dev_info(dev)
+
+ info = hostdev.get_dev_info(dev)
+ info['multifunction'] = self.is_multifunction_pci(info)
+ return info
+
+ def is_multifunction_pci(self, info):
+ if 'iommuGroup' not in info:
+ return False
+ iommu_group_nr = int(info['iommuGroup'])
+ return len(self.iommu_groups[iommu_group_nr]) > 1
@staticmethod
def _toint(num_str):
diff --git a/model/vmhostdevs.py b/model/vmhostdevs.py
index c4fb815..de52cd8 100644
--- a/model/vmhostdevs.py
+++ b/model/vmhostdevs.py
@@ -279,7 +279,8 @@ class VMHostDevModel(object):
return {'name': dev_name,
'type': e.attrib['type'],
'product': dev_info.get('product', None),
- 'vendor': dev_info.get('vendor', None)}
+ 'vendor': dev_info.get('vendor', None),
+ 'multifunction': dev_info.get('multifunction',
None)}
raise NotFoundError('KCHVMHDEV0001E',
{'vmid': vmid, 'dev_name': dev_name})
--
1.9.1