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