[libvirt] [v10 3/6] change qemu driver to use hostdev common library

Chunyan Liu cyliu at suse.com
Fri Jan 17 06:41:00 UTC 2014


Change qemu driver to use hostdev common library instead of APIs in
qemu_hostdev.[ch] Improve some test files.

Signed-off-by: Chunyan Liu <cyliu at suse.com>
---
 po/POTFILES.in                                     |    1 -
 src/Makefile.am                                    |    1 -
 src/qemu/qemu_command.c                            |    1 -
 src/qemu/qemu_conf.h                               |    9 +-
 src/qemu/qemu_domain.c                             |   22 +
 src/qemu/qemu_driver.c                             |   83 +-
 src/qemu/qemu_hostdev.c                            | 1466 --------------------
 src/qemu/qemu_hostdev.h                            |   76 -
 src/qemu/qemu_hotplug.c                            |  132 +-
 src/qemu/qemu_process.c                            |   40 +-
 .../qemuxml2argv-hostdev-pci-address.xml           |    1 +
 .../qemuxml2argvdata/qemuxml2argv-net-hostdev.xml  |    1 +
 tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml    |    2 +
 13 files changed, 130 insertions(+), 1705 deletions(-)
 delete mode 100644 src/qemu/qemu_hostdev.c
 delete mode 100644 src/qemu/qemu_hostdev.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 60c226a..9e71db3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -99,7 +99,6 @@ src/qemu/qemu_command.c
 src/qemu/qemu_conf.c
 src/qemu/qemu_domain.c
 src/qemu/qemu_driver.c
-src/qemu/qemu_hostdev.c
 src/qemu/qemu_hotplug.c
 src/qemu/qemu_migration.c
 src/qemu/qemu_monitor.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 98233cd..8b4a25c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -674,7 +674,6 @@ QEMU_DRIVER_SOURCES =							\
 		qemu/qemu_command.c qemu/qemu_command.h			\
 		qemu/qemu_domain.c qemu/qemu_domain.h			\
 		qemu/qemu_cgroup.c qemu/qemu_cgroup.h			\
-		qemu/qemu_hostdev.c qemu/qemu_hostdev.h			\
 		qemu/qemu_hotplug.c qemu/qemu_hotplug.h			\
 		qemu/qemu_hotplugpriv.h					\
 		qemu/qemu_conf.c qemu/qemu_conf.h			\
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 35b7c67..59c3968 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -24,7 +24,6 @@
 #include <config.h>
 
 #include "qemu_command.h"
-#include "qemu_hostdev.h"
 #include "qemu_capabilities.h"
 #include "qemu_bridge_filter.h"
 #include "cpu/cpu.h"
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 1f44a76..ff5836d 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -53,6 +53,7 @@
 #  error "Port me"
 # endif
 
+# define QEMU_DRIVER_NAME "QEMU"
 typedef struct _virQEMUDriver virQEMUDriver;
 typedef virQEMUDriver *virQEMUDriverPtr;
 
@@ -213,14 +214,6 @@ struct _virQEMUDriver {
     /* Immutable pointer. self-locking APIs */
     virSecurityManagerPtr securityManager;
 
-    /* Immutable pointers. Requires locks to be held before
-     * calling APIs. activePciHostdevs must be locked before
-     * inactivePciHostdevs */
-    virPCIDeviceListPtr activePciHostdevs;
-    virPCIDeviceListPtr inactivePciHostdevs;
-    virUSBDeviceListPtr activeUsbHostdevs;
-    virSCSIDeviceListPtr activeScsiHostdevs;
-
     /* Immutable pointer. Unsafe APIs. XXX */
     virHashTablePtr sharedDevices;
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c947e2e..c5949ce 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -38,6 +38,7 @@
 #include "virtime.h"
 #include "virstoragefile.h"
 #include "virstring.h"
+#include "virhostdev.h"
 
 #include <sys/time.h>
 #include <fcntl.h>
@@ -821,6 +822,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
     int ret = -1;
     virQEMUDriverPtr driver = opaque;
     virQEMUDriverConfigPtr cfg = NULL;
+    virQEMUCapsPtr qemuCaps = NULL;
 
     if (dev->type == VIR_DOMAIN_DEVICE_NET &&
         dev->data.net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
@@ -899,6 +901,26 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
         dev->data.chr->source.data.nix.listen = true;
     }
 
+    if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+        virDomainHostdevDefPtr hostdev = dev->data.hostdev;
+        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+            hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
+
+            hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
+            if (driver && driver->qemuCapsCache) {
+                bool supportsPassthroughVFIO = virHostdevHostSupportsPassthroughVFIO();
+                qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
+                                                      def->emulator);
+                if (supportsPassthroughVFIO && qemuCaps &&
+                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI))
+                    hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
+
+                virObjectUnref(qemuCaps);
+            }
+        }
+    }
+
     ret = 0;
 
 cleanup:
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d39cdc4..29d4371 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -50,7 +50,6 @@
 #include "qemu_capabilities.h"
 #include "qemu_command.h"
 #include "qemu_cgroup.h"
-#include "qemu_hostdev.h"
 #include "qemu_hotplug.h"
 #include "qemu_monitor.h"
 #include "qemu_bridge_filter.h"
@@ -94,11 +93,10 @@
 #include "virstring.h"
 #include "viraccessapicheck.h"
 #include "viraccessapicheckqemu.h"
+#include "virhostdev.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
-#define QEMU_DRIVER_NAME "QEMU"
-
 #define QEMU_NB_MEM_PARAM  3
 
 #define QEMU_NB_BLOCK_IO_TUNE_PARAM  6
@@ -698,18 +696,6 @@ qemuStateInitialize(bool privileged,
     if (qemuSecurityInit(qemu_driver) < 0)
         goto error;
 
-    if ((qemu_driver->activePciHostdevs = virPCIDeviceListNew()) == NULL)
-        goto error;
-
-    if ((qemu_driver->activeUsbHostdevs = virUSBDeviceListNew()) == NULL)
-        goto error;
-
-    if ((qemu_driver->inactivePciHostdevs = virPCIDeviceListNew()) == NULL)
-        goto error;
-
-    if ((qemu_driver->activeScsiHostdevs = virSCSIDeviceListNew()) == NULL)
-        goto error;
-
     if (!(qemu_driver->sharedDevices = virHashCreate(30, qemuSharedDeviceEntryFree)))
         goto error;
 
@@ -989,10 +975,6 @@ qemuStateCleanup(void) {
 
     virNWFilterUnRegisterCallbackDriver(&qemuCallbackDriver);
     virObjectUnref(qemu_driver->config);
-    virObjectUnref(qemu_driver->activePciHostdevs);
-    virObjectUnref(qemu_driver->inactivePciHostdevs);
-    virObjectUnref(qemu_driver->activeUsbHostdevs);
-    virObjectUnref(qemu_driver->activeScsiHostdevs);
     virHashFree(qemu_driver->sharedDevices);
     virObjectUnref(qemu_driver->caps);
     virQEMUCapsCacheFree(qemu_driver->qemuCapsCache);
@@ -10785,12 +10767,12 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
                           const char *driverName,
                           unsigned int flags)
 {
-    virQEMUDriverPtr driver = dev->conn->privateData;
     virPCIDevicePtr pci = NULL;
     unsigned domain = 0, bus = 0, slot = 0, function = 0;
     int ret = -1;
     virNodeDeviceDefPtr def = NULL;
     char *xml = NULL;
+    virHostdevManagerPtr hostdev_mgr;
 
     virCheckFlags(0, -1);
 
@@ -10814,9 +10796,9 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
 
     if (!driverName) {
         /* prefer vfio */
-        if (qemuHostdevHostSupportsPassthroughVFIO())
+        if (virHostdevHostSupportsPassthroughVFIO())
             driverName = "vfio";
-        else if (qemuHostdevHostSupportsPassthroughLegacy())
+        else if (virHostdevHostSupportsPassthroughKVM())
             driverName = "kvm";
     }
 
@@ -10837,18 +10819,12 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
         goto cleanup;
     }
 
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-
-    if (virPCIDeviceDetach(pci, driver->activePciHostdevs,
-                           driver->inactivePciHostdevs) < 0) {
-        goto out;
-    }
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr == NULL ||
+        virHostdevPciNodeDeviceDetach(hostdev_mgr, pci) < 0)
+        goto cleanup;
 
     ret = 0;
-out:
-    virObjectUnlock(driver->inactivePciHostdevs);
-    virObjectUnlock(driver->activePciHostdevs);
 cleanup:
     virPCIDeviceFree(pci);
     virNodeDeviceDefFree(def);
