2013/8/12 Jim Fehlig <jfehlig@suse.com>

> +int
> +virHostdevPrepareScsiHostdevs(virHostdevManagerPtr mgr,
> +                              const char *drv_name,
> +                              const char *dom_name,
> +                              virDomainHostdevDefPtr *hostdevs,
> +                              int nhostdevs)
> +{
> +    size_t i, j;
> +    int count;
> +    virSCSIDeviceListPtr list;
> +    virSCSIDevicePtr tmp;
> +
> +    /* To prevent situation where SCSI device is assigned to two domains
> +     * we need to keep a list of currently assigned SCSI devices.
> +     */
> +    if (!(list = virSCSIDeviceListNew()))
> +        goto cleanup;
> +
> +    /* Loop 1: 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 2: Mark devices in temporary list as used by
> +     * and add them to driver list. However, if something goes
> +     * wrong, perform rollback.
> +     */
> +    virObjectLock(mgr->activeScsiHostdevs);
> +    count = virSCSIDeviceListCount(list);
> +
> +    for (i = 0; i < count; i++) {
> +        virSCSIDevicePtr scsi = virSCSIDeviceListGet(list, i);
> +        if ((tmp = virSCSIDeviceListFind(mgr->activeScsiHostdevs, scsi))) {
> +            char *other_drvname = NULL;
> +            char *other_domname = NULL;
> +            virSCSIDeviceGetUsedBy(tmp, &other_drvname, &other_domname);
> +
> +            if (other_drvname && other_domname)
> +                virReportError(VIR_ERR_OPERATION_INVALID,
> +                               _("SCSI device %s is in use by driver %s domain %s"),
> +                               virSCSIDeviceGetName(tmp), other_drvname, other_domname);
> +            else
> +                virReportError(VIR_ERR_OPERATION_INVALID,
> +                               _("SCSI device %s is already in use"),
> +                               virSCSIDeviceGetName(tmp));
> +            goto error;
> +        }
> +
> +        virSCSIDeviceSetUsedBy(scsi, drv_name, dom_name);
> +        VIR_DEBUG("Adding %s to activeScsiHostdevs", virSCSIDeviceGetName(scsi));
> +
> +        if (virSCSIDeviceListAdd(mgr->activeScsiHostdevs, scsi) < 0)
> +            goto error;
> +    }
> +
> +    virObjectUnlock(mgr->activeScsiHostdevs);
> +
> +    /* Loop 3: 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);
>

Shouldn't this be 'virSCSIDeviceListGet(list, j)'?

Oh, shamed. Yes, should be 'virSCSIDeviceListGet(list, j)'. I copied it from qemu_hostdev.c, wrong in qemu_hostdev.c too.

> +        virSCSIDeviceListSteal(mgr->activeScsiHostdevs, tmp);
> +    }
> +    virObjectUnlock(mgr->activeScsiHostdevs);
> +cleanup:
> +    virObjectUnref(list);
> +    return -1;
> +}
> +
> +
> +int
> +virHostdevPrepareDomainHostdevs(virHostdevManagerPtr mgr,
> +                          const char *driver,
> +                          virDomainDefPtr def,
> +                          unsigned int flags)
>

Parameter whitespace alignment.

> +{
> +    if (!def->nhostdevs)
> +        return 0;
> +
> +    if (flags & VIR_SP_PCI_HOSTDEV) {
> +        if (virHostdevPreparePciHostdevs(mgr, driver,
> +                                         def->name, def->uuid,
> +                                         def->hostdevs,
> +                                         def->nhostdevs,
> +                                         flags) < 0)
> +            return -1;
> +    }
> +
> +    if (flags & VIR_SP_USB_HOSTDEV) {
> +        bool coldBoot = (flags & VIR_COLD_BOOT)?true:false;
> +        if (virHostdevPrepareUsbHostdevs(mgr, driver, def->name,
> +                                         def->hostdevs, def->nhostdevs,
> +                                         coldBoot) < 0)
> +            return -1;
> +    }
> +
> +    if (flags & VIR_SP_SCSI_HOSTDEV) {
> +        if (virHostdevPrepareScsiHostdevs(mgr, driver, def->name,
> +                                          def->hostdevs, def->nhostdevs) < 0)
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +/*
> + * Pre-condition: mgr->inactivePciHostdevs & mgr->activePciHostdevs
> + * are locked
> + */
> +static void
> +virHostdevReAttachPciDevice(virHostdevManagerPtr mgr, virPCIDevicePtr dev, const char *driver)
>

This line is > 80 columns.

> +{
> +    /* If the device is not managed and was attached to guest
> +     * successfully, it must have been inactive.
> +     */
> +    if (!virPCIDeviceGetManaged(dev)) {
> +        if (virPCIDeviceListAdd(mgr->inactivePciHostdevs, dev) < 0)
> +            virPCIDeviceFree(dev);
> +        return;
> +    }
> +
> +    /* Wait for device cleanup if it is qemu/kvm */
> +    if (STREQ(driver, QEMU_DRIVER_NAME) &&
> +        STREQ(virPCIDeviceGetStubDriver(dev), "pci-stub")) {
> +        int retries = 100;
> +        while (virPCIDeviceWaitForCleanup(dev, "kvm_assigned_device")
> +               && retries) {
> +            usleep(100*1000);
> +            retries--;
> +        }
> +    }
> +
> +    if (virPCIDeviceReattach(dev, mgr->activePciHostdevs,
> +                             mgr->inactivePciHostdevs) < 0) {
> +        virErrorPtr err = virGetLastError();
> +        VIR_ERROR(_("Failed to re-attach PCI device: %s"),
> +                  err ? err->message : _("unknown error"));
> +        virResetError(err);
> +    }
> +    virPCIDeviceFree(dev);
> +}
> +
> +/*
> + * Pre-condition: mgr->activePciHostdevs is locked
> + */
> +static virPCIDeviceListPtr
> +virHostdevGetActivePciHostDeviceList(virHostdevManagerPtr mgr,
> +                                     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;
> +        virPCIDevicePtr activeDev;
> +
> +        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 ((activeDev = virPCIDeviceListFind(mgr->activePciHostdevs, dev))) {
> +            if (virPCIDeviceListAdd(list, activeDev) < 0) {
> +                virPCIDeviceFree(dev);
> +                virObjectUnref(list);
> +                return NULL;
> +            }
> +        }
> +
> +        virPCIDeviceFree(dev);
> +    }
> +
> +    return list;
> +}
> +
> +void
> +virHostdevReAttachPciHostdevs(virHostdevManagerPtr mgr,
> +                              const char *drv_name,
> +                              const char *dom_name,
> +                              virDomainHostdevDefPtr *hostdevs,
> +                              int nhostdevs)
> +{
> +    virPCIDeviceListPtr pcidevs;
> +    size_t i;
> +
> +    virObjectLock(mgr->activePciHostdevs);
> +    virObjectLock(mgr->inactivePciHostdevs);
> +
> +    if (!(pcidevs = virHostdevGetActivePciHostDeviceList(mgr,
> +                                                         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;
> +        char *usedby_drvname = NULL;
> +        char *usedby_domname = NULL;
> +
> +        /* Never delete the dev from list driver->activePciHostdevs
> +         * if it's used by other domain.
> +         */
> +        activeDev = virPCIDeviceListFind(mgr->activePciHostdevs, dev);
> +        if (activeDev) {
> +            if (virPCIDeviceGetUsedBy(activeDev, &usedby_drvname, &usedby_domname) < 0) {
> +                VIR_WARN("Unable to get driver and domain name "
> +                         "using PCI device %s",
> +                         virPCIDeviceGetName(dev));
> +                VIR_FREE(usedby_drvname);
> +                VIR_FREE(usedby_domname);
> +                continue;
> +            }
> +
> +            if (STRNEQ_NULLABLE(drv_name, usedby_drvname) ||
> +                STRNEQ_NULLABLE(dom_name, usedby_domname)) {
> +                virPCIDeviceListSteal(pcidevs, dev);
> +                VIR_FREE(usedby_drvname);
> +                VIR_FREE(usedby_domname);
> +                continue;
> +            }
> +        }
> +
> +        /* virObjectUnref() will take care of freeing the dev. */
> +        virPCIDeviceListSteal(mgr->activePciHostdevs, dev);
> +
> +        VIR_FREE(usedby_drvname);
> +        VIR_FREE(usedby_domname);
> +    }
> +
> +    /*
> +     * 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) {
> +             virHostdevNetConfigRestore(hostdev, mgr->stateDir);
> +         }
> +    }
> +
> +    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
> +        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
> +        if (virPCIDeviceReset(dev, mgr->activePciHostdevs,
> +                              mgr->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);
> +        virHostdevReAttachPciDevice(mgr, dev, drv_name);
> +    }
> +
> +    virObjectUnref(pcidevs);
> +cleanup:
> +    virObjectUnlock(mgr->activePciHostdevs);
> +    virObjectUnlock(mgr->inactivePciHostdevs);
> +}
> +
> +void
> +virHostdevReAttachUsbHostdevs(virHostdevManagerPtr mgr,
> +                              const char *drv_name,
> +                              const char *dom_name,
> +                              virDomainHostdevDefPtr *hostdevs,
> +                              int nhostdevs)
> +{
> +    size_t i;
> +
> +    virObjectLock(mgr->activeUsbHostdevs);
> +    for (i = 0; i < nhostdevs; i++) {
> +        virDomainHostdevDefPtr hostdev = hostdevs[i];
> +        virUSBDevicePtr usb, tmp;
> +        char *usedby_drvname = NULL;
> +        char *usedby_domname = 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 driver %s domain %s",
> +                     hostdev->source.subsys.u.usb.bus,
> +                     hostdev->source.subsys.u.usb.device,
> +                     drv_name, dom_name);
> +            continue;
> +        }
> +
> +        /* Delete only those USB devices which belongs
> +         * to domain. Therefore we want to steal only
> +         * those devices from the list which were taken
> +         * by domain */
> +
> +        tmp = virUSBDeviceListFind(mgr->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;
> +        }
> +
> +        if (virUSBDeviceGetUsedBy(tmp, &usedby_drvname, &usedby_domname) < 0) {
> +            VIR_WARN("Unable to get driver and domain name "
> +                     "using USB device %03d.%03d",
> +                     hostdev->source.subsys.u.usb.bus,
> +                     hostdev->source.subsys.u.usb.device);
> +
> +            VIR_FREE(usedby_drvname);
> +            VIR_FREE(usedby_domname);
> +            continue;
> +        }
> +
> +        if (STREQ_NULLABLE(drv_name, usedby_drvname) &&
> +            STREQ_NULLABLE(dom_name, usedby_domname)) {
> +            VIR_DEBUG("Removing %03d.%03d dom=%s:%s",
> +                      hostdev->source.subsys.u.usb.bus,
> +                      hostdev->source.subsys.u.usb.device,
> +                      drv_name, dom_name);
> +            virUSBDeviceListDel(mgr->activeUsbHostdevs, tmp);
> +        }
> +
> +        VIR_FREE(usedby_drvname);
> +        VIR_FREE(usedby_domname);
> +
> +    }
> +
> +    virObjectUnlock(mgr->activeUsbHostdevs);
> +}
> +
> +void
> +virHostdevReAttachScsiHostdevs(virHostdevManagerPtr mgr,
> +                               const char *drv_name,
> +                               const char *dom_name,
> +                               virDomainHostdevDefPtr *hostdevs,
> +                               int nhostdevs)
> +{
> +    size_t i;
> +
> +    virObjectLock(mgr->activeScsiHostdevs);
> +    for (i = 0; i < nhostdevs; i++) {
> +        virDomainHostdevDefPtr hostdev = hostdevs[i];
> +        virSCSIDevicePtr scsi, tmp;
> +        char *usedby_drvname = NULL;
> +        char *usedby_domname = NULL;
> +
> +        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 driver %s 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,
> +                     drv_name, dom_name);
> +            continue;
> +        }
> +
> +        tmp = virSCSIDeviceListFind(mgr->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;
> +        }
> +
> +        if (virSCSIDeviceGetUsedBy(tmp, &usedby_drvname, &usedby_domname) < 0) {
> +            VIR_WARN("Unable to get driver and domain name "
> +                     "using SCSI device %s:%d:%d:%d ",
> +                     hostdev->source.subsys.u.scsi.adapter,
> +                     hostdev->source.subsys.u.scsi.bus,
> +                     hostdev->source.subsys.u.scsi.target,
> +                     hostdev->source.subsys.u.scsi.unit);
> +            VIR_FREE(usedby_drvname);
> +            VIR_FREE(usedby_domname);
> +            continue;
> +        }
> +
> +        if (STREQ_NULLABLE(usedby_drvname, drv_name) &&
> +            STREQ_NULLABLE(usedby_domname, dom_name)) {
> +            VIR_DEBUG("Removing %s:%d:%d:%d driver:%s 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,
> +                      drv_name, dom_name);
> +            virSCSIDeviceListDel(mgr->activeScsiHostdevs, tmp);
> +        }
> +
> +        VIR_FREE(usedby_drvname);
> +        VIR_FREE(usedby_domname);
> +    }
> +
> +    virObjectUnlock(mgr->activeScsiHostdevs);
> +}
> +
> +void
> +virHostdevReAttachDomainHostdevs(virHostdevManagerPtr mgr,
> +                           const char *driver,
> +                           virDomainDefPtr def,
> +                           unsigned int flags)
>

