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 <[email protected]> --- 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 <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
