]> xenbits.xensource.com Git - libvirt.git/commitdiff
libxl: support creating guest with USB hostdev
authorChunyan Liu <cyliu@suse.com>
Thu, 19 May 2016 08:14:33 +0000 (16:14 +0800)
committerJim Fehlig <jfehlig@suse.com>
Tue, 14 Jun 2016 20:25:47 +0000 (14:25 -0600)
Support creating guest with USB host device in config file.
Currently libxl only supports xen PV guest, and only supports
specifying USB host device by 'bus number' and 'device number',
for example:

    <hostdev mode='subsystem' type='usb' managed='no'>
      <source>
        <address bus='1' device='3'/>
      </source>
    </hostdev>

Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
src/libxl/libxl_conf.c
src/libxl/libxl_conf.h
src/libxl/libxl_domain.c
src/libxl/libxl_driver.c

index acb6594bc3f08e81a988ea34e55974037bb578de..59898193777c764267f82e63388990ed19f30675 100644 (file)
@@ -1514,6 +1514,75 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg,
 
 }
 
+#ifdef LIBXL_HAVE_PVUSB
+int
+libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev)
+{
+    virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
+
+    if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+        return -1;
+    if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+        return -1;
+
+    if (usbsrc->bus <= 0 || usbsrc->device <= 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("libxenlight supports only USB device "
+                         "specified by busnum:devnum"));
+        return -1;
+    }
+
+    usbdev->u.hostdev.hostbus = usbsrc->bus;
+    usbdev->u.hostdev.hostaddr = usbsrc->device;
+
+    return 0;
+}
+
+static int
+libxlMakeUSBList(virDomainDefPtr def, libxl_domain_config *d_config)
+{
+    virDomainHostdevDefPtr *l_hostdevs = def->hostdevs;
+    size_t nhostdevs = def->nhostdevs;
+    size_t nusbdevs = 0;
+    libxl_device_usbdev *x_usbdevs;
+    size_t i, j;
+
+    if (nhostdevs == 0)
+        return 0;
+
+    if (VIR_ALLOC_N(x_usbdevs, nhostdevs) < 0)
+        return -1;
+
+    for (i = 0, j = 0; i < nhostdevs; i++) {
+        if (l_hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+            continue;
+        if (l_hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+            continue;
+
+        libxl_device_usbdev_init(&x_usbdevs[j]);
+
+        if (libxlMakeUSB(l_hostdevs[i], &x_usbdevs[j]) < 0)
+            goto error;
+
+        nusbdevs++;
+        j++;
+    }
+
+    VIR_SHRINK_N(x_usbdevs, nhostdevs, nhostdevs - nusbdevs);
+    d_config->usbdevs = x_usbdevs;
+    d_config->num_usbdevs = nusbdevs;
+
+    return 0;
+
+ error:
+    for (i = 0; i < nusbdevs; i++)
+        libxl_device_usbdev_dispose(&x_usbdevs[i]);
+
+    VIR_FREE(x_usbdevs);
+    return -1;
+}
+#endif
+
 int
 libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev)
 {
@@ -1717,6 +1786,11 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
     if (libxlMakePCIList(def, d_config) < 0)
         return -1;
 
+#ifdef LIBXL_HAVE_PVUSB
+    if (libxlMakeUSBList(def, d_config) < 0)
+        return -1;
+#endif
+
     /*
      * Now that any potential VFBs are defined, update the build info with
      * the data of the primary display. Some day libxl might implicitely do
index 6547056dfeca97d7750b1e24cd0eb48e008d2ffe..8cb2b14c8d7403a70eeb063e59eab7cba9f440f0 100644 (file)
@@ -184,6 +184,11 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports,
 int
 libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev);
 
+# ifdef LIBXL_HAVE_PVUSB
+int
+libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev);
+# endif
+
 virDomainXMLOptionPtr
 libxlCreateXMLConf(void);
 
index 76379eb09631b499b6bda88a761240f1a1262d73..221af8754d1ee8bfbf17df08958234482873aec6 100644 (file)
@@ -731,9 +731,14 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
     int vnc_port;
     char *file;
     virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
+    unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI;
+
+#ifdef LIBXL_HAVE_PVUSB
+    hostdev_flags |= VIR_HOSTDEV_SP_USB;
+#endif
 
     virHostdevReAttachDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
-                                    vm->def, VIR_HOSTDEV_SP_PCI, NULL);
+                                    vm->def, hostdev_flags, NULL);
 
     VIR_FREE(priv->lockState);
     if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
@@ -1043,6 +1048,11 @@ libxlDomainStart(libxlDriverPrivatePtr driver,
     virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
     libxl_asyncprogress_how aop_console_how;
     libxl_domain_restore_params params;
+    unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI;
+
+#ifdef LIBXL_HAVE_PVUSB
+    hostdev_flags |= VIR_HOSTDEV_SP_USB;
+#endif
 
     libxl_domain_config_init(&d_config);
 
@@ -1118,7 +1128,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver,
         goto cleanup_dom;
 
     if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
-                                       vm->def, VIR_HOSTDEV_SP_PCI) < 0)
+                                       vm->def, hostdev_flags) < 0)
         goto cleanup_dom;
 
     /* Unlock virDomainObj while creating the domain */
index 0644f604674285a71297bcf7902311b5984ce86a..2c5d32224856780134d1192390dc3df367a782be 100644 (file)
@@ -351,6 +351,11 @@ libxlReconnectDomain(virDomainObjPtr vm,
     int len;
     uint8_t *data = NULL;
     virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
+    unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI;
+
+#ifdef LIBXL_HAVE_PVUSB
+    hostdev_flags |= VIR_HOSTDEV_SP_USB;
+#endif
 
     virObjectLock(vm);
 
@@ -378,7 +383,7 @@ libxlReconnectDomain(virDomainObjPtr vm,
 
     /* Update hostdev state */
     if (virHostdevUpdateActiveDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
-                                            vm->def, VIR_HOSTDEV_SP_PCI) < 0)
+                                            vm->def, hostdev_flags) < 0)
         goto out;
 
     if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)