Parameter whitespace alignment.

> +{
> +    if (!def->nhostdevs)
> +        return;
> +
> +    if (flags & VIR_SP_PCI_HOSTDEV) {
> +        virHostdevReAttachPciHostdevs(mgr, driver, def->name, def->hostdevs, def->nhostdevs);
> +    }
> +
> +    if (flags & VIR_SP_USB_HOSTDEV) {
> +        virHostdevReAttachUsbHostdevs(mgr, driver, def->name, def->hostdevs, def->nhostdevs);
> +    }
> +
> +    if (flags & VIR_SP_SCSI_HOSTDEV) {
> +        virHostdevReAttachScsiHostdevs(mgr, driver, def->name, def->hostdevs, def->nhostdevs);
> +    }
> +}
> +
> +/* following functions are used by NodeDevDetach/Reattach/Reset */
> +int
> +virHostdevPciNodeDeviceDetach(virHostdevManagerPtr mgr,
> +                              virPCIDevicePtr pci)
> +{
> +    int ret;
>

Needs a line after local variable declaration.

> +    virObjectLock(mgr->activePciHostdevs);
> +    virObjectLock(mgr->inactivePciHostdevs);
> +    if (virPCIDeviceDetach(pci, mgr->activePciHostdevs,
> +                           mgr->inactivePciHostdevs) < 0)
> +        ret = -1;
> +    else
> +        ret = 0;
> +
> +    virObjectUnlock(mgr->inactivePciHostdevs);
> +    virObjectUnlock(mgr->activePciHostdevs);
> +    return ret;
> +}
> +
> +int
> +virHostdevPciNodeDeviceReAttach(virHostdevManagerPtr mgr,
> +                                virPCIDevicePtr pci)
> +{
> +    int ret = -1;
> +    virPCIDevicePtr other;
> +
> +    virObjectLock(mgr->activePciHostdevs);
> +    virObjectLock(mgr->inactivePciHostdevs);
> +    other = virPCIDeviceListFind(mgr->activePciHostdevs, pci);
> +    if (other) {
> +        char *other_drvname = NULL;
> +        char *other_domname = NULL;
> +        virPCIDeviceGetUsedBy(other, &other_drvname, &other_domname);
> +
> +        if (other_drvname && other_domname)
> +            virReportError(VIR_ERR_OPERATION_INVALID,
> +                           _("PCI device %s is still in use by driver %s, domain %s"),
> +                           virPCIDeviceGetName(pci), other_drvname, other_domname);
> +        else
> +            virReportError(VIR_ERR_OPERATION_INVALID,
> +                           _("PCI device %s is still in use"),
> +                           virPCIDeviceGetName(pci));
> +        goto out;
> +    }
> +
> +    virPCIDeviceReattachInit(pci);
> +
> +    if (virPCIDeviceReattach(pci, mgr->activePciHostdevs,
> +                             mgr->inactivePciHostdevs) < 0)
> +        goto out;
> +
> +    ret = 0;
> +out:
> +    virObjectUnlock(mgr->inactivePciHostdevs);
> +    virObjectUnlock(mgr->activePciHostdevs);
> +    return ret;
> +}
> +
> +int
> +virHostdevPciNodeDeviceReset(virHostdevManagerPtr mgr,
> +                             virPCIDevicePtr pci)
> +{
> +    int ret;
>

Needs line after local variable declaration.

> +    virObjectLock(mgr->activePciHostdevs);
> +    virObjectLock(mgr->inactivePciHostdevs);
> +    if (virPCIDeviceReset(pci, mgr->activePciHostdevs,
> +                          mgr->inactivePciHostdevs) < 0)
> +        ret = -1;
> +    else
> +        ret = 0;
> +
> +    virObjectUnlock(mgr->inactivePciHostdevs);
> +    virObjectUnlock(mgr->activePciHostdevs);
> +    return ret;
> +}
> +
> +/* this function is used to free memory after using following
> + * get_active/inactive_list functions
> + */
> +void
> +virHostdevNameListFree(virHostdevNameListPtr list)
> +{
> +    size_t i;
> +
> +    if (list && list->names) {
> +        for (i = 0; i < list->nnames; i++) {
> +            VIR_FREE(list->names[i]);
> +        }
> +        VIR_FREE(list->names);
> +    }
> +    VIR_FREE(list);
> +}
> +
> +virHostdevNameListPtr
> +virHostdevGetActivePciHostdevs(virHostdevManagerPtr mgr)
> +{
> +    size_t i;
> +    int count;
> +    virHostdevNameListPtr list = NULL;
> +    virObjectLock(mgr->activePciHostdevs);
> +
> +    count = virPCIDeviceListCount(mgr->activePciHostdevs);
> +    if (count > 0) {
> +        if (VIR_ALLOC_N(list, 1) < 0) {
> +            virReportOOMError();
>

No need to explicitly report OOM error now.

> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(list->names,count) < 0) {
> +            virReportOOMError();
>

Same here.

> +            goto cleanup;
> +        }
> +        list->nnames = 0;
> +
> +        for (i = 0; i < count; i++) {
> +            virPCIDevicePtr dev = virPCIDeviceListGet(mgr->activePciHostdevs, i);
> +            if (VIR_STRDUP(list->names[list->nnames++], virPCIDeviceGetName(dev)) < 0)
> +                goto cleanup;
> +        }
> +    }
> +
> +    goto end;
> +
> +cleanup:
> +    virHostdevNameListFree(list);
> +
> +end:
> +    virObjectUnlock(mgr->activePciHostdevs);
> +    return list;
> +}
> +
> +virHostdevNameListPtr
> +virHostdevGetActiveUsbHostdevs(virHostdevManagerPtr mgr)
> +{
> +    size_t i;
> +    int count;
> +    virHostdevNameListPtr list = NULL;
> +    virObjectLock(mgr->activeUsbHostdevs);
> +
> +    count = virUSBDeviceListCount(mgr->activeUsbHostdevs);
> +    if (count > 0) {
> +        if (VIR_ALLOC_N(list, 1) < 0) {
> +            virReportOOMError();
>

Same, no need for OOM error reporting.

> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(list->names,count) < 0) {
> +            virReportOOMError();
>

And again.

> +            goto cleanup;
> +        }
> +        list->nnames = 0;
> +
> +        for (i = 0; i < count; i++) {
> +            virUSBDevicePtr usb = virUSBDeviceListGet(mgr->activeUsbHostdevs, i);
> +            if (VIR_STRDUP(list->names[list->nnames++], virUSBDeviceGetName(usb)) < 0)
> +                goto cleanup;
> +        }
> +    }
> +
> +    goto end;
> +
> +cleanup:
> +    virHostdevNameListFree(list);
> +end:
> +    virObjectUnlock(mgr->activeUsbHostdevs);
> +    return list;
> +}
> +
> +virHostdevNameListPtr
> +virHostdevGetActiveScsiHostdevs(virHostdevManagerPtr mgr)
> +{
> +    size_t i;
> +    int count;
> +    virHostdevNameListPtr list = NULL;
> +    virObjectLock(mgr->activeScsiHostdevs);
> +
> +    count = virSCSIDeviceListCount(mgr->activeScsiHostdevs);
> +    if (count > 0) {
> +        if (VIR_ALLOC_N(list, 1) < 0) {
> +            virReportOOMError();
>

And again.

> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(list->names,count) < 0) {
> +            virReportOOMError();
>

Here too.

> +            goto cleanup;
> +        }
> +        list->nnames = 0;
> +
> +        for (i = 0; i < count; i++) {
> +            virSCSIDevicePtr dev = virSCSIDeviceListGet(mgr->activeScsiHostdevs, i);
> +            if (VIR_STRDUP(list->names[list->nnames++], virSCSIDeviceGetName(dev)) < 0)
> +                goto cleanup;
> +        }
> +    }
> +
> +    goto end;
> +
> +cleanup:
> +    virHostdevNameListFree(list);
> +end:
> +    virObjectUnlock(mgr->activeScsiHostdevs);
> +    return list;
> +}
> +
> +virHostdevNameListPtr
> +virHostdevGetDomainActivePciHostdevs(virHostdevManagerPtr mgr,
> +                                     const char *drv_name,
> +                                     const char *dom_name)
> +{
> +    size_t i, count;
> +    virHostdevNameListPtr list = NULL;
> +    virObjectLock(mgr->activePciHostdevs);
> +
> +    count = virPCIDeviceListCount(mgr->activePciHostdevs);
> +    if (count > 0) {
> +        if (VIR_ALLOC_N(list, 1) < 0) {
> +            virReportOOMError();
>

Same.

> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(list->names,count) < 0) {
> +            virReportOOMError();
>

Same.

> +            goto cleanup;
> +        }
> +        list->nnames = 0;
> +
> +        for (i = 0; i < count; i++) {
> +            virPCIDevicePtr dev = virPCIDeviceListGet(mgr->activePciHostdevs, i);
> +            char *usedby_drvname = NULL;
> +            char *usedby_domname = NULL;
> +            int ret;
> +
> +            if (virPCIDeviceGetUsedBy(dev, &usedby_drvname, &usedby_domname) < 0) {
> +                VIR_FREE(usedby_drvname);
> +                VIR_FREE(usedby_domname);
> +
> +                goto cleanup;
> +            }
> +
> +            if (STREQ(drv_name, usedby_drvname) &&
> +                STREQ(dom_name, usedby_domname)) {
> +                ret = VIR_STRDUP(list->names[list->nnames++], virPCIDeviceGetName(dev));
> +                if (ret < 0) {
> +                    VIR_FREE(usedby_drvname);
> +                    VIR_FREE(usedby_domname);
> +                    goto cleanup;
> +                }
> +            }
> +
> +            VIR_FREE(usedby_drvname);
> +            VIR_FREE(usedby_domname);
> +        }
> +
> +        VIR_SHRINK_N(list->names, count, count - list->nnames);
> +    }
> +
> +    goto end;
> +
> +cleanup:
> +    virHostdevNameListFree(list);
> +end:
> +    virObjectUnlock(mgr->activePciHostdevs);
> +    return list;
> +}
> +
> +virHostdevNameListPtr
> +virHostdevGetDomainActiveUsbHostdevs(virHostdevManagerPtr mgr,
> +                                     const char *drv_name,
> +                                     const char *dom_name)
> +{
> +    size_t i, count;
> +    virHostdevNameListPtr list = NULL;
> +    virObjectLock(mgr->activeUsbHostdevs);
> +
> +    count = virUSBDeviceListCount(mgr->activeUsbHostdevs);
> +    if (count > 0) {
> +        if (VIR_ALLOC_N(list, 1) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(list->names,count) < 0) {
> +            virReportOOMError();
>

A few more cases of unneeded OOM error reporting.

> +            goto cleanup;
> +        }
> +        list->nnames = 0;
> +
> +        for (i = 0; i < count; i++) {
> +            virUSBDevicePtr usb = virUSBDeviceListGet(mgr->activeUsbHostdevs, i);
> +            char *usedby_drvname = NULL;
> +            char *usedby_domname = NULL;
> +            int ret;
> +
> +            if (virUSBDeviceGetUsedBy(usb, &usedby_drvname, &usedby_domname) < 0) {
> +                    VIR_FREE(usedby_drvname);
> +                    VIR_FREE(usedby_domname);
> +                    goto cleanup;
> +            }
> +
> +            if (STREQ(drv_name, usedby_drvname) &&
> +                STREQ(dom_name, usedby_domname)) {
> +                ret = VIR_STRDUP(list->names[list->nnames++], virUSBDeviceGetName(usb));
> +                if (ret < 0) {
> +                    VIR_FREE(usedby_drvname);
> +                    VIR_FREE(usedby_domname);
> +                    goto cleanup;
> +                }
> +            }
> +
> +            VIR_FREE(usedby_drvname);
> +            VIR_FREE(usedby_domname);
> +        }
> +
> +        VIR_SHRINK_N(list->names, count, count - list->nnames);
> +    }
> +
> +    goto end;
> +
> +cleanup:
> +    virHostdevNameListFree(list);
> +end:
> +    virObjectUnlock(mgr->activeUsbHostdevs);
> +    return list;
> +}
> +
> +virHostdevNameListPtr
> +virHostdevGetDomainActiveScsiHostdevs(virHostdevManagerPtr mgr,
> +                                      const char *drv_name,
> +                                      const char *dom_name)
> +{
> +    size_t i, count;
> +    virHostdevNameListPtr list = NULL;
> +    virObjectLock(mgr->activeScsiHostdevs);
> +
> +    count = virSCSIDeviceListCount(mgr->activeScsiHostdevs);
> +    if (count > 0) {
> +        if (VIR_ALLOC_N(list, 1) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(list->names,count) < 0) {
> +            virReportOOMError();
>

You're probably getting tired of this comment by now :).

> +            goto cleanup;
> +        }
> +        list->nnames = 0;
> +
> +        for (i = 0; i < count; i++) {
> +            virSCSIDevicePtr dev = virSCSIDeviceListGet(mgr->activeScsiHostdevs, i);
> +            char *usedby_drvname = NULL;
> +            char *usedby_domname = NULL;
> +            int ret;
> +
> +            if (virSCSIDeviceGetUsedBy(dev, &usedby_drvname, &usedby_domname) < 0) {
> +                    VIR_FREE(usedby_drvname);
> +                    VIR_FREE(usedby_domname);
> +                    goto cleanup;
> +            }
> +
> +            if (STREQ(drv_name, usedby_drvname) &&
> +                STREQ(dom_name, usedby_domname)) {
> +                ret = VIR_STRDUP(list->names[list->nnames++], virSCSIDeviceGetName(dev));
> +                if (ret < 0){
> +                    VIR_FREE(usedby_drvname);
> +                    VIR_FREE(usedby_domname);
> +                    goto cleanup;
> +                }
> +            }
> +
> +            VIR_FREE(usedby_drvname);
> +            VIR_FREE(usedby_domname);
> +        }
> +
> +        VIR_SHRINK_N(list->names, count, count - list->nnames);
> +    }
> +
> +    goto end;
> +
> +cleanup:
> +    virHostdevNameListFree(list);
> +end:
> +    virObjectUnlock(mgr->activeScsiHostdevs);
> +    return list;
> +}
> diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
> new file mode 100644
> index 0000000..09377db
> --- /dev/null
> +++ b/src/util/virhostdev.h
> @@ -0,0 +1,123 @@
> +/* virhostdev.h: hostdev management
> + *
> + * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
> + * 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: Chunyan Liu <cyliu@suse.com>
> + * Author: Daniel P. Berrange <berrange@redhat.com>
> + */
> +
> +#ifndef __VIR_HOSTDEV_MANAGER_H__
> +# define __VIR_HOSTDEV_MANAGER_H__
> +
> +# include "internal.h"
> +# include "configmake.h"
> +
> +# include "domain_conf.h"
> +# include "virpci.h"
> +
> +# define HOSTDEV_STATE_DIR LOCALSTATEDIR "/run/libvirt/hostdevmanager"
>