@@ -10865,13 +10841,12 @@ qemuNodeDeviceDettach(virNodeDevicePtr dev)
 static int
 qemuNodeDeviceReAttach(virNodeDevicePtr dev)
 {
-    virQEMUDriverPtr driver = dev->conn->privateData;
     virPCIDevicePtr pci = NULL;
-    virPCIDevicePtr other;
     unsigned domain = 0, bus = 0, slot = 0, function = 0;
     int ret = -1;
     virNodeDeviceDefPtr def = NULL;
     char *xml = NULL;
+    virHostdevManagerPtr hostdev_mgr;
 
     xml = virNodeDeviceGetXMLDesc(dev, 0);
     if (!xml)
@@ -10891,35 +10866,13 @@ qemuNodeDeviceReAttach(virNodeDevicePtr dev)
     if (!pci)
         goto cleanup;
 
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-    other = virPCIDeviceListFind(driver->activePciHostdevs, pci);
-    if (other) {
-        const char *other_name = NULL;
-        const char *other_drvname = NULL;
-        virPCIDeviceGetUsedBy(other, &other_drvname, &other_name);
-
-        if (other_name)
-            virReportError(VIR_ERR_OPERATION_INVALID,
-                           _("PCI device %s is still in use by domain %s"),
-                           virPCIDeviceGetName(pci), other_name);
-        else
-            virReportError(VIR_ERR_OPERATION_INVALID,
-                           _("PCI device %s is still in use"),
-                           virPCIDeviceGetName(pci));
-        goto out;
-    }
-
-    virPCIDeviceReattachInit(pci);
-
-    if (virPCIDeviceReattach(pci, driver->activePciHostdevs,
-                             driver->inactivePciHostdevs) < 0)
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr == NULL ||
+        virHostdevPciNodeDeviceReAttach(hostdev_mgr, pci) < 0)
         goto out;
 
     ret = 0;
 out:
-    virObjectUnlock(driver->inactivePciHostdevs);
-    virObjectUnlock(driver->activePciHostdevs);
     virPCIDeviceFree(pci);
 cleanup:
     virNodeDeviceDefFree(def);
@@ -10930,12 +10883,12 @@ cleanup:
 static int
 qemuNodeDeviceReset(virNodeDevicePtr dev)
 {
-    virQEMUDriverPtr driver = dev->conn->privateData;
     virPCIDevicePtr pci;
     unsigned domain = 0, bus = 0, slot = 0, function = 0;
     int ret = -1;
     virNodeDeviceDefPtr def = NULL;
     char *xml = NULL;
+    virHostdevManagerPtr hostdev_mgr;
 
     xml = virNodeDeviceGetXMLDesc(dev, 0);
     if (!xml)
@@ -10955,17 +10908,13 @@ qemuNodeDeviceReset(virNodeDevicePtr dev)
     if (!pci)
         goto cleanup;
 
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-
-    if (virPCIDeviceReset(pci, driver->activePciHostdevs,
-                          driver->inactivePciHostdevs) < 0)
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr == NULL ||
+        virHostdevPciNodeDeviceReset(hostdev_mgr, pci) < 0)
         goto out;
 
     ret = 0;
 out:
