[libvirt] [PATCH 11/25] qemu: Refactor helpers for USB device attachment

Osier Yang jyang at redhat.com
Fri May 3 18:07:30 UTC 2013


It's better to put the usb related codes into qemuDomainAttachHostUsbDevice
instead of qemuDomainAttachHostDevice.

And in the old qemuDomainAttachHostDevice, just stealing the "usb" from
driver->activeUsbHostdevs leaks the memory.
---
 src/qemu/qemu_hotplug.c | 77 +++++++++++++++++++++----------------------------
 1 file changed, 33 insertions(+), 44 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a4f48b0..422d336 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1136,20 +1136,38 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
                                   virDomainObjPtr vm,
                                   virDomainHostdevDefPtr hostdev)
 {
-    int ret;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virUSBDeviceList *list = NULL;
+    virUSBDevicePtr usb = NULL;
     char *devstr = NULL;
+    bool added = false;
+    int ret = -1;
+
+    if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
+        return -1;
+
+    if (!(list = virUSBDeviceListNew()))
+        goto cleanup;
+
+    if (virUSBDeviceListAdd(list, usb) < 0)
+        goto cleanup;
+
+    if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0)
+        goto cleanup;
+
+    added = true;
+    virUSBDeviceListSteal(list, usb);
 
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
-            goto error;
+            goto cleanup;
         if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, priv->qemuCaps)))
-            goto error;
+            goto cleanup;
     }
 
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
         virReportOOMError();
-        goto error;
+        goto cleanup;
     }
 
     qemuDomainObjEnterMonitor(driver, vm);
@@ -1162,26 +1180,24 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
     qemuDomainObjExitMonitor(driver, vm);
     virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
     if (ret < 0)
-        goto error;
+        goto cleanup;
 
     vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
 
+    ret = 0;
+cleanup:
+    if (added)
+        virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
+    virUSBDeviceFree(usb);
+    virObjectUnref(list);
     VIR_FREE(devstr);
-
-    return 0;
-
-error:
-    VIR_FREE(devstr);
-    return -1;
+    return ret;
 }
 
 int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
                                virDomainHostdevDefPtr hostdev)
 {
-    virUSBDeviceList *list;
-    virUSBDevicePtr usb = NULL;
-
     if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("hostdev mode '%s' not supported"),
@@ -1189,33 +1205,12 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    if (!(list = virUSBDeviceListNew()))
-        goto cleanup;
-
-    if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
-        if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
-            goto cleanup;
-
-        if (virUSBDeviceListAdd(list, usb) < 0) {
-            virUSBDeviceFree(usb);
-            usb = NULL;
-            goto cleanup;
-        }
-
-        if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0) {
-            usb = NULL;
-            goto cleanup;
-        }
-
-        virUSBDeviceListSteal(list, usb);
-    }
-
     if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
-       goto cleanup;
+        return -1;
 
     if (virSecurityManagerSetHostdevLabel(driver->securityManager,
                                           vm->def, hostdev, NULL) < 0)
-        goto teardown_cgroup;
+        goto cleanup;
 
     switch (hostdev->source.subsys.type) {
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
@@ -1237,7 +1232,6 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
         goto error;
     }
 
-    virObjectUnref(list);
     return 0;
 
 error:
@@ -1245,14 +1239,9 @@ error:
                                               vm->def, hostdev, NULL) < 0)
         VIR_WARN("Unable to restore host device labelling on hotplug fail");
 
-teardown_cgroup:
+cleanup:
     if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
         VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
-
-cleanup:
-    virObjectUnref(list);
-    if (usb)
-        virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
     return -1;
 }
 
-- 
1.8.1.4




More information about the libvir-list mailing list