This could be moved to virhostdev.c right?

Yeah, could be.
 
> +
> +typedef enum {
> +    VIR_SP_PCI_HOSTDEV       = (1 << 0), /* support pci passthrough */
> +    VIR_SP_USB_HOSTDEV       = (1 << 1), /* support usb passthrough */
> +    VIR_SP_SCSI_HOSTDEV      = (1 << 2), /* support scsi passthrough */
> +
> +    VIR_COLD_BOOT            = (1 << 8), /* cold boot */
> +    VIR_STRICT_ACS_CHECK     = (1 << 9), /* strict acs check */
> +} virHostdevManagerFlag;
> +
> +typedef struct _virHostdevManager virHostdevManager;
> +typedef virHostdevManager *virHostdevManagerPtr;
> +
> +struct virHostdevNameList {
> +    char **names;
> +    size_t nnames;
> +};
> +typedef struct virHostdevNameList *virHostdevNameListPtr;
> +
> +virHostdevManagerPtr virHostdevManagerGetDefault(void);
> +
> +/* functions used to prepare/unprepare hostdevs for domain */
> +int virHostdevPrepareDomainHostdevs(virHostdevManagerPtr mgr,
> +                              const char *driver,
> +                              virDomainDefPtr def,
> +                              unsigned int flags);
> +void virHostdevReAttachDomainHostdevs(virHostdevManagerPtr mgr,
> +                                const char *driver,
> +                                virDomainDefPtr def,
> +                                unsigned int flags);
>