-    virObjectUnlock(driver->inactivePciHostdevs);
-    virObjectUnlock(driver->activePciHostdevs);
     virPCIDeviceFree(pci);
 cleanup:
     virNodeDeviceDefFree(def);
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
deleted file mode 100644
index 1dc652b..0000000
--- a/src/qemu/qemu_hostdev.c
+++ /dev/null
@@ -1,1466 +0,0 @@
-/*
- * qemu_hostdev.c: QEMU hostdev management
- *
- * Copyright (C) 2006-2007, 2009-2013 Red Hat, Inc.
- * Copyright (C) 2006 Daniel P. Berrange
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Author: Daniel P. Berrange <berrange at redhat.com>
- */
-
-#include <config.h>
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "qemu_hostdev.h"
-#include "virlog.h"
-#include "virerror.h"
-#include "viralloc.h"
-#include "virpci.h"
-#include "virusb.h"
-#include "virscsi.h"
-#include "virnetdev.h"
-#include "virfile.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-static virPCIDeviceListPtr
-qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs)
-{
-    virPCIDeviceListPtr list;
-    size_t i;
-
-    if (!(list = virPCIDeviceListNew()))
-        return NULL;
-
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        virPCIDevicePtr dev;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        dev = virPCIDeviceNew(hostdev->source.subsys.u.pci.addr.domain,
-                              hostdev->source.subsys.u.pci.addr.bus,
-                              hostdev->source.subsys.u.pci.addr.slot,
-                              hostdev->source.subsys.u.pci.addr.function);
-        if (!dev) {
-            virObjectUnref(list);
-            return NULL;
-        }
-
-        if (virPCIDeviceListAdd(list, dev) < 0) {
-            virPCIDeviceFree(dev);
-            virObjectUnref(list);
-            return NULL;
-        }
-
-        virPCIDeviceSetManaged(dev, hostdev->managed);
-        if (hostdev->source.subsys.u.pci.backend
-            == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
-            if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0) {
-                virObjectUnref(list);
-                return NULL;
-            }
-        } else {
-            if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) {
-                virObjectUnref(list);
-                return NULL;
-            }
-        }
-    }
-
-    return list;
-}
-
-
-/*
- * qemuGetActivePciHostDeviceList - make a new list with a *copy* of
- *   every virPCIDevice object that is found on the activePciHostdevs
- *   list *and* is in the hostdev list for this domain.
- *
- * Return the new list, or NULL if there was a failure.
- *
- * Pre-condition: driver->activePciHostdevs is locked
- */
-static virPCIDeviceListPtr
-qemuGetActivePciHostDeviceList(virQEMUDriverPtr driver,
-                               virDomainHostdevDefPtr *hostdevs,
-                               int nhostdevs)
-{
-    virPCIDeviceListPtr list;
-    size_t i;
-
-    if (!(list = virPCIDeviceListNew()))
-        return NULL;
-
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        virDevicePCIAddressPtr addr;
-        virPCIDevicePtr activeDev;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        addr = &hostdev->source.subsys.u.pci.addr;
-        activeDev = virPCIDeviceListFindByIDs(driver->activePciHostdevs,
-                                              addr->domain, addr->bus,
-                                              addr->slot, addr->function);
-        if (activeDev && virPCIDeviceListAddCopy(list, activeDev) < 0) {
-            virObjectUnref(list);
-            return NULL;
-        }
-    }
-
-    return list;
-}
-
-
-int
-qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver,
-                            virDomainDefPtr def)
-{
-    virDomainHostdevDefPtr hostdev = NULL;
-    virPCIDevicePtr dev = NULL;
-    size_t i;
-    int ret = -1;
-
-    if (!def->nhostdevs)
-        return 0;
-
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-
-    for (i = 0; i < def->nhostdevs; i++) {
-        hostdev = def->hostdevs[i];
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        dev = virPCIDeviceNew(hostdev->source.subsys.u.pci.addr.domain,
-                              hostdev->source.subsys.u.pci.addr.bus,
-                              hostdev->source.subsys.u.pci.addr.slot,
-                              hostdev->source.subsys.u.pci.addr.function);
-
-        if (!dev)
-            goto cleanup;
-
-        virPCIDeviceSetManaged(dev, hostdev->managed);
-        if (hostdev->source.subsys.u.pci.backend
-            == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
-            if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0)
-                goto cleanup;
-        } else {
-            if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
-                goto cleanup;
-
-        }
-        virPCIDeviceSetUsedBy(dev, "QEMU", def->name);
-
-        /* Setup the original states for the PCI device */
-        virPCIDeviceSetUnbindFromStub(dev, hostdev->origstates.states.pci.unbind_from_stub);
-        virPCIDeviceSetRemoveSlot(dev, hostdev->origstates.states.pci.remove_slot);
-        virPCIDeviceSetReprobe(dev, hostdev->origstates.states.pci.reprobe);
-
-        if (virPCIDeviceListAdd(driver->activePciHostdevs, dev) < 0)
-            goto cleanup;
-        dev = NULL;
-    }
-
-    ret = 0;
-cleanup:
-    virPCIDeviceFree(dev);
-    virObjectUnlock(driver->activePciHostdevs);
-    virObjectUnlock(driver->inactivePciHostdevs);
-    return ret;
-}
-
-
-int
-qemuUpdateActiveUsbHostdevs(virQEMUDriverPtr driver,
-                            virDomainDefPtr def)
-{
-    virDomainHostdevDefPtr hostdev = NULL;
-    size_t i;
-    int ret = -1;
-
-    if (!def->nhostdevs)
-        return 0;
-
-    virObjectLock(driver->activeUsbHostdevs);
-    for (i = 0; i < def->nhostdevs; i++) {
-        virUSBDevicePtr usb = NULL;
-        hostdev = def->hostdevs[i];
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-            continue;
-
-        usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
-                              hostdev->source.subsys.u.usb.device,
-                              NULL);
-        if (!usb) {
-            VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s",
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device,
-                     def->name);
-            continue;
-        }
-
-        virUSBDeviceSetUsedBy(usb, "QEMU", def->name);
-
-        if (virUSBDeviceListAdd(driver->activeUsbHostdevs, usb) < 0) {
-            virUSBDeviceFree(usb);
-            goto cleanup;
-        }
-    }
-    ret = 0;
-cleanup:
-    virObjectUnlock(driver->activeUsbHostdevs);
-    return ret;
-}
-
-int
-qemuUpdateActiveScsiHostdevs(virQEMUDriverPtr driver,
-                             virDomainDefPtr def)
-{
-    virDomainHostdevDefPtr hostdev = NULL;
-    size_t i;
-    int ret = -1;
-
-    if (!def->nhostdevs)
-        return 0;
-
-    virObjectLock(driver->activeScsiHostdevs);
-    for (i = 0; i < def->nhostdevs; i++) {
-        virSCSIDevicePtr scsi = NULL;
-        hostdev = def->hostdevs[i];
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
-            continue;
-
-        if (!(scsi = virSCSIDeviceNew(hostdev->source.subsys.u.scsi.adapter,
-                                      hostdev->source.subsys.u.scsi.bus,
-                                      hostdev->source.subsys.u.scsi.target,
-                                      hostdev->source.subsys.u.scsi.unit,
-                                      hostdev->readonly)))
-            goto cleanup;
-
-        virSCSIDeviceSetUsedBy(scsi, "QEMU", def->name);
-
-        if (virSCSIDeviceListAdd(driver->activeScsiHostdevs, scsi) < 0) {
-            virSCSIDeviceFree(scsi);
-            goto cleanup;
-        }
-    }
-    ret = 0;
-
-cleanup:
-    virObjectUnlock(driver->activeScsiHostdevs);
-    return ret;
-}
-
-
-static int
-qemuDomainHostdevPciSysfsPath(virDomainHostdevDefPtr hostdev,
-                              char **sysfs_path)
-{
-    virPCIDeviceAddress config_address;
-
-    config_address.domain = hostdev->source.subsys.u.pci.addr.domain;
-    config_address.bus = hostdev->source.subsys.u.pci.addr.bus;
-    config_address.slot = hostdev->source.subsys.u.pci.addr.slot;
-    config_address.function = hostdev->source.subsys.u.pci.addr.function;
-
-    return virPCIDeviceAddressGetSysfsFile(&config_address, sysfs_path);
-}
-
-
-int
-qemuDomainHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev)
-{
-    char *sysfs_path = NULL;
-    int ret = -1;
-
-    if (qemuDomainHostdevPciSysfsPath(hostdev, &sysfs_path) < 0)
-        return ret;
-
-    ret = virPCIIsVirtualFunction(sysfs_path);
-
-    VIR_FREE(sysfs_path);
-
-    return ret;
-}
-
-
-static int
-qemuDomainHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
-                           int *vf)
-{
-    int ret = -1;
-    char *sysfs_path = NULL;
-
-    if (qemuDomainHostdevPciSysfsPath(hostdev, &sysfs_path) < 0)
-        return ret;
-
-    if (virPCIIsVirtualFunction(sysfs_path) == 1) {
-        if (virPCIGetVirtualFunctionInfo(sysfs_path, linkdev,
-                                         vf) < 0)
-            goto cleanup;
-    } else {
-        if (virPCIGetNetName(sysfs_path, linkdev) < 0)
-            goto cleanup;
-        *vf = -1;
-    }
-
-    ret = 0;
-
-cleanup:
-    VIR_FREE(sysfs_path);
-
-    return ret;
-}
-
-
-static int
-qemuDomainHostdevNetConfigVirtPortProfile(const char *linkdev, int vf,
-                                          virNetDevVPortProfilePtr virtPort,
-                                          const virMacAddr *macaddr,
-                                          const unsigned char *uuid,
-                                          bool associate)
-{
-    int ret = -1;
-
-    if (!virtPort)
-        return ret;
-
-    switch (virtPort->virtPortType) {
-    case VIR_NETDEV_VPORT_PROFILE_NONE:
-    case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH:
-    case VIR_NETDEV_VPORT_PROFILE_8021QBG:
-    case VIR_NETDEV_VPORT_PROFILE_LAST:
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("virtualport type %s is "
-                         "currently not supported on interfaces of type "
-                         "hostdev"),
-                       virNetDevVPortTypeToString(virtPort->virtPortType));
-        break;
-
-    case VIR_NETDEV_VPORT_PROFILE_8021QBH:
-        if (associate)
-            ret = virNetDevVPortProfileAssociate(NULL, virtPort, macaddr,
-                                                 linkdev, vf, uuid,
-                                                 VIR_NETDEV_VPORT_PROFILE_OP_CREATE, false);
-        else
-            ret = virNetDevVPortProfileDisassociate(NULL, virtPort,
-                                                    macaddr, linkdev, vf,
-                                                    VIR_NETDEV_VPORT_PROFILE_OP_DESTROY);
-        break;
-    }
-
-    return ret;
-}
-
-
-int
-qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
-                                  const unsigned char *uuid,
-                                  char *stateDir)
-{
-    char *linkdev = NULL;
-    virNetDevVlanPtr vlan;
-    virNetDevVPortProfilePtr virtPort;
-    int ret = -1;
-    int vf = -1;
-    int vlanid = -1;
-    bool port_profile_associate = true;
-    int isvf;
-
-    isvf = qemuDomainHostdevIsVirtualFunction(hostdev);
-    if (isvf <= 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("Interface type hostdev is currently supported on"
-                         " SR-IOV Virtual Functions only"));
-        return ret;
-    }
-
-    if (qemuDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
-        return ret;
-
-    vlan = virDomainNetGetActualVlan(hostdev->parent.data.net);
-    virtPort = virDomainNetGetActualVirtPortProfile(
-                                 hostdev->parent.data.net);
-    if (virtPort) {
-        if (vlan) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("direct setting of the vlan tag is not allowed "
-                             "for hostdev devices using %s mode"),
-                           virNetDevVPortTypeToString(virtPort->virtPortType));
-            goto cleanup;
-        }
-        ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf,
-                            virtPort, &hostdev->parent.data.net->mac, uuid,
-                            port_profile_associate);
-    } else {
-        /* Set only mac and vlan */
-        if (vlan) {
-            if (vlan->nTags != 1 || vlan->trunk) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("vlan trunking is not supported "
-                                 "by SR-IOV network devices"));
-                goto cleanup;
-            }
-            if (vf == -1) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("vlan can only be set for SR-IOV VFs, but "
-                                 "%s is not a VF"), linkdev);
-                goto cleanup;
-            }
-            vlanid = vlan->tag[0];
-        } else  if (vf >= 0) {
-            vlanid = 0; /* assure any current vlan tag is reset */
-        }
-
-        ret = virNetDevReplaceNetConfig(linkdev, vf,
-                                        &hostdev->parent.data.net->mac,
-                                        vlanid, stateDir);
-    }
-cleanup:
-    VIR_FREE(linkdev);
-    return ret;
-}
-
-
-int
-qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
-                                  char *stateDir)
-{
-    char *linkdev = NULL;
-    virNetDevVPortProfilePtr virtPort;
-    int ret = -1;
-    int vf = -1;
-    bool port_profile_associate = false;
-    int isvf;
-
-    /* This is only needed for PCI devices that have been defined
-     * using <interface type='hostdev'>. For all others, it is a NOP.
-     */
-    if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-        hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI ||
-        hostdev->parent.type != VIR_DOMAIN_DEVICE_NET ||
-        !hostdev->parent.data.net)
-       return 0;
-
-    isvf = qemuDomainHostdevIsVirtualFunction(hostdev);
-    if (isvf <= 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("Interface type hostdev is currently supported on"
-                         " SR-IOV Virtual Functions only"));
-        return ret;
-    }
-
-    if (qemuDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0)
-        return ret;
-
-    virtPort = virDomainNetGetActualVirtPortProfile(
-                                 hostdev->parent.data.net);
-    if (virtPort)
-        ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort,
-                                          &hostdev->parent.data.net->mac, NULL,
-                                          port_profile_associate);
-    else
-        ret = virNetDevRestoreNetConfig(linkdev, vf, stateDir);
-
-    VIR_FREE(linkdev);
-
-    return ret;
-}
-
-
-bool
-qemuHostdevHostSupportsPassthroughVFIO(void)
-{
-    DIR *iommuDir = NULL;
-    struct dirent *iommuGroup = NULL;
-    bool ret = false;
-
-    /* condition 1 - /sys/kernel/iommu_groups/ contains entries */
-    if (!(iommuDir = opendir("/sys/kernel/iommu_groups/")))
-        goto cleanup;
-
-    while ((iommuGroup = readdir(iommuDir))) {
-        /* skip ./ ../ */
-        if (STRPREFIX(iommuGroup->d_name, "."))
-            continue;
-
-        /* assume we found a group */
-        break;
-    }
-
-    if (!iommuGroup)
-        goto cleanup;
-    /* okay, iommu is on and recognizes groups */
-
-    /* condition 2 - /dev/vfio/vfio exists */
-    if (!virFileExists("/dev/vfio/vfio"))
-        goto cleanup;
-
-    ret = true;
-
-cleanup:
-    if (iommuDir)
-        closedir(iommuDir);
-
-    return ret;
-}
-
-
-#if HAVE_LINUX_KVM_H
-# include <linux/kvm.h>
-bool
-qemuHostdevHostSupportsPassthroughLegacy(void)
-{
-    int kvmfd = -1;
-    bool ret = false;
-
-    if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
-        goto cleanup;
-
-# ifdef KVM_CAP_IOMMU
-    if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
-        goto cleanup;
-
-    ret = true;
-# endif
-
-cleanup:
-    VIR_FORCE_CLOSE(kvmfd);
-
-    return ret;
-}
-#else
-bool
-qemuHostdevHostSupportsPassthroughLegacy(void)
-{
-    return false;
-}
-#endif
-
-
-static bool
-qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs,
-                                  size_t nhostdevs,
-                                  virQEMUCapsPtr qemuCaps)
-{
-    bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
-    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
-    size_t i;
-
-    /* assign defaults for hostdev passthrough */
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        int *backend = &hostdev->source.subsys.u.pci.backend;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        switch ((virDomainHostdevSubsysPciBackendType) *backend) {
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
-            if (supportsPassthroughVFIO &&
-                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
-                *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
-            } else if (supportsPassthroughKVM &&
-                       (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE) ||
-                        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
-                *backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
-            } else {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("host doesn't support passthrough of "
-                                 "host PCI devices"));
-                return false;
-            }
-
-            break;
-
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
-            if (!supportsPassthroughVFIO) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("host doesn't support VFIO PCI passthrough"));
-                return false;
-            }
-            break;
-
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
-            if (!supportsPassthroughKVM) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("host doesn't support legacy PCI passthrough"));
-                return false;
-            }
-
-            break;
-
-        case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
-            break;
-        }
-    }
-
-    return true;
-}
-
-
-int
-qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
-                             const char *name,
-                             const unsigned char *uuid,
-                             virDomainHostdevDefPtr *hostdevs,
-                             int nhostdevs,
-                             virQEMUCapsPtr qemuCaps)
-{
-    virPCIDeviceListPtr pcidevs = NULL;
-    int last_processed_hostdev_vf = -1;
-    size_t i;
-    int ret = -1;
-    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
-
-    if (!qemuPrepareHostdevPCICheckSupport(hostdevs, nhostdevs, qemuCaps))
-        goto cleanup;
-
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-
-    if (!(pcidevs = qemuGetPciHostDeviceList(hostdevs, nhostdevs)))
-        goto cleanup;
-
-    /* We have to use 9 loops here. *All* devices must
-     * be detached before we reset any of them, because
-     * in some cases you have to reset the whole PCI,
-     * which impacts all devices on it. Also, all devices
-     * must be reset before being marked as active.
-     */
-
-    /* Loop 1: validate that non-managed device isn't in use, eg
-     * by checking that device is either un-bound, or bound
-     * to pci-stub.ko
-     */
-
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-        virPCIDevicePtr other;
-
-        if (!virPCIDeviceIsAssignable(dev, !cfg->relaxedACS)) {
-            virReportError(VIR_ERR_OPERATION_INVALID,
-                           _("PCI device %s is not assignable"),
-                           virPCIDeviceGetName(dev));
-            goto cleanup;
-        }
-        /* The device is in use by other active domain if
-         * the dev is in list driver->activePciHostdevs.
-         */
-        if ((other = virPCIDeviceListFind(driver->activePciHostdevs, dev))) {
-            const char *other_name = NULL;
-            const char *other_drvname = NULL;
-            virPCIDeviceGetUsedBy(other, &other_drvname, &other_name);
-
-            if (other_name)
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("PCI device %s is in use by domain %s"),
-                               virPCIDeviceGetName(dev), other_name);
-            else
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("PCI device %s is already in use"),
-                               virPCIDeviceGetName(dev));
-            goto cleanup;
-        }
-    }
-
-    /* Loop 2: detach managed devices (i.e. bind to appropriate stub driver) */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-        if (virPCIDeviceGetManaged(dev) &&
-            virPCIDeviceDetach(dev, driver->activePciHostdevs, NULL) < 0)
-            goto reattachdevs;
-    }
-
-    /* Loop 3: Now that all the PCI hostdevs have been detached, we
-     * can safely reset them */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-
-        if (virPCIDeviceReset(dev, driver->activePciHostdevs,
-                              driver->inactivePciHostdevs) < 0)
-            goto reattachdevs;
-    }
-
-    /* Loop 4: For SRIOV network devices, Now that we have detached the
-     * the network device, set the netdev config */
-    for (i = 0; i < nhostdevs; i++) {
-         virDomainHostdevDefPtr hostdev = hostdevs[i];
-         if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-             continue;
-         if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-             continue;
-         if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
-             hostdev->parent.data.net) {
-             if (qemuDomainHostdevNetConfigReplace(hostdev, uuid,
-                                                   cfg->stateDir) < 0) {
-                 goto resetvfnetconfig;
-             }
-         }
-         last_processed_hostdev_vf = i;
-    }
-
-    /* Loop 5: Now mark all the devices as active */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-        if (virPCIDeviceListAdd(driver->activePciHostdevs, dev) < 0)
-            goto inactivedevs;
-    }
-
-    /* Loop 6: Now remove the devices from inactive list. */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-         virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-         virPCIDeviceListDel(driver->inactivePciHostdevs, dev);
-    }
-
-    /* Loop 7: Now set the used_by_domain of the device in
-     * driver->activePciHostdevs as domain name.
-     */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev, activeDev;
-
-        dev = virPCIDeviceListGet(pcidevs, i);
-        activeDev = virPCIDeviceListFind(driver->activePciHostdevs, dev);
-
-        if (activeDev)
-            virPCIDeviceSetUsedBy(activeDev, "QEMU", name);
-    }
-
-    /* Loop 8: Now set the original states for hostdev def */
-    for (i = 0; i < nhostdevs; i++) {
-        virPCIDevicePtr dev;
-        virPCIDevicePtr pcidev;
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            continue;
-
-        dev = virPCIDeviceNew(hostdev->source.subsys.u.pci.addr.domain,
-                              hostdev->source.subsys.u.pci.addr.bus,
-                              hostdev->source.subsys.u.pci.addr.slot,
-                              hostdev->source.subsys.u.pci.addr.function);
-
-        /* original states "unbind_from_stub", "remove_slot",
-         * "reprobe" were already set by pciDettachDevice in
-         * loop 2.
-         */
-        if ((pcidev = virPCIDeviceListFind(pcidevs, dev))) {
-            hostdev->origstates.states.pci.unbind_from_stub =
-                virPCIDeviceGetUnbindFromStub(pcidev);
-            hostdev->origstates.states.pci.remove_slot =
-                virPCIDeviceGetRemoveSlot(pcidev);
-            hostdev->origstates.states.pci.reprobe =
-                virPCIDeviceGetReprobe(pcidev);
-        }
-
-        virPCIDeviceFree(dev);
-    }
-
-    /* Loop 9: Now steal all the devices from pcidevs */
-    while (virPCIDeviceListCount(pcidevs) > 0)
-        virPCIDeviceListStealIndex(pcidevs, 0);
-
-    ret = 0;
-    goto cleanup;
-
-inactivedevs:
-    /* Only steal all the devices from driver->activePciHostdevs. We will
-     * free them in virObjectUnref().
-     */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-        virPCIDeviceListSteal(driver->activePciHostdevs, dev);
-    }
-
-resetvfnetconfig:
-    for (i = 0;
-         last_processed_hostdev_vf != -1 && i < last_processed_hostdev_vf; i++)
-        qemuDomainHostdevNetConfigRestore(hostdevs[i], cfg->stateDir);
-
-reattachdevs:
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-
-        /* NB: This doesn't actually re-bind to original driver, just
-         * unbinds from the stub driver
-         */
-        ignore_value(virPCIDeviceReattach(dev, driver->activePciHostdevs,
-                                          NULL));
-    }
-
-cleanup:
-    virObjectUnlock(driver->activePciHostdevs);
-    virObjectUnlock(driver->inactivePciHostdevs);
-    virObjectUnref(pcidevs);
-    virObjectUnref(cfg);
-    return ret;
-}
-
-
-int
-qemuPrepareHostdevUSBDevices(virQEMUDriverPtr driver,
-                             const char *name,
-                             virUSBDeviceListPtr list)
-{
-    size_t i, j;
-    unsigned int count;
-    virUSBDevicePtr tmp;
-
-    virObjectLock(driver->activeUsbHostdevs);
-    count = virUSBDeviceListCount(list);
-
-    for (i = 0; i < count; i++) {
-        virUSBDevicePtr usb = virUSBDeviceListGet(list, i);
-        if ((tmp = virUSBDeviceListFind(driver->activeUsbHostdevs, usb))) {
-            const char *other_name = NULL;
-            const char *other_drvname = NULL;
-            virUSBDeviceGetUsedBy(tmp, &other_drvname, &other_name);
-
-            if (other_name)
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("USB device %s is in use by domain %s"),
-                               virUSBDeviceGetName(tmp), other_name);
-            else
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("USB device %s is already in use"),
-                               virUSBDeviceGetName(tmp));
-            goto error;
-        }
-
-        virUSBDeviceSetUsedBy(usb, "QEMU", name);
-        VIR_DEBUG("Adding %03d.%03d dom=%s to activeUsbHostdevs",
-                  virUSBDeviceGetBus(usb), virUSBDeviceGetDevno(usb), name);
-        /*
-         * The caller is responsible to steal these usb devices
-         * from the virUSBDeviceList that passed in on success,
-         * perform rollback on failure.
-         */
-        if (virUSBDeviceListAdd(driver->activeUsbHostdevs, usb) < 0)
-            goto error;
-    }
-
-    virObjectUnlock(driver->activeUsbHostdevs);
-    return 0;
-
-error:
-    for (j = 0; j < i; j++) {
-        tmp = virUSBDeviceListGet(list, i);
-        virUSBDeviceListSteal(driver->activeUsbHostdevs, tmp);
-    }
-    virObjectUnlock(driver->activeUsbHostdevs);
-    return -1;
-}
-
-
-int
-qemuFindHostdevUSBDevice(virDomainHostdevDefPtr hostdev,
-                         bool mandatory,
-                         virUSBDevicePtr *usb)
-{
-    unsigned vendor = hostdev->source.subsys.u.usb.vendor;
-    unsigned product = hostdev->source.subsys.u.usb.product;
-    unsigned bus = hostdev->source.subsys.u.usb.bus;
-    unsigned device = hostdev->source.subsys.u.usb.device;
-    bool autoAddress = hostdev->source.subsys.u.usb.autoAddress;
-    int rc;
-
-    *usb = NULL;
-
-    if (vendor && bus) {
-        rc = virUSBDeviceFind(vendor, product, bus, device,
-                              NULL,
-                              autoAddress ? false : mandatory,
-                              usb);
-        if (rc < 0) {
-            return -1;
-        } else if (!autoAddress) {
-            goto out;
-        } else {
-            VIR_INFO("USB device %x:%x could not be found at previous"
-                     " address (bus:%u device:%u)",
-                     vendor, product, bus, device);
-        }
-    }
-
-    /* When vendor is specified, its USB address is either unspecified or the
-     * device could not be found at the USB device where it had been
-     * automatically found before.
-     */
-    if (vendor) {
-        virUSBDeviceListPtr devs;
-
-        rc = virUSBDeviceFindByVendor(vendor, product, NULL, mandatory, &devs);
-        if (rc < 0)
-            return -1;
-
-        if (rc == 1) {
-            *usb = virUSBDeviceListGet(devs, 0);
-            virUSBDeviceListSteal(devs, *usb);
-        }
-        virObjectUnref(devs);
-
-        if (rc == 0) {
-            goto out;
-        } else if (rc > 1) {
-            if (autoAddress) {
-                virReportError(VIR_ERR_OPERATION_FAILED,
-                               _("Multiple USB devices for %x:%x were found,"
-                                 " but none of them is at bus:%u device:%u"),
-                               vendor, product, bus, device);
-            } else {
-                virReportError(VIR_ERR_OPERATION_FAILED,
-                               _("Multiple USB devices for %x:%x, "
-                                 "use <address> to specify one"),
-                               vendor, product);
-            }
-            return -1;
-        }
-
-        hostdev->source.subsys.u.usb.bus = virUSBDeviceGetBus(*usb);
-        hostdev->source.subsys.u.usb.device = virUSBDeviceGetDevno(*usb);
-        hostdev->source.subsys.u.usb.autoAddress = true;
-
-        if (autoAddress) {
-            VIR_INFO("USB device %x:%x found at bus:%u device:%u (moved"
-                     " from bus:%u device:%u)",
-                     vendor, product,
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device,
-                     bus, device);
-        }
-    } else if (!vendor && bus) {
-        if (virUSBDeviceFindByBus(bus, device, NULL, mandatory, usb) < 0)
-            return -1;
-    }
-
-out:
-    if (!*usb)
-        hostdev->missing = true;
-    return 0;
-}
-
-
-static int
-qemuPrepareHostUSBDevices(virQEMUDriverPtr driver,
-                          virDomainDefPtr def,
-                          bool coldBoot)
-{
-    size_t i;
-    int ret = -1;
-    virUSBDeviceListPtr list;
-    virUSBDevicePtr tmp;
-    virDomainHostdevDefPtr *hostdevs = def->hostdevs;
-    int nhostdevs = def->nhostdevs;
-
-    /* To prevent situation where USB device is assigned to two domains
-     * we need to keep a list of currently assigned USB devices.
-     * This is done in several loops which cannot be joined into one big
-     * loop. See qemuPrepareHostdevPCIDevices()
-     */
-    if (!(list = virUSBDeviceListNew()))
-        goto cleanup;
-
-    /* Loop 1: build temporary list
-     */
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        bool required = true;
-        virUSBDevicePtr usb;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-            continue;
-
-        if (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_OPTIONAL ||
-            (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE &&
-             !coldBoot))
-            required = false;
-
-        if (qemuFindHostdevUSBDevice(hostdev, required, &usb) < 0)
-            goto cleanup;
-
-        if (usb && virUSBDeviceListAdd(list, usb) < 0) {
-            virUSBDeviceFree(usb);
-            goto cleanup;
-        }
-    }
-
-    /* Mark devices in temporary list as used by @name
-     * and add them do driver list. However, if something goes
-     * wrong, perform rollback.
-     */
-    if (qemuPrepareHostdevUSBDevices(driver, def->name, list) < 0)
-        goto cleanup;
-
-    /* Loop 2: Temporary list was successfully merged with
-     * driver list, so steal all items to avoid freeing them
-     * in cleanup label.
-     */
-    while (virUSBDeviceListCount(list) > 0) {
-        tmp = virUSBDeviceListGet(list, 0);
-        virUSBDeviceListSteal(list, tmp);
-    }
-
-    ret = 0;
-
-cleanup:
-    virObjectUnref(list);
-    return ret;
-}
-
-
-int
-qemuPrepareHostdevSCSIDevices(virQEMUDriverPtr driver,
-                              const char *name,
-                              virDomainHostdevDefPtr *hostdevs,
-                              int nhostdevs)
-{
-    size_t i, j;
-    int count;
-    virSCSIDeviceListPtr list;
-    virSCSIDevicePtr tmp;
-
-    /* Loop 1: Add the shared scsi host device to shared device
-     * table.
-     */
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainDeviceDef dev;
-
-        dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
-        dev.data.hostdev = hostdevs[i];
-
-        if (qemuAddSharedDevice(driver, &dev, name) < 0)
-            return -1;
-
-        if (qemuSetUnprivSGIO(&dev) < 0)
-            return -1;
-    }
-
-    /* To prevent situation where SCSI device is assigned to two domains
-     * we need to keep a list of currently assigned SCSI devices.
-     * This is done in several loops which cannot be joined into one big
-     * loop. See qemuPrepareHostdevPCIDevices()
-     */
-    if (!(list = virSCSIDeviceListNew()))
-        goto cleanup;
-
-    /* Loop 2: build temporary list */
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        virSCSIDevicePtr scsi;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
-            continue;
-
-        if (hostdev->managed) {
-            virReportError(VIR_ERR_XML_ERROR, "%s",
-                           _("SCSI host device doesn't support managed mode"));
-            goto cleanup;
-        }
-
-        if (!(scsi = virSCSIDeviceNew(hostdev->source.subsys.u.scsi.adapter,
-                                      hostdev->source.subsys.u.scsi.bus,
-                                      hostdev->source.subsys.u.scsi.target,
-                                      hostdev->source.subsys.u.scsi.unit,
-                                      hostdev->readonly)))
-            goto cleanup;
-
-        if (scsi && virSCSIDeviceListAdd(list, scsi) < 0) {
-            virSCSIDeviceFree(scsi);
-            goto cleanup;
-        }
-    }
-
-    /* Loop 3: Mark devices in temporary list as used by @name
-     * and add them to driver list. However, if something goes
-     * wrong, perform rollback.
-     */
-    virObjectLock(driver->activeScsiHostdevs);
-    count = virSCSIDeviceListCount(list);
-
-    for (i = 0; i < count; i++) {
-        virSCSIDevicePtr scsi = virSCSIDeviceListGet(list, i);
-        if ((tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi))) {
-            const char *other_name = NULL;
-            const char *other_drvname = NULL;
-            virSCSIDeviceGetUsedBy(tmp, &other_drvname, &other_name);
-
-            if (other_name)
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("SCSI device %s is in use by domain %s"),
-                               virSCSIDeviceGetName(tmp), other_name);
-            else
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("SCSI device %s is already in use"),
-                               virSCSIDeviceGetName(tmp));
-            goto error;
-        }
-
-        virSCSIDeviceSetUsedBy(scsi, "QEMU", name);
-        VIR_DEBUG("Adding %s to activeScsiHostdevs", virSCSIDeviceGetName(scsi));
-
-        if (virSCSIDeviceListAdd(driver->activeScsiHostdevs, scsi) < 0)
-            goto error;
-    }
-
-    virObjectUnlock(driver->activeScsiHostdevs);
-
-    /* Loop 4: Temporary list was successfully merged with
-     * driver list, so steal all items to avoid freeing them
-     * when freeing temporary list.
-     */
-    while (virSCSIDeviceListCount(list) > 0) {
-        tmp = virSCSIDeviceListGet(list, 0);
-        virSCSIDeviceListSteal(list, tmp);
-    }
-
-    virObjectUnref(list);
-    return 0;
-
-error:
-    for (j = 0; j < i; j++) {
-        tmp = virSCSIDeviceListGet(list, i);
-        virSCSIDeviceListSteal(driver->activeScsiHostdevs, tmp);
-    }
-    virObjectUnlock(driver->activeScsiHostdevs);
-cleanup:
-    virObjectUnref(list);
-    return -1;
-}
-
-
-int
-qemuPrepareHostDevices(virQEMUDriverPtr driver,
-                       virDomainDefPtr def,
-                       virQEMUCapsPtr qemuCaps,
-                       bool coldBoot)
-{
-    if (!def->nhostdevs)
-        return 0;
-
-    if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid,
-                                     def->hostdevs, def->nhostdevs,
-                                     qemuCaps) < 0)
-        return -1;
-
-    if (qemuPrepareHostUSBDevices(driver, def, coldBoot) < 0)
-        return -1;
-
-    if (qemuPrepareHostdevSCSIDevices(driver, def->name,
-                                      def->hostdevs, def->nhostdevs) < 0)
-        return -1;
-
-    return 0;
-}
-
-
-/*
- * Pre-condition: driver->inactivePciHostdevs & driver->activePciHostdevs
- * are locked
- */
-void
-qemuReattachPciDevice(virPCIDevicePtr dev, virQEMUDriverPtr driver)
-{
-    int retries = 100;
-
-    /* If the device is not managed and was attached to guest
-     * successfully, it must have been inactive.
-     */
-    if (!virPCIDeviceGetManaged(dev)) {
-        if (virPCIDeviceListAdd(driver->inactivePciHostdevs, dev) < 0)
-            virPCIDeviceFree(dev);
-        return;
-    }
-
-    while (virPCIDeviceWaitForCleanup(dev, "kvm_assigned_device")
-           && retries) {
-        usleep(100*1000);
-        retries--;
-    }
-
-    if (virPCIDeviceReattach(dev, driver->activePciHostdevs,
-                             driver->inactivePciHostdevs) < 0) {
-        virErrorPtr err = virGetLastError();
-        VIR_ERROR(_("Failed to re-attach PCI device: %s"),
-                  err ? err->message : _("unknown error"));
-        virResetError(err);
-    }
-    virPCIDeviceFree(dev);
-}
-
-
-void
-qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
-                                 const char *name,
-                                 virDomainHostdevDefPtr *hostdevs,
-                                 int nhostdevs)
-{
-    virPCIDeviceListPtr pcidevs;
-    size_t i;
-    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
-
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-
-    if (!(pcidevs = qemuGetActivePciHostDeviceList(driver,
-                                                   hostdevs,
-                                                   nhostdevs))) {
-        virErrorPtr err = virGetLastError();
-        VIR_ERROR(_("Failed to allocate PCI device list: %s"),
-                  err ? err->message : _("unknown error"));
-        virResetError(err);
-        goto cleanup;
-    }
-
-    /* Again 4 loops; mark all devices as inactive before reset
-     * them and reset all the devices before re-attach.
-     * Attach mac and port profile parameters to devices
-     */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-        virPCIDevicePtr activeDev = NULL;
-
-        /* delete the copy of the dev from pcidevs if it's used by
-         * other domain. Or delete it from activePciHostDevs if it had
-         * been used by this domain.
-         */
-        activeDev = virPCIDeviceListFind(driver->activePciHostdevs, dev);
-        if (activeDev) {
-                const char *tmp_name = NULL;
-                const char *tmp_drvname = NULL;
-                virPCIDeviceGetUsedBy(activeDev, &tmp_drvname, &tmp_name);
-                if (STRNEQ_NULLABLE(name, tmp_name)) {
-                    virPCIDeviceListDel(pcidevs, dev);
-                    continue;
-                }
-        }
-
-        virPCIDeviceListDel(driver->activePciHostdevs, dev);
-    }
-
-    /* At this point, any device that had been used by the guest is in
-     * pcidevs, but has been removed from activePciHostdevs.
-     */
-
-    /*
-     * For SRIOV net host devices, unset mac and port profile before
-     * reset and reattach device
-     */
-    for (i = 0; i < nhostdevs; i++)
-        qemuDomainHostdevNetConfigRestore(hostdevs[i], cfg->stateDir);
-
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
-
-        if (virPCIDeviceReset(dev, driver->activePciHostdevs,
-                              driver->inactivePciHostdevs) < 0) {
-            virErrorPtr err = virGetLastError();
-            VIR_ERROR(_("Failed to reset PCI device: %s"),
-                      err ? err->message : _("unknown error"));
-            virResetError(err);
-        }
-    }
-
-    while (virPCIDeviceListCount(pcidevs) > 0) {
-        virPCIDevicePtr dev = virPCIDeviceListStealIndex(pcidevs, 0);
-        qemuReattachPciDevice(dev, driver);
-    }
-
-    virObjectUnref(pcidevs);
-cleanup:
-    virObjectUnlock(driver->activePciHostdevs);
-    virObjectUnlock(driver->inactivePciHostdevs);
-    virObjectUnref(cfg);
-}
-
-
-static void
-qemuDomainReAttachHostUsbDevices(virQEMUDriverPtr driver,
-                                 const char *name,
-                                 virDomainHostdevDefPtr *hostdevs,
-                                 int nhostdevs)
-{
-    size_t i;
-
-    virObjectLock(driver->activeUsbHostdevs);
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        virUSBDevicePtr usb, tmp;
-        const char *used_by = NULL;
-        const char *used_by_drvname = NULL;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-            continue;
-        if (hostdev->missing)
-            continue;
-
-        usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
-                              hostdev->source.subsys.u.usb.device,
-                              NULL);
-
-        if (!usb) {
-            VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s",
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device,
-                     name);
-            continue;
-        }
-
-        /* Delete only those USB devices which belongs
-         * to domain @name because qemuProcessStart() might
-         * have failed because USB device is already taken.
-         * Therefore we want to steal only those devices from
-         * the list which were taken by @name */
-
-        tmp = virUSBDeviceListFind(driver->activeUsbHostdevs, usb);
-        virUSBDeviceFree(usb);
-
-        if (!tmp) {
-            VIR_WARN("Unable to find device %03d.%03d "
-                     "in list of active USB devices",
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device);
-            continue;
-        }
-
-        virUSBDeviceGetUsedBy(tmp, &used_by_drvname, &used_by);
-        if (STREQ_NULLABLE(used_by, name)) {
-            VIR_DEBUG("Removing %03d.%03d dom=%s from activeUsbHostdevs",
-                      hostdev->source.subsys.u.usb.bus,
-                      hostdev->source.subsys.u.usb.device,
-                      name);
-
-            virUSBDeviceListDel(driver->activeUsbHostdevs, tmp);
-        }
-    }
-    virObjectUnlock(driver->activeUsbHostdevs);
-}
-
-
-void
-qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver,
-                                  const char *name,
-                                  virDomainHostdevDefPtr *hostdevs,
-                                  int nhostdevs)
-{
-    size_t i;
-
-    virObjectLock(driver->activeScsiHostdevs);
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        virSCSIDevicePtr scsi, tmp;
-        const char *used_by = NULL;
-        const char *used_by_drvname = NULL;
-        virDomainDeviceDef dev;
-
-        dev.type = VIR_DOMAIN_DEVICE_HOSTDEV;
-        dev.data.hostdev = hostdev;
-
-        ignore_value(qemuRemoveSharedDevice(driver, &dev, name));
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
-            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)
-            continue;
-
-        if (!(scsi = virSCSIDeviceNew(hostdev->source.subsys.u.scsi.adapter,
-                                      hostdev->source.subsys.u.scsi.bus,
-                                      hostdev->source.subsys.u.scsi.target,
-                                      hostdev->source.subsys.u.scsi.unit,
-                                      hostdev->readonly))) {
-            VIR_WARN("Unable to reattach SCSI device %s:%d:%d:%d on domain %s",
-                     hostdev->source.subsys.u.scsi.adapter,
-                     hostdev->source.subsys.u.scsi.bus,
-                     hostdev->source.subsys.u.scsi.target,
-                     hostdev->source.subsys.u.scsi.unit,
-                     name);
-            continue;
-        }
-
-        /* Only delete the devices which are marked as being used by @name,
-         * because qemuProcessStart could fail on the half way. */
-
-        tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi);
-        virSCSIDeviceFree(scsi);
-
-        if (!tmp) {
-            VIR_WARN("Unable to find device %s:%d:%d:%d "
-                     "in list of active SCSI devices",
-                     hostdev->source.subsys.u.scsi.adapter,
-                     hostdev->source.subsys.u.scsi.bus,
-                     hostdev->source.subsys.u.scsi.target,
-                     hostdev->source.subsys.u.scsi.unit);
-            continue;
-        }
-
-        virSCSIDeviceGetUsedBy(tmp, &used_by_drvname, &used_by);
-        if (STREQ_NULLABLE(used_by, name)) {
-            VIR_DEBUG("Removing %s:%d:%d:%d dom=%s from activeScsiHostdevs",
-                      hostdev->source.subsys.u.scsi.adapter,
-                      hostdev->source.subsys.u.scsi.bus,
-                      hostdev->source.subsys.u.scsi.target,
-                      hostdev->source.subsys.u.scsi.unit,
-                      name);
-
-            virSCSIDeviceListDel(driver->activeScsiHostdevs, tmp);
-        }
-    }
-    virObjectUnlock(driver->activeScsiHostdevs);
-}
-
-void
-qemuDomainReAttachHostDevices(virQEMUDriverPtr driver,
-                              virDomainDefPtr def)
-{
-    if (!def->nhostdevs)
-        return;
-
-    qemuDomainReAttachHostdevDevices(driver, def->name, def->hostdevs,
-                                     def->nhostdevs);
-
-    qemuDomainReAttachHostUsbDevices(driver, def->name, def->hostdevs,
-                                     def->nhostdevs);
-
-    qemuDomainReAttachHostScsiDevices(driver, def->name, def->hostdevs,
-                                      def->nhostdevs);
-}
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
deleted file mode 100644
index ffb3167..0000000
--- a/src/qemu/qemu_hostdev.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * qemu_hostdev.h: QEMU hostdev management
- *
- * Copyright (C) 2006-2007, 2009-2013 Red Hat, Inc.
- * Copyright (C) 2006 Daniel P. Berrange
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Author: Daniel P. Berrange <berrange at redhat.com>
- */
-
-#ifndef __QEMU_HOSTDEV_H__
-# define __QEMU_HOSTDEV_H__
-
-# include "qemu_conf.h"
-# include "domain_conf.h"
-
-int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver,
-                                virDomainDefPtr def);
-int qemuUpdateActiveUsbHostdevs(virQEMUDriverPtr driver,
-                                virDomainDefPtr def);
-int qemuUpdateActiveScsiHostdevs(virQEMUDriverPtr driver,
-                                 virDomainDefPtr def);
-bool qemuHostdevHostSupportsPassthroughLegacy(void);
-bool qemuHostdevHostSupportsPassthroughVFIO(void);
-int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
-                                 const char *name,
-                                 const unsigned char *uuid,
-                                 virDomainHostdevDefPtr *hostdevs,
-                                 int nhostdevs,
-                                 virQEMUCapsPtr qemuCaps);
-int qemuFindHostdevUSBDevice(virDomainHostdevDefPtr hostdev,
-                             bool mandatory,
-                             virUSBDevicePtr *usb);
-int qemuPrepareHostdevUSBDevices(virQEMUDriverPtr driver,
-                                 const char *name,
-                                 virUSBDeviceListPtr list);
-int qemuPrepareHostdevSCSIDevices(virQEMUDriverPtr driver,
-                                  const char *name,
-                                  virDomainHostdevDefPtr *hostdevs,
-                                  int nhostdevs);
-int qemuPrepareHostDevices(virQEMUDriverPtr driver,
-                           virDomainDefPtr def,
-                           virQEMUCapsPtr qemuCaps,
-                           bool coldBoot);
-void qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver,
-                                       const char *name,
-                                       virDomainHostdevDefPtr *hostdevs,
-                                       int nhostdevs);
-void qemuReattachPciDevice(virPCIDevicePtr dev, virQEMUDriverPtr driver);
-void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
-                                      const char *name,
-                                      virDomainHostdevDefPtr *hostdevs,
-                                      int nhostdevs);
-void qemuDomainReAttachHostDevices(virQEMUDriverPtr driver,
-                                   virDomainDefPtr def);
-int qemuDomainHostdevIsVirtualFunction(virDomainHostdevDefPtr hostdev);
-int qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
-                                      const unsigned char *uuid,
-                                      char *stateDir);
-int qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
-                                      char *stateDir);
-
-#endif /* __QEMU_HOSTDEV_H__ */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7a8caf1..8ffa663 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -30,7 +30,7 @@
 #include "qemu_domain.h"
 #include "qemu_command.h"
 #include "qemu_bridge_filter.h"
