[libvirt] [PATCH v3 09/10] qemu: Implement usb hub device hotunplug

John Ferlan jferlan at redhat.com
Thu Nov 15 16:18:09 UTC 2018



On 11/11/18 10:59 PM, Han Han wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1375423
> 
> Signed-off-by: Han Han <hhan at redhat.com>
> ---
>  src/qemu/qemu_driver.c  |  5 ++-
>  src/qemu/qemu_hotplug.c | 81 ++++++++++++++++++++++++++++++++++++++++-
>  src/qemu/qemu_hotplug.h |  4 ++
>  3 files changed, 88 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 774f6ac8b9..2813a00050 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -7822,11 +7822,14 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
>          ret = qemuDomainDetachVsockDevice(vm, dev->data.vsock, async);
>          break;
>  
> +    case VIR_DOMAIN_DEVICE_HUB:
> +        ret = qemuDomainDetachHubDevice(vm, dev->data.hub, async);
> +        break;
> +
>      case VIR_DOMAIN_DEVICE_FS:
>      case VIR_DOMAIN_DEVICE_SOUND:
>      case VIR_DOMAIN_DEVICE_VIDEO:
>      case VIR_DOMAIN_DEVICE_GRAPHICS:
> -    case VIR_DOMAIN_DEVICE_HUB:
>      case VIR_DOMAIN_DEVICE_SMARTCARD:
>      case VIR_DOMAIN_DEVICE_MEMBALLOON:
>      case VIR_DOMAIN_DEVICE_NVRAM:
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index ca73456260..124703b7b2 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -4965,6 +4965,32 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriverPtr driver,
>  }
>  
>  
> +static int
> +qemuDomainRemoveHubDevice(virDomainObjPtr vm,
> +                          virDomainHubDefPtr dev)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virQEMUDriverPtr driver = priv->driver;
> +    virObjectEventPtr event = NULL;
> +    size_t i;
> +
> +    VIR_DEBUG("Removing hub device %s from domain %p %s",
> +              dev->info.alias, vm, vm->def->name);
> +
> +    event = virDomainEventDeviceRemovedNewFromObj(vm, dev->info.alias);
> +    virObjectEventStateQueue(driver->domainEventState, event);
> +    for (i = 0; i < vm->def->nhubs; i++) {
> +        if (vm->def->hubs[i] == dev)
> +            break;
> +    }
> +    qemuDomainReleaseDeviceAddress(vm, &dev->info, NULL);
> +
> +    virDomainHubDefFree(vm->def->hubs[i]);
> +    VIR_DELETE_ELEMENT(vm->def->hubs, i, vm->def->nhubs);
> +    return 0;
> +}
> +
> +
>  int
>  qemuDomainRemoveDevice(virQEMUDriverPtr driver,
>                         virDomainObjPtr vm,
> @@ -5016,13 +5042,16 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
>          ret = qemuDomainRemoveVsockDevice(vm, dev->data.vsock);
>          break;
>  
> +    case VIR_DOMAIN_DEVICE_HUB:
> +        ret = qemuDomainRemoveHubDevice(vm, dev->data.hub);
> +        break;
> +
>      case VIR_DOMAIN_DEVICE_NONE:
>      case VIR_DOMAIN_DEVICE_LEASE:
>      case VIR_DOMAIN_DEVICE_FS:
>      case VIR_DOMAIN_DEVICE_SOUND:
>      case VIR_DOMAIN_DEVICE_VIDEO:
>      case VIR_DOMAIN_DEVICE_GRAPHICS:
> -    case VIR_DOMAIN_DEVICE_HUB:
>      case VIR_DOMAIN_DEVICE_SMARTCARD:
>      case VIR_DOMAIN_DEVICE_MEMBALLOON:
>      case VIR_DOMAIN_DEVICE_NVRAM:
> @@ -7019,3 +7048,53 @@ qemuDomainDetachVsockDevice(virDomainObjPtr vm,
>          qemuDomainResetDeviceRemoval(vm);
>      return ret;
>  }
> +
> +
> +int
> +qemuDomainDetachHubDevice(virDomainObjPtr vm,
> +                          virDomainHubDefPtr def,
> +                          bool async)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virQEMUDriverPtr driver = priv->driver;
> +    virDomainHubDefPtr detach;
> +    int ret = -1;
> +    int idx;
> +
> +    if ((idx = virDomainHubDefFind(vm->def, def)) < 0) {
> +        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> +                       _("matching hub device not found"));
> +        return -1;
> +    }
> +
> +    detach = vm->def->hubs[idx];
> +    if (qemuDomainHubIsBusy(vm, detach)) {
> +        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> +                       _("device cannot be detached: device is busy"));
> +        goto cleanup;
> +    }

This is where either the virDomainUSBDeviceDefForeach logic would need
to be called in order to determine whether some other device was
attached to this hub or some mechanism to get/search usbaddrs for this
hub and determine if its "targetHub->portmap" was (virBitmapIsAllClear).

More or less the antecedent to virDomainUSBAddressSetAddHub and
potentially virDomainUSBAddressSetAddController.

John

> +
> +    if (!async)
> +        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
> +
> +    qemuDomainObjEnterMonitor(driver, vm);
> +    if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
> +        ignore_value(qemuDomainObjExitMonitor(driver, vm));
> +        goto cleanup;
> +    }
> +
> +    if (qemuDomainObjExitMonitor(driver, vm) < 0)
> +        goto cleanup;
> +
> +    if (async) {
> +        ret = 0;
> +    } else {
> +        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
> +            ret = qemuDomainRemoveHubDevice(vm, detach);
> +    }
> +
> + cleanup:
> +    if (!async)
> +        qemuDomainResetDeviceRemoval(vm);
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
> index 19b8950254..5c860c26ac 100644
> --- a/src/qemu/qemu_hotplug.h
> +++ b/src/qemu/qemu_hotplug.h
> @@ -204,4 +204,8 @@ int qemuDomainDetachInputDevice(virDomainObjPtr vm,
>  int qemuDomainDetachVsockDevice(virDomainObjPtr vm,
>                                  virDomainVsockDefPtr dev,
>                                  bool async);
> +
> +int qemuDomainDetachHubDevice(virDomainObjPtr vm,
> +                              virDomainHubDefPtr def,
> +                              bool async);
>  #endif /* __QEMU_HOTPLUG_H__ */
> 




More information about the libvir-list mailing list