[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