-#include "qemu_hostdev.h"
+#include "qemu_conf.h"
 #include "domain_audit.h"
 #include "domain_nwfilter.h"
 #include "virlog.h"
@@ -50,6 +50,7 @@
 #include "virstoragefile.h"
 #include "virstring.h"
 #include "virtime.h"
+#include "virhostdev.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 #define CHANGE_MEDIA_RETRIES 10
@@ -1156,12 +1157,20 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
     bool teardownlabel = false;
     int backend = hostdev->source.subsys.u.pci.backend;
     unsigned long long memKB;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virHostdevManagerPtr hostdev_mgr;
+    unsigned int flags = 0;
 
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
         return -1;
 
-    if (qemuPrepareHostdevPCIDevices(driver, vm->def->name, vm->def->uuid,
-                                     &hostdev, 1, priv->qemuCaps) < 0)
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (!cfg->relaxedACS)
+        flags |= VIR_STRICT_ACS_CHECK;
+    if (hostdev_mgr == NULL ||
+        virHostdevPreparePciHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                     vm->def->name, vm->def->uuid,
+                                     &hostdev, 1, flags) < 0)
         return -1;
 
     switch ((virDomainHostdevSubsysPciBackendType) backend) {
@@ -1267,7 +1276,8 @@ error:
     if (releaseaddr)
         qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
 
-    qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
+    virHostdevReAttachPciHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                  vm->def->name, &hostdev, 1);
 
     VIR_FREE(devstr);
     VIR_FREE(configfd_name);
