[libvirt] [PATCHv3 3/4] change qemu driver to use hostdev common library

Jim Fehlig jfehlig at suse.com
Wed Aug 14 17:48:39 UTC 2013


cyliu at suse.com wrote:
> From: Chunyan Liu <cyliu at suse.com>
>
> Change qemu driver to use hostdev common library instead of APIs in
> qemu_hostdev.[ch]
>
> 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_driver.c  |   72 +---
>  src/qemu/qemu_hostdev.c | 1289 -----------------------------------------------
>  src/qemu/qemu_hostdev.h |   72 ---
>  src/qemu/qemu_hotplug.c |  127 ++---
>  src/qemu/qemu_process.c |   34 +-
>  9 files changed, 88 insertions(+), 1518 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 9176b95..1124311 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -97,7 +97,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 a89e414..20fa84e 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -632,7 +632,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_conf.c qemu/qemu_conf.h			\
>  		qemu/qemu_process.c qemu/qemu_process.h			\
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index aa3a2fd..977317f 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 8229cfc..26050ec 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -52,6 +52,7 @@
>  #  error "Port me"
>  # endif
>  
> +# define QEMU_DRIVER_NAME "QEMU"
>  typedef struct _virQEMUDriver virQEMUDriver;
>  typedef virQEMUDriver *virQEMUDriverPtr;
>  
> @@ -203,14 +204,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_driver.c b/src/qemu/qemu_driver.c
> index 5634abf..776c16b 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
> @@ -691,18 +689,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;
>  
> @@ -983,9 +969,6 @@ qemuStateCleanup(void) {
>  
>      virNWFilterUnRegisterCallbackDriver(&qemuCallbackDriver);
>      virObjectUnref(qemu_driver->config);
> -    virObjectUnref(qemu_driver->activePciHostdevs);
> -    virObjectUnref(qemu_driver->inactivePciHostdevs);
> -    virObjectUnref(qemu_driver->activeUsbHostdevs);
>      virHashFree(qemu_driver->sharedDevices);
>      virObjectUnref(qemu_driver->caps);
>      virQEMUCapsCacheFree(qemu_driver->qemuCapsCache);
> @@ -10906,12 +10889,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);
>  
> @@ -10945,18 +10928,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 (virHostdevPciNodeDeviceDetach(hostdev_mgr, pci) < 0) {
> +        goto cleanup;
>      }
>  
>      ret = 0;
> -out:
> -    virObjectUnlock(driver->inactivePciHostdevs);
> -    virObjectUnlock(driver->activePciHostdevs);
>  cleanup:
>      virPCIDeviceFree(pci);
>      virNodeDeviceDefFree(def);
> @@ -10973,13 +10950,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)
> @@ -10999,33 +10975,12 @@ qemuNodeDeviceReAttach(virNodeDevicePtr dev)
>      if (!pci)
>          goto cleanup;
>  
> -    virObjectLock(driver->activePciHostdevs);
> -    virObjectLock(driver->inactivePciHostdevs);
> -    other = virPCIDeviceListFind(driver->activePciHostdevs, pci);
> -    if (other) {
> -        const char *other_name = virPCIDeviceGetUsedBy(other);
> -
> -        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 (virHostdevPciNodeDeviceReAttach(hostdev_mgr, pci) < 0)
>          goto out;
>  
>      ret = 0;
>  out:
> -    virObjectUnlock(driver->inactivePciHostdevs);
> -    virObjectUnlock(driver->activePciHostdevs);
>      virPCIDeviceFree(pci);
>  cleanup:
>      virNodeDeviceDefFree(def);
> @@ -11036,12 +10991,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)
> @@ -11061,17 +11016,12 @@ 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 (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 21fe47f..0000000
> --- a/src/qemu/qemu_hostdev.c
> +++ /dev/null
> @@ -1,1289 +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 "qemu_hostdev.h"
> -#include "virlog.h"
> -#include "virerror.h"
> -#include "viralloc.h"
> -#include "virpci.h"
> -#include "virusb.h"
> -#include "virscsi.h"
> -#include "virnetdev.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, 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, 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, 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 virMacAddrPtr 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;
> -
> -    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;
> -}
> -
> -int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
> -                                 const char *name,
> -                                 const unsigned char *uuid,
> -                                 virDomainHostdevDefPtr *hostdevs,
> -                                 int nhostdevs)
> -{
> -    virPCIDeviceListPtr pcidevs;
> -    int last_processed_hostdev_vf = -1;
> -    size_t i;
> -    int ret = -1;
> -    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> -
> -    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 = virPCIDeviceGetUsedBy(other);
> -
> -            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, 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++) {
> -         virDomainHostdevDefPtr hostdev = hostdevs[i];
> -         if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
> -             hostdev->parent.data.net) {
> -             qemuDomainHostdevNetConfigRestore(hostdev, 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
> -         */
> -        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 = virUSBDeviceGetUsedBy(tmp);
> -
> -            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, 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 = virSCSIDeviceGetUsedBy(tmp);
> -
> -            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, 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,
> -                           bool coldBoot)
> -{
> -    if (!def->nhostdevs)
> -        return 0;
> -
> -    if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid,
> -                                     def->hostdevs, def->nhostdevs) < 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 &&
> -            STRNEQ_NULLABLE(name, virPCIDeviceGetUsedBy(activeDev))) {
> -            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++) {
> -         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) {
> -             qemuDomainHostdevNetConfigRestore(hostdev, 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;
> -
> -        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;
> -        }
> -
> -        used_by = virUSBDeviceGetUsedBy(tmp);
> -        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;
> -        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;
> -        }
> -
> -        used_by = virSCSIDeviceGetUsedBy(tmp);
> -        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 327d4d5..0000000
> --- a/src/qemu/qemu_hostdev.h
> +++ /dev/null
> @@ -1,72 +0,0 @@
> -/*
> - * qemu_hostdev.h: QEMU hostdev management
> - *
> - * Copyright (C) 2006-2007, 2009-2010 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);
> -int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
> -                                 const char *name,
> -                                 const unsigned char *uuid,
> -                                 virDomainHostdevDefPtr *hostdevs,
> -                                 int nhostdevs);
> -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,
> -                           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 032de69..c94fd16 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -29,7 +29,8 @@
>  #include "qemu_domain.h"
>  #include "qemu_command.h"
>  #include "qemu_bridge_filter.h"
> -#include "qemu_hostdev.h"
> +#include "qemu_conf.h"
> +
>   

Spurious whitespace addition.

>  #include "domain_audit.h"
>  #include "domain_nwfilter.h"
>  #include "virlog.h"
> @@ -49,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
> @@ -1007,12 +1009,19 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
>      int configfd = -1;
>      char *configfd_name = NULL;
>      bool releaseaddr = false;
> +    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) < 0)
> +    hostdev_mgr = virHostdevManagerGetDefault();
> +    if (!cfg->relaxedACS)
> +        flags |= VIR_STRICT_ACS_CHECK;
> +    if (virHostdevPreparePciHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
> +                                     vm->def->name, vm->def->uuid,
> +                                     &hostdev, 1, flags) < 0)
>          return -1;
>  
>      if (hostdev->source.subsys.u.pci.backend
> @@ -1093,7 +1102,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);
> @@ -1278,26 +1288,21 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
>                                    virDomainHostdevDefPtr hostdev)
>  {
>      qemuDomainObjPrivatePtr priv = vm->privateData;
> -    virUSBDeviceList *list = NULL;
>      virUSBDevicePtr usb = NULL;
>      char *devstr = NULL;
>      bool added = false;
>      int ret = -1;
> +    virHostdevManagerPtr hostdev_mgr;
>  
> -    if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
> -        return -1;
> -
> -    if (!(list = virUSBDeviceListNew()))
> -        goto cleanup;
> -
> -    if (virUSBDeviceListAdd(list, usb) < 0)
> -        goto cleanup;
> -
> -    if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0)
> +    hostdev_mgr = virHostdevManagerGetDefault();
> +    if (virHostdevPrepareUsbHostdevs(hostdev_mgr,
> +                                     QEMU_DRIVER_NAME,
> +                                     vm->def->name,
> +                                     &hostdev,
> +                                     1, 0) < 0)
>          goto cleanup;
>  
>      added = true;
> -    virUSBDeviceListSteal(list, usb);
>  
>      if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
>          if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
> @@ -1326,9 +1331,9 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
>      ret = 0;
>  cleanup:
>      if (added)
> -        virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
> +        virHostdevReAttachUsbHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
> +                                      vm->def->name, &hostdev, 1);
>      virUSBDeviceFree(usb);
> -    virObjectUnref(list);
>      VIR_FREE(devstr);
>      return ret;
>  }
> @@ -1342,6 +1347,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
>      qemuDomainObjPrivatePtr priv = vm->privateData;
>      char *devstr = NULL;
>      char *drvstr = NULL;
> +    virHostdevManagerPtr hostdev_mgr;
>  
>      if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
>          !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
> @@ -1351,8 +1357,11 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
>          return -1;
>      }
>  
> -    if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
> -                                      &hostdev, 1)) {
> +    hostdev_mgr = virHostdevManagerGetDefault();
> +    if (virHostdevPrepareScsiHostdevs(hostdev_mgr,
> +                                     QEMU_DRIVER_NAME,
> +                                     vm->def->name,
> +                                     &hostdev, 1) < 0) {
>   

Parameter alignment seems a bit off.

>          virReportError(VIR_ERR_INTERNAL_ERROR,
>                         _("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
>                         hostdev->source.subsys.u.scsi.adapter,
> @@ -1400,7 +1409,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);
>      VIR_FREE(drvstr);
>      VIR_FREE(devstr);
>      return ret;
> @@ -2362,71 +2372,38 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
>  
>  
>  static void
> -qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
> -                              virDomainObjPtr vm,
> +qemuDomainRemovePCIHostDevice(virDomainObjPtr vm,
>                                virDomainHostdevDefPtr hostdev)
>  {
> -    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> -    virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
> -    virPCIDevicePtr pci;
> -    virPCIDevicePtr activePci;
> +    virHostdevManagerPtr hostdev_mgr;
>  
> -    /*
> -     * For SRIOV net host devices, unset mac and port profile before
> -     * reset and reattach device
> -     */
> -    if (hostdev->parent.data.net)
> -        qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
> -
> -    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);
> +    hostdev_mgr = virHostdevManagerGetDefault();
> +    virHostdevReAttachPciHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
> +                              vm->def->name, &hostdev, 1);
>   