Parameter whitespace alignment in these two function declarations.

> +int virHostdevPreparePciHostdevs(virHostdevManagerPtr mgr,
> +                                 const char *drv_name,
> +                                 const char *dom_name,
> +                                 const unsigned char *uuid,
> +                                 virDomainHostdevDefPtr *hostdevs,
> +                                 int nhostdevs,
> +                                 unsigned int flags);
> +int virHostdevPrepareUsbHostdevs(virHostdevManagerPtr mgr,
> +                                 const char *drv_name,
> +                                 const char *dom_name,
> +                                 virDomainHostdevDefPtr *hostdevs,
> +                                 int nhostdevs,
> +                                 bool coldBoot);
> +int virHostdevPrepareScsiHostdevs(virHostdevManagerPtr mgr,
> +                                  const char *drv_name,
> +                                  const char *dom_name,
> +                                  virDomainHostdevDefPtr *hostdevs,
> +                                  int nhostdevs);
> +void virHostdevReAttachPciHostdevs(virHostdevManagerPtr mgr,
> +                                   const char *drv_name,
> +                                   const char *dom_name,
> +                                   virDomainHostdevDefPtr *hostdevs,
> +                                   int nhostdevs);
> +void virHostdevReAttachUsbHostdevs(virHostdevManagerPtr mgr,
> +                                   const char *drv_name,
> +                                   const char *dom_name,
> +                                   virDomainHostdevDefPtr *hostdevs,
> +                                   int nhostdevs);
> +void virHostdevReAttachScsiHostdevs(virHostdevManagerPtr mgr,
> +                                    const char *drv_name,
> +                                    const char *dom_name,
> +                                    virDomainHostdevDefPtr *hostdevs,
> +                                    int nhostdevs);
> +
> +/* functions used by NodeDevDetach/Reattach/Reset */
> +int virHostdevPciNodeDeviceDetach(virHostdevManagerPtr mgr,
> +                                  virPCIDevicePtr pci);
> +int virHostdevPciNodeDeviceReAttach(virHostdevManagerPtr mgr,
> +                                    virPCIDevicePtr pci);
> +int virHostdevPciNodeDeviceReset(virHostdevManagerPtr mgr,
> +                                 virPCIDevicePtr pci);
> +
> +/* functions to get active/inactive lists */
> +virHostdevNameListPtr virHostdevGetActivePciHostdevs(virHostdevManagerPtr mgr);
> +virHostdevNameListPtr virHostdevGetActiveUsbHostdevs(virHostdevManagerPtr mgr);
> +virHostdevNameListPtr virHostdevGetActiveScsiHostdevs(virHostdevManagerPtr mgr);
> +virHostdevNameListPtr virHostdevGetDomainActivePciHostdevs(virHostdevManagerPtr mgr,
> +                                                           const char *drv_name,
> +                                                           const char *dom_name);
> +virHostdevNameListPtr virHostdevGetDomainActiveUsbHostdevs(virHostdevManagerPtr mgr,
> +                                                           const char *drv_name,
> +                                                           const char *dom_name);
> +virHostdevNameListPtr virHostdevGetDomainActiveScsiHostdevs(virHostdevManagerPtr mgr,
> +                                                            const char *drv_name,
> +                                                            const char *dom_name);
> +/* function to free memory after get active/inactive lists */
> +void virHostdevNameListFree(virHostdevNameListPtr list);
> +
> +#endif /* __VIR_HOSTDEV_MANAGER_H__ */
> diff --git a/src/util/virpci.c b/src/util/virpci.c
> index be50b4f..dc38efe 100644
> --- a/src/util/virpci.c
> +++ b/src/util/virpci.c
> @@ -62,7 +62,10 @@ struct _virPCIDevice {
>      char          name[PCI_ADDR_LEN]; /* domain:bus:slot.function */
>      char          id[PCI_ID_LEN];     /* product vendor */
>      char          *path;
> -    const char    *used_by;           /* The domain which uses the device */
> +
> +    /* The driver:domain which uses the device */
> +    const char    *used_by_drvname;
> +    const char    *used_by_domname;
>
>      unsigned int  pcie_cap_pos;
>      unsigned int  pci_pm_cap_pos;
> @@ -1642,15 +1645,21 @@ virPCIDeviceSetReprobe(virPCIDevicePtr dev, bool reprobe)
>  }
>
>  void
> -virPCIDeviceSetUsedBy(virPCIDevicePtr dev, const char *name)
> +virPCIDeviceSetUsedBy(virPCIDevicePtr dev, const char *drv_name, const char *dom_name)
>  {
> -    dev->used_by = name;
> +    dev->used_by_drvname = drv_name;
> +    dev->used_by_domname = dom_name;
>  }
>
> -const char *
> -virPCIDeviceGetUsedBy(virPCIDevicePtr dev)
> +int
> +virPCIDeviceGetUsedBy(virPCIDevicePtr dev, char **drv_name, char **dom_name)
>  {
> -    return dev->used_by;
> +    if (VIR_STRDUP(*drv_name, dev->used_by_drvname) < 0)
> +        return -1;
> +    if (VIR_STRDUP(*dom_name, dev->used_by_domname) < 0)
> +        return -1;
> +
> +    return 0;
>  }
>
>  void virPCIDeviceReattachInit(virPCIDevicePtr pci)
> diff --git a/src/util/virpci.h b/src/util/virpci.h
> index 0aa6fee..dc1a80b 100644
> --- a/src/util/virpci.h
> +++ b/src/util/virpci.h
> @@ -66,8 +66,11 @@ int virPCIDeviceSetStubDriver(virPCIDevicePtr dev,
>                                const char *driver);
>  const char *virPCIDeviceGetStubDriver(virPCIDevicePtr dev);
>  void virPCIDeviceSetUsedBy(virPCIDevice *dev,
> -                           const char *used_by);
> -const char *virPCIDeviceGetUsedBy(virPCIDevice *dev);
> +                           const char *drv_name,
> +                           const char *dom_name);
> +int virPCIDeviceGetUsedBy(virPCIDevice *dev,
> +                            char **drv_name,
> +                            char **dom_name);
>