@@ -1453,28 +1463,23 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
                               virDomainHostdevDefPtr hostdev)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virUSBDeviceList *list = NULL;
-    virUSBDevicePtr usb = NULL;
     char *devstr = NULL;
     bool added = false;
     bool teardowncgroup = false;
     bool teardownlabel = false;
     int ret = -1;
-
-    if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
+    virHostdevManagerPtr hostdev_mgr;
+
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr == NULL ||
+        virHostdevPrepareUsbHostdevs(hostdev_mgr,
+                                     QEMU_DRIVER_NAME,
+                                     vm->def->name,
+                                     &hostdev,
+                                     1, 0) < 0)
         return -1;
 
-    if (!(list = virUSBDeviceListNew()))
-        goto cleanup;
-
-    if (virUSBDeviceListAdd(list, usb) < 0)
-        goto cleanup;
-
-    if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0)
-        goto cleanup;
-
     added = true;
-    virUSBDeviceListSteal(list, usb);
 
     if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
         goto cleanup;
@@ -1519,13 +1524,9 @@ cleanup:
                                                   vm->def, hostdev, NULL) < 0)
             VIR_WARN("Unable to restore host device labelling on hotplug fail");
         if (added)
-            virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
+            virHostdevReAttachUsbHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                          vm->def->name, &hostdev, 1);
     }
