Change in vdsm[master]: vdsm: introduce hostdev module

mpolednik at redhat.com mpolednik at redhat.com
Tue Sep 2 13:39:36 UTC 2014


Martin Polednik has uploaded a new change for review.

Change subject: vdsm: introduce hostdev module
......................................................................

vdsm: introduce hostdev module

Hostdev module serves the purpose of encapsulating functions
related to reporting, acquiring and releasing host devices
(nodeDevices in libvirt terms)

Change-Id: I2bba96db5be180d00cb74fb89b10c5b09e5bd180
Signed-off-by: Martin Polednik <mpolednik at redhat.com>
---
M debian/vdsm.install
M vdsm.spec.in
M vdsm/API.py
M vdsm/Makefile.am
A vdsm/hostdev.py
M vdsm/rpc/vdsmapi-schema.json
6 files changed, 185 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/13/32313/1

diff --git a/debian/vdsm.install b/debian/vdsm.install
index b1840ec..b913b3d 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -52,6 +52,7 @@
 ./usr/share/vdsm/gluster/hostname.py
 ./usr/share/vdsm/hooking.py
 ./usr/share/vdsm/hooks.py
+./usr/share/vdsm/hostdev.py
 ./usr/share/vdsm/kaxmlrpclib.py
 ./usr/share/vdsm/ksm.py
 ./usr/share/vdsm/logUtils.py
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 323b586..2d09962 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -940,6 +940,7 @@
 %{_datadir}/%{vdsm_name}/API.py*
 %{_datadir}/%{vdsm_name}/hooking.py*
 %{_datadir}/%{vdsm_name}/hooks.py*
+%{_datadir}/%{vdsm_name}/hostdev.py*
 %{_datadir}/%{vdsm_name}/mk_sysprep_floppy
 %{_datadir}/%{vdsm_name}/parted_utils.py*
 %{_datadir}/%{vdsm_name}/mkimage.py*
diff --git a/vdsm/API.py b/vdsm/API.py
index 585923e..14f9fbc 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -52,6 +52,7 @@
 from vdsm.config import config
 import ksm
 import hooks
+import hostdev
 from caps import PAGE_SIZE_BYTES
 
 import supervdsm
@@ -1287,6 +1288,10 @@
         statsList = hooks.after_get_all_vm_stats(statsList)
         return {'status': doneCode, 'statsList': statsList}
 
