[libvirt] [PATCH V2 3/7] libxl: support usb controller hotplug

Chunyan Liu cyliu at suse.com
Wed Jun 15 06:00:10 UTC 2016


Support USB controller hot-plug and hot-unplug.

 #virsh attach-device dom usbctrl.xml
 #virsh detach-device dom usbctrl.xml
 usbctrl.xml example:
 <controller type='usb' index='0' model='qusb2'>

Signed-off-by: Chunyan Liu <cyliu at suse.com>
---
 src/libxl/libxl_driver.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index f507265..f614769 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3006,6 +3006,60 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr driver,
 
 #ifdef LIBXL_HAVE_PVUSB
 static int
+libxlDomainAttachControllerDevice(libxlDriverPrivatePtr driver,
+                                  virDomainObjPtr vm,
+                                  virDomainControllerDefPtr controller)
+{
+    libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
+    const char *type = virDomainControllerTypeToString(controller->type);
+    libxl_device_usbctrl usbctrl;
+    int ret = -1;
+
+    libxl_device_usbctrl_init(&usbctrl);
+
+    if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("'%s' controller cannot be hot plugged."),
+                       type);
+        goto cleanup;
+    }
+
+    if (controller->idx == -1)
+        controller->idx = virDomainControllerFindUnusedIndex(vm->def,
+                                                             controller->type);
+
+    if (controller->opts.usbopts.ports == -1)
+        controller->opts.usbopts.ports = 8;
+
+    if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) {
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       _("target %s:%d already exists"),
+                       type, controller->idx);
+        goto cleanup;
+    }
+
+    if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers + 1) < 0)
+        goto cleanup;
+
+    if (libxlMakeUSBController(controller, &usbctrl) < 0)
+        goto cleanup;
+
+    if (libxl_device_usbctrl_add(cfg->ctx, vm->def->id, &usbctrl, 0) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("libxenlight failed to attach USB controller"));
+        goto cleanup;
+    }
+
+    virDomainControllerInsertPreAlloced(vm->def, controller);
+    ret = 0;
+
+ cleanup:
+    virObjectUnref(cfg);
+    libxl_device_usbctrl_dispose(&usbctrl);
+    return ret;
+}
+
+static int
 libxlDomainAttachHostUSBDevice(libxlDriverPrivatePtr driver,
                                virDomainObjPtr vm,
                                virDomainHostdevDefPtr hostdev)
@@ -3240,6 +3294,12 @@ libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
                 dev->data.disk = NULL;
             break;
 
+        case VIR_DOMAIN_DEVICE_CONTROLLER:
+            ret = libxlDomainAttachControllerDevice(driver, vm, dev->data.controller);
+            if (!ret)
+                dev->data.controller = NULL;
+            break;
+
         case VIR_DOMAIN_DEVICE_NET:
             ret = libxlDomainAttachNetDevice(driver, vm,
                                              dev->data.net);
@@ -3270,6 +3330,7 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
     virDomainDiskDefPtr disk;
     virDomainNetDefPtr net;
     virDomainHostdevDefPtr hostdev;
+    virDomainControllerDefPtr controller;
     virDomainHostdevDefPtr found;
     char mac[VIR_MAC_STRING_BUFLEN];
 
@@ -3287,6 +3348,21 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
             dev->data.disk = NULL;
             break;
 
+        case VIR_DOMAIN_DEVICE_CONTROLLER:
+            controller = dev->data.controller;
+            if (controller->idx != -1 &&
+                virDomainControllerFind(vmdef, controller->type,
+                                        controller->idx) >= 0) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("Target already exists"));
+                return -1;
+            }
+
+            if (virDomainControllerInsert(vmdef, controller) < 0)
+                return -1;
+            dev->data.controller = NULL;
+            break;
+
         case VIR_DOMAIN_DEVICE_NET:
             net = dev->data.net;
             if (virDomainHasNet(vmdef, net)) {
@@ -3425,6 +3501,57 @@ libxlDomainDetachHostPCIDevice(libxlDriverPrivatePtr driver,
 
 #ifdef LIBXL_HAVE_PVUSB
 static int
+libxlDomainDetachControllerDevice(libxlDriverPrivatePtr driver,
+                                  virDomainObjPtr vm,
+                                  virDomainDeviceDefPtr dev)
+{
+    int idx, ret = -1;
+    virDomainControllerDefPtr detach = NULL;
+    virDomainControllerDefPtr controller = dev->data.controller;
+    const char *type = virDomainControllerTypeToString(controller->type);
+    libxl_device_usbctrl usbctrl;
+    libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
+
+    libxl_device_usbctrl_init(&usbctrl);
+
+    if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("'%s' controller cannot be hot plugged."),
+                       type);
+        goto cleanup;
+    }
+
+    if ((idx = virDomainControllerFind(vm->def,
+                                       controller->type,
+                                       controller->idx)) < 0) {
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       _("controller %s:%d not found"),
+                       type, controller->idx);
+        goto cleanup;
+    }
+
+    detach = vm->def->controllers[idx];
+
+    if (libxlMakeUSBController(controller, &usbctrl) < 0)
+        goto cleanup;
+
+    if (libxl_device_usbctrl_remove(cfg->ctx, vm->def->id, &usbctrl, 0) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("libxenlight failed to detach USB controller"));
+        goto cleanup;
+    }
+
+    virDomainControllerRemove(vm->def, idx);
+    ret = 0;
+
+ cleanup:
+    virDomainControllerDefFree(detach);
+    virObjectUnref(cfg);
+    libxl_device_usbctrl_dispose(&usbctrl);
+    return ret;
+}
+
+static int
 libxlDomainDetachHostUSBDevice(libxlDriverPrivatePtr driver,
                                virDomainObjPtr vm,
                                virDomainHostdevDefPtr hostdev)
@@ -3588,6 +3715,10 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
             ret = libxlDomainDetachDeviceDiskLive(vm, dev);
             break;
 
+        case VIR_DOMAIN_DEVICE_CONTROLLER:
+            ret = libxlDomainDetachControllerDevice(driver, vm, dev);
+            break;
+
         case VIR_DOMAIN_DEVICE_NET:
             ret = libxlDomainDetachNetDevice(driver, vm,
                                              dev->data.net);
@@ -3622,6 +3753,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk, detach;
     virDomainHostdevDefPtr hostdev, det_hostdev;
+    virDomainControllerDefPtr cont, det_cont;
     virDomainNetDefPtr net;
     int idx;
 
@@ -3636,6 +3768,18 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
             virDomainDiskDefFree(detach);
             break;
 
+        case VIR_DOMAIN_DEVICE_CONTROLLER:
+            cont = dev->data.controller;
+            if ((idx = virDomainControllerFind(vmdef, cont->type,
+                                               cont->idx)) < 0) {
+                virReportError(VIR_ERR_INVALID_ARG, "%s",
+                               _("device not present in domain configuration"));
+                return -1;
+            }
+            det_cont = virDomainControllerRemove(vmdef, idx);
+            virDomainControllerDefFree(det_cont);
+            break;
+
         case VIR_DOMAIN_DEVICE_NET:
             net = dev->data.net;
             if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
-- 
2.1.4




More information about the libvir-list mailing list