-    if (list && usb &&
-        !virUSBDeviceListFind(list, usb) &&
-        !virUSBDeviceListFind(driver->activeUsbHostdevs, usb))
-        virUSBDeviceFree(usb);
-    virObjectUnref(list);
     VIR_FREE(devstr);
     return ret;
 }
@@ -1542,6 +1543,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
     char *drvstr = NULL;
     bool teardowncgroup = false;
     bool teardownlabel = false;
+    virHostdevManagerPtr hostdev_mgr;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
         !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
@@ -1555,8 +1557,12 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
     if (!cont)
         return -1;
 
-    if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
-                                      &hostdev, 1)) {
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr == NULL ||
+        virHostdevPrepareScsiHostdevs(hostdev_mgr,
+                                      QEMU_DRIVER_NAME,
+                                      vm->def->name,
+                                      &hostdev, 1) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
                        hostdev->source.subsys.u.scsi.adapter,
@@ -1613,7 +1619,8 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
     ret = 0;
 cleanup:
     if (ret < 0) {
-        qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1);
+        virHostdevReAttachScsiHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                       vm->def->name, &hostdev, 1);
         if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
             VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
         if (teardownlabel &&
@@ -2526,62 +2533,41 @@ qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
 
 
 static void
-qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
-                              virDomainObjPtr vm,
+qemuDomainRemovePCIHostDevice(virDomainObjPtr vm,
                               virDomainHostdevDefPtr hostdev)
 {
-    virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
-    virPCIDevicePtr pci;
-    virPCIDevicePtr activePci;
-
-    virObjectLock(driver->activePciHostdevs);
-    virObjectLock(driver->inactivePciHostdevs);
-    pci = virPCIDeviceNew(subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
-                          subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
-    if (pci) {
-        activePci = virPCIDeviceListSteal(driver->activePciHostdevs, pci);
-        if (activePci &&
-            virPCIDeviceReset(activePci, driver->activePciHostdevs,
-                              driver->inactivePciHostdevs) == 0) {
-            qemuReattachPciDevice(activePci, driver);
-        } else {
-            /* reset of the device failed, treat it as if it was returned */
-            virPCIDeviceFree(activePci);
-        }
-        virPCIDeviceFree(pci);
-    }
-    virObjectUnlock(driver->activePciHostdevs);
-    virObjectUnlock(driver->inactivePciHostdevs);
+    virHostdevManagerPtr hostdev_mgr;
+
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr != NULL)
+        virHostdevReAttachPciHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                      vm->def->name, &hostdev, 1);
 
     qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
 }
 
 static void
-qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
-                              virDomainObjPtr vm ATTRIBUTE_UNUSED,
+qemuDomainRemoveUSBHostDevice(virDomainObjPtr vm,
                               virDomainHostdevDefPtr hostdev)
 {
-    virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
-    virUSBDevicePtr usb;
-
-    usb = virUSBDeviceNew(subsys->u.usb.bus, subsys->u.usb.device, NULL);
-    if (usb) {
-        virObjectLock(driver->activeUsbHostdevs);
-        virUSBDeviceListDel(driver->activeUsbHostdevs, usb);
-        virObjectUnlock(driver->activeUsbHostdevs);
-        virUSBDeviceFree(usb);
-    } else {
-        VIR_WARN("Unable to find device %03d.%03d in list of used USB devices",
-                 subsys->u.usb.bus, subsys->u.usb.device);
-    }
+    virHostdevManagerPtr hostdev_mgr;
+
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr != NULL)
+        virHostdevReAttachUsbHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                      vm->def->name, &hostdev, 1);
 }
 
 static void
-qemuDomainRemoveSCSIHostDevice(virQEMUDriverPtr driver,
-                               virDomainObjPtr vm,
+qemuDomainRemoveSCSIHostDevice(virDomainObjPtr vm,
                                virDomainHostdevDefPtr hostdev)
 {
-    qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1);
+    virHostdevManagerPtr hostdev_mgr;
+
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr != NULL)
+        virHostdevReAttachScsiHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                       vm->def->name, &hostdev, 1);
 }
 
 static void
