Change in vdsm[master]: [WIP] vdsm: add support for PCI passthrough

mpoledni at redhat.com mpoledni at redhat.com
Tue Dec 17 11:56:34 UTC 2013


Martin Polednik has uploaded a new change for review.

Change subject: [WIP] vdsm: add support for PCI passthrough
......................................................................

[WIP] vdsm: add support for PCI passthrough

required functionality:
* report PCI devices available on host [x]
* handle createVm xml generation [x]
* hotplugHostdev [ ] (required for after-migration)
* hotpunlugHostdev [ ] (required for migration)

Change-Id: I363d2622d72ca2db75f60032fe0892c348bab121
Signed-off-by: Martin Polednik <mpoledni at redhat.com>
---
M lib/vdsm/define.py
M vdsm/caps.py
M vdsm/vm.py
3 files changed, 83 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/62/22462/1

diff --git a/lib/vdsm/define.py b/lib/vdsm/define.py
index eb78633..9605f93 100644
--- a/lib/vdsm/define.py
+++ b/lib/vdsm/define.py
@@ -132,6 +132,12 @@
     'transientErr': {'status': {
         'code': 59,
         'message': 'Action not permitted on a VM with transient disks'}},
+    'hotplugHostdev': {'status': {
+        'code': 60,
+        'message': 'Failed to hotplug hostdev'}},
+    'hotunplugHostdev': {'status': {
+        'code': 61,
+        'message': 'Failed to hotunplug hostdev'}},
     'recovery': {'status': {
         'code': 99,
         'message': 'Recovering from crash or Initializing'}},
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 3839134..d6af375 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -308,6 +308,38 @@
     return dict(release=release, version=version, name=osname)
 
 
+def hostdevList():
+    devices = []
+    for device in libvirtconnection.get().listAllDevices():
+        devXML = minidom.parseString(device.XMLDesc())
+        dev = {}
+
+        # we have to grab attributes that will most likely not only
+        # uniquely identify device, but also serve as human readable
+        # representation of the device
+        try:
+            dev['name'] = devXML.getElementsByTagName('name')[0].\
+                childNodes[0].data
+            capability = devXML.getElementsByTagName('capability')[0]
+            try:
+                dev['product'] = capability.getElementsByTagName('product')[0]\
+                    .childNodes[0].data
+                dev['vendor'] = capability.getElementsByTagName('vendor')[0].\
+                    childNodes[0].data
+            except IndexError:
+                # althought the retrieval of product/vendor was not successful,
+                # we can still report back the name
+                pass
+        except IndexError:
+            # should device not have a name, there is nothing engine could send
+            # back that we could use to uniquely identify and initiate a device
+            continue
+
+        devices.append(dev)
+
+    return devices
+
+
 def get():
     targetArch = platform.machine()
 
@@ -360,6 +392,7 @@
                               config.getint('vars', 'extra_mem_reserve'))
     caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')
     caps['rngSources'] = _getRngSources()
+    caps['hostDevices'] = hostdevList()
 
     return caps
 
diff --git a/vdsm/vm.py b/vdsm/vm.py
index a5d923b..a477bc9 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -78,6 +78,7 @@
 WATCHDOG_DEVICES = 'watchdog'
 CONSOLE_DEVICES = 'console'
 SMARTCARD_DEVICES = 'smartcard'
+HOSTDEV_DEVICES = 'hostdev'
 
 
 def isVdsmImage(drive):
@@ -1656,6 +1657,27 @@
         return m
 
 
+class HostDevice(VmDevice):
+    def getXML(self):
+        """
+        Create domxml for a hostdev device.
+
+        <devices>
+            <hostdev mode='subsystem' type='usb'>
+            <source startupPolicy='optional'>
+                <vendor id='0x1234'/>
+                <product id='0xbeef'/>
+            </source>
+            <boot order='2'/>
+            </hostdev>
+        </devices>
+        """
+        # libvirt gives us direct api call to construct the XML
+        return xml.dom.minidom.parseString(libvirtconnection.get().
+                                           nodeDeviceLookupByName(self.name).
+                                           XMLDesc())
+
+
 class WatchdogDevice(VmDevice):
     def __init__(self, *args, **kwargs):
         super(WatchdogDevice, self).__init__(*args, **kwargs)
@@ -1769,7 +1791,8 @@
                      (CONSOLE_DEVICES, ConsoleDevice),
                      (REDIR_DEVICES, RedirDevice),
                      (RNG_DEVICES, RngDevice),
-                     (SMARTCARD_DEVICES, SmartCardDevice))
+                     (SMARTCARD_DEVICES, SmartCardDevice),
+                     (HOSTDEV_DEVICES, HostDevice))
 
     def _makeDeviceDict(self):
         return dict((dev, []) for dev, _ in self.DeviceMapping)
@@ -3127,6 +3150,26 @@
 
                 break
 
+    def hotplugHostdev(self, params):
+        hostdev = HostDevice(self.conf, self.log, **params)
+        self._devices[HOSTDEV_DEVICES].append(hostdev)
+        hostdevXML = hostdev.getXML().toprettyxml(encoding='utf-8')
+        hostdev._deviceXML = hostdevXML
+        self.log.debug("Hotplug hostdev xml: %s", hostdevXML)
+
+        try:
+            self._dom.attachDevice(hostdevXML)
+        except libvirt.libvirtError as e:
+            self.log.error("Hotplug failed", exc_info=True)
+            if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+                return errCode['noVM']
+            return {'status': {'code':
+                               errCode['hotplugHostdev']['status']['code'],
+                               'message': e.message}}
+
+    def hotunplugHostdev(self, name):
+        pass
+
     def hotplugNic(self, params):
         if self.isMigrating():
             return errCode['migInProgress']


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

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


More information about the vdsm-patches mailing list