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

Chun Yan Liu cyliu at suse.com
Mon May 23 03:40:00 UTC 2016



>>> On 5/20/2016 at 06:32 PM, in message <573EE7C3.7000703 at oracle.com>, Joao
Martins <joao.m.martins at oracle.com> wrote: 
> 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? 

No harm without LIBXL_HAVE_PVUSB, it can be handled. But if you want
to use it to reboot the domain, the real hotplug into the system will be failed
without LIBXL_HAVE_PVUSB. So, if our purpose is: any PVUSB function should
be forbidden without LIBXL_HAVE_PVUSB, we need to add a check; otherwise,
it's OK. How do you think?

- Chunyan

>  
> >                  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