@@ -2621,17 +2607,15 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
 
     virDomainAuditHostdev(vm, hostdev, "detach", true);
 
-    qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
-
     switch ((enum virDomainHostdevSubsysType) hostdev->source.subsys.type) {
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
-        qemuDomainRemovePCIHostDevice(driver, vm, hostdev);
+        qemuDomainRemovePCIHostDevice(vm, hostdev);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
-        qemuDomainRemoveUSBHostDevice(driver, vm, hostdev);
+        qemuDomainRemoveUSBHostDevice(vm, hostdev);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
-        qemuDomainRemoveSCSIHostDevice(driver, vm, hostdev);
+        qemuDomainRemoveSCSIHostDevice(vm, hostdev);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
         break;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9331744..3247ace 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -39,10 +39,10 @@
 #include "qemu_capabilities.h"
 #include "qemu_monitor.h"
 #include "qemu_command.h"
-#include "qemu_hostdev.h"
 #include "qemu_hotplug.h"
 #include "qemu_bridge_filter.h"
 #include "qemu_migration.h"
+#include "qemu_conf.h"
 
 #include "cpu/cpu.h"
 #include "datatypes.h"
@@ -66,6 +66,7 @@
 #include "viratomic.h"
 #include "virnuma.h"
 #include "virstring.h"
+#include "virhostdev.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -3118,6 +3119,8 @@ qemuProcessReconnect(void *opaque)
     int reason;
     virQEMUDriverConfigPtr cfg;
     size_t i;
+    virHostdevManagerPtr hostdev_mgr;
+    unsigned int flags;
 
     memcpy(&oldjob, &data->oldjob, sizeof(oldjob));
 
@@ -3149,14 +3152,12 @@ qemuProcessReconnect(void *opaque)
         priv->agentError = true;
     }
 
-    if (qemuUpdateActivePciHostdevs(driver, obj->def) < 0) {
-        goto error;
-    }
-
-    if (qemuUpdateActiveUsbHostdevs(driver, obj->def) < 0)
-        goto error;
 
-    if (qemuUpdateActiveScsiHostdevs(driver, obj->def) < 0)
+    hostdev_mgr = virHostdevManagerGetDefault();
+    flags = VIR_SP_PCI_HOSTDEV | VIR_SP_USB_HOSTDEV | VIR_SP_SCSI_HOSTDEV;
+    if (hostdev_mgr == NULL ||
+        virHostdevUpdateActiveHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                       obj->def, flags) < 0)
         goto error;
 
     if (qemuConnectCgroup(driver, obj) < 0)
@@ -3588,6 +3589,9 @@ int qemuProcessStart(virConnectPtr conn,
     virQEMUDriverConfigPtr cfg;
     virCapsPtr caps = NULL;
 
+    virHostdevManagerPtr hostdev_mgr;
+    unsigned int hostdev_flags;
+
     VIR_DEBUG("vm=%p name=%s id=%d pid=%llu",
               vm, vm->def->name, vm->def->id,
               (unsigned long long)vm->pid);
@@ -3676,8 +3680,16 @@ int qemuProcessStart(virConnectPtr conn,
 
     /* Must be run before security labelling */
     VIR_DEBUG("Preparing host devices");
-    if (qemuPrepareHostDevices(driver, vm->def, priv->qemuCaps,
-                               !migrateFrom) < 0)
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (hostdev_mgr == NULL)
+        goto cleanup;
+    hostdev_flags = VIR_SP_PCI_HOSTDEV | VIR_SP_USB_HOSTDEV | VIR_SP_SCSI_HOSTDEV;
+    if (!migrateFrom)
+        hostdev_flags |= VIR_COLD_BOOT;
+    if (!cfg->relaxedACS)
+        hostdev_flags |= VIR_STRICT_ACS_CHECK;
+    if (virHostdevPrepareDomainHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                        vm->def, hostdev_flags) < 0)
         goto cleanup;
 
     VIR_DEBUG("Preparing chr devices");
@@ -4213,6 +4225,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     char *timestamp;
     char ebuf[1024];
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virHostdevManagerPtr hostdev_mgr;
+    unsigned int hostdev_flags;
 
     VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%llu flags=%x",
               vm, vm->def->name, vm->def->id,
@@ -4356,7 +4370,11 @@ void qemuProcessStop(virQEMUDriverPtr driver,
         priv->ccwaddrs = NULL;
     }
 
-    qemuDomainReAttachHostDevices(driver, vm->def);
+    hostdev_mgr = virHostdevManagerGetDefault();
+    hostdev_flags = VIR_SP_PCI_HOSTDEV | VIR_SP_USB_HOSTDEV | VIR_SP_SCSI_HOSTDEV;
+    if (hostdev_mgr != NULL)
+        virHostdevReAttachDomainHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
+                                         vm->def, hostdev_flags);
 
     def = vm->def;
     for (i = 0; i < def->nnets; i++) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml
index 422127c..b9a221a 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml
@@ -24,6 +24,7 @@
     <controller type='ide' index='0'/>
     <controller type='pci' index='0' model='pci-root'/>
     <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='kvm'/>
       <source>
         <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
       </source>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
index d65ef87..9e79348 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdev.xml
@@ -24,6 +24,7 @@
     <controller type='pci' index='0' model='pci-root'/>
     <interface type='hostdev' managed='yes'>
       <mac address='00:11:22:33:44:55'/>
+      <driver name='kvm'/>
       <source>
         <address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/>
       </source>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml
index a5e59b2..924842b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml
@@ -33,12 +33,14 @@
       <rom file='/etc/fake/bootrom.bin'/>
     </interface>
     <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='kvm'/>
       <source>
         <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
       </source>
       <rom bar='off'/>
     </hostdev>
     <hostdev mode='subsystem' type='pci' managed='yes'>
+      <driver name='kvm'/>
       <source>
         <address domain='0x0000' bus='0x06' slot='0x12' function='0x6'/>
       </source>
-- 
1.6.0.2




More information about the libvir-list mailing list