+    def hostdevListByCaps(self, caps):
+        devices = hostdev.listByCaps(self._cif.vmContainer)
+        return {'status': doneCode, 'deviceList': devices}
+
     def getStats(self):
         """
         Report host statistics.
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 2afdd00..64653f1 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -32,6 +32,7 @@
 	dmidecodeUtil.py \
 	hooking.py \
 	hooks.py \
+	hostdev.py \
 	kaxmlrpclib.py \
 	ksm.py \
 	logUtils.py \
diff --git a/vdsm/hostdev.py b/vdsm/hostdev.py
new file mode 100644
index 0000000..cd3501e
--- /dev/null
+++ b/vdsm/hostdev.py
@@ -0,0 +1,106 @@
+#
+# Copyright 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import logging
+import xml.etree.ElementTree as etree
+
+from vdsm import libvirtconnection
+
+
+def parseDeviceParams(device_xml):
+    params = {}
+
+    devXML = etree.fromstring(device_xml)
+    name = devXML.find('name').text
+    if name != 'computer':
+        params['parent'] = devXML.find('parent').text
+
+    caps = devXML.find('capability')
+    params['capability'] = caps.attrib['type']
+
+    for element in ('vendor', 'product'):
+        elementXML = caps.find(element)
+        if elementXML is not None:
+            if 'id' in elementXML.attrib:
+                params[element + '_id'] = elementXML.attrib['id']
+            params[element] = elementXML.text
+
+    iommu_group = caps.find('iommuGroup')
+    if iommu_group:
+        params['iommu_group'] = iommu_group.attrib['number']
+
+    return params
+
+
+def getDevicesFromLibvirt(vmContainer):
+    """
+    Method that scans all VMs in supported vmContainer, locates node
+    devices and pairs them with VM in internal mapping, removing VMs or
+    devices that no longer exist
+    """
+    devices = {}
+    hostDevices = [(dev.name(), dev) for dev
+                   in libvirtconnection.listAllDevices(0)]
+
+    for (device_name, device) in hostDevices:
+        devices[device_name] = [device, '']
+
+    # loop through VMs and find their host devices
+    for vmId, params in vmContainer.items():
+        try:
+            for device in params.conf['devices']:
+                if device['device'] == 'hostdev':
+                    try:
+                        devices[device['name']][1] = vmId
+                    except KeyError:
+                        # VM has device which is no (longer) present
+                        # on the host - althought this should be handled by
+                        # user, warning can help debugging libvirt errors
+                        logging.warning('VM %s has device %s which is not '
+                                        'available!', vmId, device['name'])
+        # BC: ignore old VM's without conf['devices'] section, no handling
+        # needed as hostdev was not supported
+        except KeyError:
+            pass
+
+    return devices
+
+
+def listByCaps(vmContainer, caps):
+    """
+    Returns devices that have specified capability in format
+    {device_name: {'params': {'capability': '', 'vendor': '',
+                              'vendor_id': '', 'product': '',
+                              'product_id': '', 'iommu_group': ''},
+                   'vmId': vmId]}
+    """
+    # device configuration may have changed: repopulate the map
+    devices = getDevicesFromLibvirt(vmContainer)
+
+    for device_name, assignment in devices.items():
+        devices[device_name] = {
+            'params': parseDeviceParams(assignment[0].XMLDesc()),
+            'vmId': assignment[1]}
+
+    for device_name, assignment in devices.items():
+        if caps and assignment['params']['capability'] not in caps:
+            del(devices[device_name])
+
+    return devices
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 2ff8e0b..946fd85 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -3610,6 +3610,77 @@
  'returns': ['VmStats']}
 
 ##
+# @HostDeviceParams:
+#
+# A host device parameters
+#
+# @capability:      The capability of the device (ussualy pci,
+#                   usb_device, scsi)
+#
+# @iommu_group:     The iommu group which the device belongs to
+#
+# @parent:          Name of the parent device
+#
+# @product_id:      Hexadecimal representation of the product
+#                   specified by vendor
+#
+# @product:         String representation of the product specified
+#                   by vendor
+#
+# @vendor_id:       Hexadecimal representation of the vendor
+#
+# @vendor:          String representation of the vendor
+#
+# Since: 4.16.0
+##
+{'type': 'HostDeviceParams',
+ 'data': {'capability': 'str', 'iommu_group': 'uint',
+          'parent': 'str', 'product_id': 'str', 'product': 'str',
+          'vendor_id': 'str', 'vendor': 'str'}}
+
+##
+# @HostDevice:
+#
+# Assignment of the device to VM
+#
+# @vmId:            The VM UUID
+#
+# @params:          Properties of the device
+#
+# Since: 4.16.0
+##
+{'type': 'HostDevice',
+ 'data': {'vmId': 'UUID', 'params': 'HostDeviceParams'}}
+
+##
+# @HostDevices:
+#
+# Mapping of devices to their assignments 
+#
+# @deviceName:      Name of the device
+#
+# Since: 4.16.0
+##
+{'type': 'HostDevices',
+ 'data': {'deviceName': 'HostDevice'}}
+
+##
+# @Host.hostdevFilterByCaps:
+#
+# Refresh and get information about devices available on the host
+#
+# @caps:            List of capabilities of devices to fetch
+#
+# Returns:
+# A list of devices on the host
+#
+# Since: 4.16.0
+##
+{'command': {'class': 'Host', 'name': 'hostdevFilterByCaps'},
+ 'data': {'caps': ['str']},
+ 'returns': ['HostDevices']}
+
+##
 # @Host.ping:
 #
 # Test connectivity to vdsm.


-- 
To view, visit http://gerrit.ovirt.org/32313
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2bba96db5be180d00cb74fb89b10c5b09e5bd180
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpolednik at redhat.com>


More information about the vdsm-patches mailing list