[libvirt] [PATCH 1/2] libxl: support creating guest with USB hostdev

Chunyan Liu cyliu at suse.com
Thu Apr 21 08:16:03 UTC 2016


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

Signed-off-by: Chunyan Liu <cyliu at suse.com>
---
 src/libxl/libxl_conf.c   | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/libxl/libxl_conf.h   |  3 ++
 src/libxl/libxl_domain.c |  4 +--
 src/libxl/libxl_driver.c |  2 +-
 4 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 30f2ce9..3b69cbf 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1848,6 +1848,74 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg,
 }
 
 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 < nhostdevs; i++)
+        libxl_device_usbdev_dispose(&x_usbdevs[i]);
+
+    VIR_FREE(x_usbdevs);
+    return -1;
+}
+
+
+int
 libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev)
 {
     virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
@@ -2078,6 +2146,9 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
     if (libxlMakePCIList(def, d_config) < 0)
         return -1;
 
+    if (libxlMakeUSBList(def, d_config) < 0)
+        return -1;
+
     /*
      * Now that any potential VFBs are defined, update the build info with
      * the data of the primary display. Some day libxl might implicitely do
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 24e2911..e3ccca1 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -192,6 +192,9 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports,
 int
 libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev);
 
+int
+libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev);
+
 virDomainXMLOptionPtr
 libxlCreateXMLConf(void);
 
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 14a900c..4272dda 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -728,7 +728,7 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
     virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
 
     virHostdevReAttachDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
-                                    vm->def, VIR_HOSTDEV_SP_PCI, NULL);
+                                    vm->def, VIR_HOSTDEV_SP_PCI | VIR_HOSTDEV_SP_USB, NULL);
 
     VIR_FREE(priv->lockState);
     if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
@@ -1103,7 +1103,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
         goto cleanup_dom;
 
     if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
-                                       vm->def, VIR_HOSTDEV_SP_PCI) < 0)
+                                       vm->def, VIR_HOSTDEV_SP_PCI | VIR_HOSTDEV_SP_USB) < 0)
         goto cleanup_dom;
 
     /* Unlock virDomainObj while creating the domain */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index bf97c9c..18a0891 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -383,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, VIR_HOSTDEV_SP_PCI | VIR_HOSTDEV_SP_USB) < 0)
         goto out;
 
     if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
-- 
2.1.4




More information about the libvir-list mailing list