Parameter alignment off.

>  
>      qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
> -    virObjectUnref(cfg);
>  }
>  
>  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();
> +    virHostdevReAttachPciHostdevs(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();
> +    virHostdevReAttachScsiHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
> +                                   vm->def->name, &hostdev, 1);
>  }
>  
>  static void
> @@ -2467,13 +2444,13 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
>  
>      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 d631a6f..0f32c6c 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -38,10 +38,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 "datatypes.h"
>  #include "virlog.h"
> @@ -64,6 +64,7 @@
>  #include "viratomic.h"
>  #include "virnuma.h"
>  #include "virstring.h"
> +#include "virhostdev.h"
>  
>  #define VIR_FROM_THIS VIR_FROM_QEMU
>  
> @@ -3018,6 +3019,8 @@ qemuProcessReconnect(void *opaque)
>      int reason;
>      virQEMUDriverConfigPtr cfg;
>      size_t i;
> +    virHostdevManagerPtr hostdev_mgr;
> +    unsigned int flags;
>  
>      memcpy(&oldjob, &data->oldjob, sizeof(oldjob));
>  
> @@ -3049,14 +3052,11 @@ 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 (virHostdevPrepareDomainHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
> +                                  obj->def, flags) < 0)
>   

Parameter alignment off.

>          goto error;
>  
>      if (qemuConnectCgroup(driver, obj) < 0)
> @@ -3453,6 +3453,8 @@ int qemuProcessStart(virConnectPtr conn,
>      unsigned int stop_flags;
>      virQEMUDriverConfigPtr cfg;
>      virCapsPtr caps = NULL;
> +    virHostdevManagerPtr hostdev_mgr;
> +    unsigned int hostdev_flags;
>  
>      /* Okay, these are just internal flags,
>       * but doesn't hurt to check */
> @@ -3527,7 +3529,14 @@ int qemuProcessStart(virConnectPtr conn,
>  
>      /* Must be run before security labelling */
>      VIR_DEBUG("Preparing host devices");
> -    if (qemuPrepareHostDevices(driver, vm->def, !migrateFrom) < 0)
> +    hostdev_mgr = virHostdevManagerGetDefault();
> +    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)
>   

Parameter alignment off.

>          goto cleanup;
>  
>      VIR_DEBUG("Preparing chr devices");
> @@ -4075,6 +4084,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 '%s' pid=%d flags=%x",
>                vm->def->name, vm->pid, flags);
> @@ -4217,7 +4228,10 @@ 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;
> +    virHostdevReAttachDomainHostdevs(hostdev_mgr, QEMU_DRIVER_NAME,
> +                               vm->def, hostdev_flags);
>   

Parameter alignment off.

Again, this is one of those patches that I hope other libvirt devs with
more expertise in this area of code can review.

Regards,
Jim

>  
>      def = vm->def;
>      for (i = 0; i < def->nnets; i++) {
>   




More information about the libvir-list mailing list