Parameters not aligned properly in these two function declarations.

>  unsigned int virPCIDeviceGetUnbindFromStub(virPCIDevicePtr dev);
>  void  virPCIDeviceSetUnbindFromStub(virPCIDevice *dev,
>                                      bool unbind);
> diff --git a/src/util/virscsi.c b/src/util/virscsi.c
> index 32e438b..dc1eebb 100644
> --- a/src/util/virscsi.c
> +++ b/src/util/virscsi.c
> @@ -55,7 +55,10 @@ struct _virSCSIDevice {
>      char *name; /* adapter:bus:target:unit */
>      char *id;   /* model:vendor */
>      char *sg_path; /* e.g. /dev/sg2 */
> -    const char *used_by; /* name of the domain using this dev */
> +
> +    /* driver:domain using this dev */
> +    const char *used_by_drvname;
> +    const char *used_by_domname;
>
>      bool readonly;
>  };
> @@ -267,15 +270,22 @@ virSCSIDeviceFree(virSCSIDevicePtr dev)
>
>  void
>  virSCSIDeviceSetUsedBy(virSCSIDevicePtr dev,
> -                       const char *name)
> +                       const char *drvname,
> +                       const char *domname)
>  {
> -    dev->used_by = name;
> +    dev->used_by_drvname = drvname;
> +    dev->used_by_domname = domname;
>  }
>
> -const char *
> -virSCSIDeviceGetUsedBy(virSCSIDevicePtr dev)
> +int
> +virSCSIDeviceGetUsedBy(virSCSIDevicePtr dev, char **drvname, char **domname)
>  {
> -    return dev->used_by;
> +    if (VIR_STRDUP(*drvname, dev->used_by_drvname) < 0)
> +        return -1;
> +    if (VIR_STRDUP(*domname, dev->used_by_domname) < 0)
> +        return -1;
> +
> +    return 0;
>  }
>
>  const char *
> diff --git a/src/util/virscsi.h b/src/util/virscsi.h
> index cce5df4..89b3e5d 100644
> --- a/src/util/virscsi.h
> +++ b/src/util/virscsi.h
> @@ -49,8 +49,12 @@ virSCSIDevicePtr virSCSIDeviceNew(const char *adapter,
>                                    bool readonly);
>
>  void virSCSIDeviceFree(virSCSIDevicePtr dev);
> -void virSCSIDeviceSetUsedBy(virSCSIDevicePtr dev, const char *name);
> -const char *virSCSIDeviceGetUsedBy(virSCSIDevicePtr dev);
> +void virSCSIDeviceSetUsedBy(virSCSIDevicePtr dev,
> +                            const char *drvname,
> +                            const char *domname);
> +int virSCSIDeviceGetUsedBy(virSCSIDevicePtr dev,
> +                           char **drvname,
> +                           char **domname);
>  const char *virSCSIDeviceGetName(virSCSIDevicePtr dev);
>  unsigned int virSCSIDeviceGetAdapter(virSCSIDevicePtr dev);
>  unsigned int virSCSIDeviceGetBus(virSCSIDevicePtr dev);
> diff --git a/src/util/virusb.c b/src/util/virusb.c
> index e901618..54d836d 100644
> --- a/src/util/virusb.c
> +++ b/src/util/virusb.c
> @@ -55,7 +55,10 @@ struct _virUSBDevice {
>      char          name[USB_ADDR_LEN]; /* domain:bus:slot.function */
>      char          id[USB_ID_LEN];     /* product vendor */
>      char          *path;
> -    const char    *used_by;           /* name of the domain using this dev */
> +
> +    /* driver:domain using this dev */
> +    const char    *used_by_drvname;
> +    const char    *used_by_domname;
>  };
>
>  struct _virUSBDeviceList {
> @@ -378,16 +381,24 @@ virUSBDeviceFree(virUSBDevicePtr dev)
>      VIR_FREE(dev);
>  }
>
> -
>  void virUSBDeviceSetUsedBy(virUSBDevicePtr dev,
> -                           const char *name)
> +                           const char *drv_name,
> +                           const char *dom_name)
>  {
> -    dev->used_by = name;
> +    dev->used_by_drvname = drv_name;
> +    dev->used_by_domname = dom_name;
>  }
>
> -const char * virUSBDeviceGetUsedBy(virUSBDevicePtr dev)
> +int virUSBDeviceGetUsedBy(virUSBDevicePtr dev,
> +                           char **drv_name,
> +                           char **dom_name)
>

