[libvirt] [PATCH 12/13] Fix QEMU hotplug device alias assignment

Daniel P. Berrange berrange at redhat.com
Mon Feb 1 18:39:41 UTC 2010


To allow devices to be hot(un-)plugged it is neccessary to ensure
they all have a unique device aliases. This fixes the hotplug
methods to assign device aliases before invoking the monitor
commands which need them

* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Expose methods
  for assigning device aliases for disks, host devices and
  controllers
* src/qemu/qemu_driver.c: Assign device aliases when hotplugging
  all types of device
* tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args,
  tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args:
  Update for changed hostdev naming scheme
---
 src/qemu/qemu_conf.c                               |   61 +++++++++++++++----
 src/qemu/qemu_conf.h                               |    3 +
 src/qemu/qemu_driver.c                             |   35 +++++++-----
 .../qemuxml2argv-hostdev-pci-address-device.args   |    2 +-
 .../qemuxml2argv-hostdev-usb-address-device.args   |    2 +-
 5 files changed, 74 insertions(+), 29 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index e8f2678..074fb7b 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1637,7 +1637,7 @@ no_memory:
 }
 
 
-static int
+int
 qemuAssignDeviceDiskAlias(virDomainDiskDefPtr def, int qemuCmdFlags)
 {
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
@@ -1677,6 +1677,49 @@ qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx)
     return 0;
 }
 
+
+int
+qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev, int idx)
+{
+    if (idx == -1) {
+        int i;
+        idx = 0;
+        for (i = 0 ; i < def->nhostdevs ; i++) {
+            int thisidx;
+            if ((thisidx = qemuDomainDeviceAliasIndex(&def->hostdevs[i]->info, "hostdev")) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                                 _("Unable to determine device index for hostdevwork device"));
+                return -1;
+            }
+            if (thisidx >= idx)
+                idx = thisidx + 1;
+        }
+    }
+
+    if (virAsprintf(&hostdev->info.alias, "hostdev%d", idx) < 0) {
+        virReportOOMError(NULL);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+int
+qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller)
+{
+    const char *prefix = virDomainControllerTypeToString(controller->type);
+
+    if (virAsprintf(&controller->info.alias,  "%s%d", prefix,
+                    controller->idx) < 0) {
+        virReportOOMError(NULL);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 qemuAssignDeviceAliases(virDomainDefPtr def, int qemuCmdFlags)
 {
@@ -1702,24 +1745,16 @@ qemuAssignDeviceAliases(virDomainDefPtr def, int qemuCmdFlags)
             goto no_memory;
     }
     for (i = 0; i < def->nhostdevs ; i++) {
-        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
-            const char *prefix = virDomainHostdevSubsysTypeToString
-                (def->hostdevs[i]->source.subsys.type);
-            if (virAsprintf(&def->hostdevs[i]->info.alias, "host%s%d", prefix, i) < 0)
-                goto no_memory;
-        } else {
-            if (virAsprintf(&def->hostdevs[i]->info.alias, "host%d",i) < 0)
-                goto no_memory;
-        }
+        if (qemuAssignDeviceHostdevAlias(def, def->hostdevs[i], i) < 0)
+            return -1;
     }
     for (i = 0; i < def->nvideos ; i++) {
         if (virAsprintf(&def->videos[i]->info.alias, "video%d", i) < 0)
             goto no_memory;
     }
     for (i = 0; i < def->ncontrollers ; i++) {
-        const char *prefix = virDomainControllerTypeToString(def->controllers[i]->type);
-        if (virAsprintf(&def->controllers[i]->info.alias, "%s%d", prefix, i) < 0)
-            goto no_memory;
+        if (qemuAssignDeviceControllerAlias(def->controllers[i]) < 0)
+            return -1;
     }
     for (i = 0; i < def->ninputs ; i++) {
         if (virAsprintf(&def->inputs[i]->info.alias, "input%d", i) < 0)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index b7b1666..1a0fac0 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -284,6 +284,9 @@ int  qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr ad
 
 int qemuDomainNetVLAN(virDomainNetDefPtr def);
 int qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx);
+int qemuAssignDeviceDiskAlias(virDomainDiskDefPtr def, int qemuCmdFlags);
+int qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr net, int idx);
+int qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller);
 
 
 #endif /* __QEMUD_CONF_H */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 23bbd6b..5e58ce2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5240,6 +5240,8 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
         if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
             goto error;
+        if (qemuAssignDeviceDiskAlias(disk, qemuCmdFlags) < 0)
+            goto error;
 
         if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
             goto error;
@@ -5322,9 +5324,12 @@ static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
         }
     }
 
-    if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
-        qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
-        goto cleanup;
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+        if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
+            goto cleanup;
+        if (qemuAssignDeviceControllerAlias(controller) < 0)
+            goto cleanup;
+    }
 
     if (!(devstr = qemuBuildControllerDevStr(controller))) {
         virReportOOMError(NULL);
@@ -5428,17 +5433,7 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
         driver->securityDriver->domainSetSecurityImageLabel(conn, vm, disk) < 0)
         return -1;
 
-    /* This func allocates the bus/unit IDs so must be before
-     * we search for controller
-     */
-    if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
-        goto error;
-
-    if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
-        !(devstr = qemuBuildDriveDevStr(NULL, disk)))
-        goto error;
-
-    /* We should have an adddress now, so make sure */
+    /* We should have an adddress already, so make sure */
     if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                          _("unexpected disk address type %s"),
@@ -5446,6 +5441,16 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
         goto error;
     }
 
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+        if (qemuAssignDeviceDiskAlias(disk, qemuCmdFlags) < 0)
+            goto error;
+        if (!(devstr = qemuBuildDriveDevStr(NULL, disk)))
+            goto error;
+    }
+
+    if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
+        goto error;
+
     for (i = 0 ; i <= disk->info.addr.drive.controller ; i++) {
         cont = qemuDomainFindOrCreateSCSIDiskController(conn, driver, vm, i, qemuCmdFlags);
         if (!cont)
@@ -5540,6 +5545,8 @@ static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
     }
 
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+        if (qemuAssignDeviceDiskAlias(disk, qemuCmdFlags) < 0)
+            goto error;
         if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
             goto error;
         if (!(devstr = qemuBuildDriveDevStr(NULL, disk)))
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args
index 1b8a130..868f892 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostdev0,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args
index cdab007..0d39928 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device usb-host,hostbus=014,hostaddr=006,id=hostusb0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device usb-host,hostbus=014,hostaddr=006,id=hostdev0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
-- 
1.6.5.2




More information about the libvir-list mailing list