[libvirt] [PATCH 2/2] libxl: support hotplug USB host device
Chun Yan Liu
cyliu at suse.com
Fri May 13 02:48:19 UTC 2016
>>> On 5/13/2016 at 07:20 AM, in message <57350FA5.3070307 at suse.com>, Jim Fehlig
<jfehlig at suse.com> wrote:
> Chunyan Liu wrote:
> > Support hot attach/detach a USB host device to guest.
> > Curretnly libxl only supports xen PV guest, and only
>
> s/Curretnly/Currently/
>
> > supports specifying USB host device by 'bus number'
> > and 'device number'.
> >
> > Signed-off-by: Chunyan Liu <cyliu at suse.com>
> > ---
> > src/libxl/libxl_driver.c | 130
> ++++++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 129 insertions(+), 1 deletion(-)
> >
> > diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
> > index 18a0891..8900644 100644
> > --- a/src/libxl/libxl_driver.c
> > +++ b/src/libxl/libxl_driver.c
> > @@ -3024,6 +3024,55 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr
> driver,
> > }
> >
> > 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);
>
> Move the init below the check for hostdev->mode and hostdev->source.subsys.type,
> otherwise it is not disposed if the check fails.
Yes, will update.
>
> > +
> > + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
> > + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
> > + return ret;
> > +
> > + 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 error;
> > +
> > + 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 error;
> > + }
> > +
> > + vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
> > + ret = 0;
> > + goto cleanup;
> > +
> > + error:
>
> I think 'reattach' is a better name for this label.
Will update.
>
> > + virHostdevReAttachUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
> > + vm->def->name, &hostdev, 1);
> > +
> > + cleanup:
> > + virObjectUnref(cfg);
> > + libxl_device_usbdev_dispose(&usbdev);
> > + return ret;
> > +}
> > +
> > +
> > +static int
> > libxlDomainAttachHostDevice(libxlDriverPrivatePtr driver,
> > virDomainObjPtr vm,
> > virDomainHostdevDefPtr hostdev)
> > @@ -3041,6 +3090,11 @@ libxlDomainAttachHostDevice(libxlDriverPrivatePtr
> driver,
> > return -1;
> > break;
> >
> > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
> > + if (libxlDomainAttachHostUSBDevice(driver, vm, hostdev) < 0)
> > + return -1;
> > + break;
> > +
> > default:
> > virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > _("hostdev subsys type '%s' not supported"),
> > @@ -3266,7 +3320,8 @@ 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_USB ||
> VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI))
>
> if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB
> ||
> hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
>
> > return -1;
> >
> > if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) {
> > @@ -3385,6 +3440,76 @@ libxlDomainDetachHostPCIDevice(libxlDriverPrivatePtr
> driver,
> > }
> >
> > 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"),
>
> Space after Busnum, but not Devnum.
Will update.
>
> > + 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"),
>
> Same here.
>
> > + 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"),
>
> And here.
>
> > + usbsrc->bus, usbsrc->device);
> > + goto error;
> > + }
> > +
> > + virDomainHostdevRemove(vm->def, idx);
> > +
> > + virHostdevReAttachUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
> > + vm->def->name, &hostdev, 1);
> > +
> > + ret = 0;
> > +
> > + error:
> > + virDomainHostdevDefFree(detach);
>
> The error label will be hit on success of the function. Should
> virDomainHostdevDefFree() be called in 'cleanup' and 'error' dropped?
Yes, that's better. Will update.
Thanks,
Chunyan
>
> Regards,
> Jim
>
> > +
> > + cleanup:
> > + virObjectUnref(cfg);
> > + libxl_device_usbdev_dispose(&usbdev);
> > + return ret;
> > +}
> > +
> > +static int
> > libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
> > virDomainObjPtr vm,
> > virDomainHostdevDefPtr hostdev)
> > @@ -3402,6 +3527,9 @@ libxlDomainDetachHostDevice(libxlDriverPrivatePtr
> driver,
> > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
> > return libxlDomainDetachHostPCIDevice(driver, vm, hostdev);
> >
> > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
> > + return libxlDomainDetachHostUSBDevice(driver, vm, hostdev);
> > +
> > default:
> > virReportError(VIR_ERR_INTERNAL_ERROR,
> > _("unexpected hostdev type %d"), subsys->type);
>
>
More information about the libvir-list
mailing list