Parameter alignment.

This patch is looking good, but since I'm not terribly familiar with
this area of libvirt and historically there have been quite a few bugs
related to passthrough, it would be best if one of the devs familiar
with this code (Laine, Osier) could also review it.

Regards,
Jim

Thanks a lot for your review and comment.
Since this patch affect existing qemu/lxc driver too, I also hope some one expert in that could review and point out problem if there is.

Thanks,
Chunyan

>  {
> -    return dev->used_by;
> +    if (VIR_STRDUP(*drv_name, dev->used_by_drvname) < 0)
> +        return -1;
> +    if (VIR_STRDUP(*dom_name, dev->used_by_domname) < 0)
> +        return -1;
> +
> +    return 0;
>  }
>
>  const char *virUSBDeviceGetName(virUSBDevicePtr dev)
> diff --git a/src/util/virusb.h b/src/util/virusb.h
> index aa59d12..5f1df58 100644
> --- a/src/util/virusb.h
> +++ b/src/util/virusb.h
> @@ -60,8 +60,12 @@ int virUSBDeviceFind(unsigned int vendor,
>                       virUSBDevicePtr *usb);
>
>  void virUSBDeviceFree(virUSBDevicePtr dev);
> -void virUSBDeviceSetUsedBy(virUSBDevicePtr dev, const char *name);
> -const char *virUSBDeviceGetUsedBy(virUSBDevicePtr dev);
> +void virUSBDeviceSetUsedBy(virUSBDevicePtr dev,
> +                           const char *drv_name,
> +                           const char *dom_name);
> +int virUSBDeviceGetUsedBy(virUSBDevicePtr dev,
> +                          char **drv_name,
> +                          char **dom_name);
>  const char *virUSBDeviceGetName(virUSBDevicePtr dev);
>
>  unsigned int virUSBDeviceGetBus(virUSBDevicePtr dev);
>