[libvirt] [PATCH V2 2/4] libxl: support hotplug USB host device

Joao Martins joao.m.martins at oracle.com
Fri May 20 10:32:35 UTC 2016


On 05/19/2016 09:14 AM, Chunyan Liu wrote:
> Support hot attach/detach a USB host device to guest.
> Curretnly libxl only supports xen PV guest, and only
> supports specifying USB host device by 'bus number'
> and 'device number'.
> 
> For example:
>  usb.xml:
>     <hostdev mode='subsystem' type='usb' managed='no'>
>       <source>
>         <address bus='1' device='3'/>
>       </source>
>     </hostdev>
>  #xl attach-device dom usb.xml
>  #xl detach-device dom usb.xml
> 
> Signed-off-by: Chunyan Liu <cyliu at suse.com>
> ---
> Changes:
>   * add LIBXL_HAVE_PVUSB check
>   * fix Jim's comments
> 
>  src/libxl/libxl_driver.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 135 insertions(+), 1 deletion(-)
> 
> diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> index 960673f..a171efe 100644
> --- a/src/libxl/libxl_driver.c
> +++ b/src/libxl/libxl_driver.c
> @@ -3028,6 +3028,56 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr driver,
>      return ret;
>  }
>  
> +#ifdef LIBXL_HAVE_PVUSB
> +static int
> +libxlDomainAttachHostUSBDevice(libxlDriverPrivatePtr driver,
> +                               virDomainObjPtr vm,
> +                               virDomainHostdevDefPtr hostdev)
> +{
> +    libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> +    libxl_device_usbdev usbdev;
> +    virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
> +    int ret = -1;
> +
> +    libxl_device_usbdev_init(&usbdev);
> +
> +    if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
> +        hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
> +        goto cleanup;
> +
> +    if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
> +        goto cleanup;
> +
> +    if (virHostdevPrepareUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
> +                                    vm->def->name, &hostdev, 1, 0) < 0)
> +        goto cleanup;
> +
> +    if (libxlMakeUSB(hostdev, &usbdev) < 0)
> +        goto reattach;
> +
> +    if (libxl_device_usbdev_add(cfg->ctx, vm->def->id, &usbdev, 0) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("libxenlight failed to attach usb device Busnum:%3x, Devnum:%3x"),
> +                       hostdev->source.subsys.u.usb.bus,
> +                       hostdev->source.subsys.u.usb.device);
> +        goto reattach;
> +    }
> +
> +    vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
> +    ret = 0;
> +    goto cleanup;
> +
> + reattach:
> +    virHostdevReAttachUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
> +                                 vm->def->name, &hostdev, 1);
> +
> + cleanup:
> +    virObjectUnref(cfg);
> +    libxl_device_usbdev_dispose(&usbdev);
> +    return ret;
> +}
> +#endif
> +
>  static int
>  libxlDomainAttachHostDevice(libxlDriverPrivatePtr driver,
>                              virDomainObjPtr vm,
> @@ -3046,6 +3096,13 @@ libxlDomainAttachHostDevice(libxlDriverPrivatePtr driver,
>              return -1;
>          break;
>  
> +#ifdef LIBXL_HAVE_PVUSB
> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
> +        if (libxlDomainAttachHostUSBDevice(driver, vm, hostdev) < 0)
> +            return -1;
> +        break;
> +#endif
> +
>      default:
>          virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>                         _("hostdev subsys type '%s' not supported"),
> @@ -3271,7 +3328,9 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
>          case VIR_DOMAIN_DEVICE_HOSTDEV:
>              hostdev = dev->data.hostdev;
>  
> -            if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
> +            if (hostdev->source.subsys.type !=
> +                (VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI ||
> +                 VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB))
Is this conditional correct when LIBXL_HAVE_PVUSB isn't there?

>                  return -1;
>  
>              if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) {
> @@ -3389,6 +3448,76 @@ libxlDomainDetachHostPCIDevice(libxlDriverPrivatePtr driver,
>      return ret;
>  }
>  
> +#ifdef LIBXL_HAVE_PVUSB
> +static int
> +libxlDomainDetachHostUSBDevice(libxlDriverPrivatePtr driver,
> +                               virDomainObjPtr vm,
> +                               virDomainHostdevDefPtr hostdev)
> +{
> +    libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
> +    virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
> +    virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb;
> +    virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
> +    libxl_device_usbdev usbdev;
> +    libxl_device_usbdev *usbdevs = NULL;
> +    int num = 0;
> +    virDomainHostdevDefPtr detach;
> +    int idx;
> +    size_t i;
> +    bool found = false;
> +    int ret = -1;
> +
> +    libxl_device_usbdev_init(&usbdev);
> +
> +    idx = virDomainHostdevFind(vm->def, hostdev, &detach);
> +    if (idx < 0) {
> +        virReportError(VIR_ERR_OPERATION_FAILED,
> +                       _("host USB device Busnum: %3x, Devnum: %3x not found"),
> +                       usbsrc->bus, usbsrc->device);
> +        goto cleanup;
> +    }
> +
> +    usbdevs = libxl_device_usbdev_list(cfg->ctx, vm->def->id, &num);
> +    for (i = 0; i < num; i++) {
> +        if (usbdevs[i].u.hostdev.hostbus == usbsrc->bus &&
> +            usbdevs[i].u.hostdev.hostaddr == usbsrc->device) {
> +            libxl_device_usbdev_copy(cfg->ctx, &usbdev, &usbdevs[i]);
> +            found = true;
> +            break;
> +        }
> +    }
> +    libxl_device_usbdev_list_free(usbdevs, num);
> +
> +    if (!found) {
> +        virReportError(VIR_ERR_OPERATION_FAILED,
> +                       _("host USB device Busnum: %3x, Devnum: %3x not found"),
> +                       usbsrc->bus, usbsrc->device);
> +        goto cleanup;
> +    }
> +
> +    if (libxl_device_usbdev_remove(cfg->ctx, vm->def->id, &usbdev, 0) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("libxenlight failed to detach USB device\
> +                          Busnum: %3x, Devnum: %3x"),
> +                       usbsrc->bus, usbsrc->device);
> +        goto cleanup;
> +    }
> +
> +    virDomainHostdevRemove(vm->def, idx);
> +
> +    virHostdevReAttachUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
> +                                 vm->def->name, &hostdev, 1);
> +
> +    ret = 0;
> +
> + cleanup:
> +    virDomainHostdevDefFree(detach);
> +    virObjectUnref(cfg);
> +    libxl_device_usbdev_dispose(&usbdev);
> +    return ret;
> +}
> +#endif
> +
>  static int
>  libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
>                              virDomainObjPtr vm,
> @@ -3407,6 +3536,11 @@ libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
>          case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
>              return libxlDomainDetachHostPCIDevice(driver, vm, hostdev);
>  
> +#ifdef LIBXL_HAVE_PVUSB
> +        case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
> +            return libxlDomainDetachHostUSBDevice(driver, vm, hostdev);
> +#endif
> +
>          default:
>              virReportError(VIR_ERR_INTERNAL_ERROR,
>                             _("unexpected hostdev type %d"), subsys->type);
> 




More information about the libvir-list mailing list