[libvirt] [PATCH 10/13] Re-arrange QEMU device alias assignment code

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


This patch re-arranges the QEMU device alias assignment code to
make it easier to call into the same codeblock when performing
device hotplug. The new code has the ability to skip over already
assigned names to facilitate hotplug

* src/qemu/qemu_driver.c: Call qemuAssignDeviceNetAlias()
  instead of qemuAssignNetNames
* src/qemu/qemu_conf.h: Export qemuAssignDeviceNetAlias()
  instead of qemuAssignNetNames
* src/qemu/qemu_driver.c: Merge the legacy disk/network alias
  assignment code into the main methods
---
 src/qemu/qemu_conf.c   |  295 +++++++++++++++++++++++++-----------------------
 src/qemu/qemu_conf.h   |    4 +-
 src/qemu/qemu_driver.c |   14 ++-
 3 files changed, 166 insertions(+), 147 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index b255503..e8f2678 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1537,30 +1537,166 @@ int qemuDomainNetVLAN(virDomainNetDefPtr def)
     return qemuDomainDeviceAliasIndex(&def->info, "net");
 }
 
+
+/* Names used before -drive existed */
+static int qemuAssignDeviceDiskAliasLegacy(virDomainDiskDefPtr disk)
+{
+    char *devname;
+
+    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+        STREQ(disk->dst, "hdc"))
+        devname = strdup("cdrom");
+    else
+        devname = strdup(disk->dst);
+
+    if (!devname) {
+        virReportOOMError(NULL);
+        return -1;
+    }
+
+    disk->info.alias = devname;
+    return 0;
+}
+
+
+/* Names used before -drive supported the id= option */
+static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk)
+{
+    int busid, devid;
+    int ret;
+    char *devname;
+
+    if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("cannot convert disk '%s' to bus/device index"),
+                         disk->dst);
+        return -1;
+    }
+
+    switch (disk->bus) {
+    case VIR_DOMAIN_DISK_BUS_IDE:
+        if (disk->device== VIR_DOMAIN_DISK_DEVICE_DISK)
+            ret = virAsprintf(&devname, "ide%d-hd%d", busid, devid);
+        else
+            ret = virAsprintf(&devname, "ide%d-cd%d", busid, devid);
+        break;
+    case VIR_DOMAIN_DISK_BUS_SCSI:
+        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
+            ret = virAsprintf(&devname, "scsi%d-hd%d", busid, devid);
+        else
+            ret = virAsprintf(&devname, "scsi%d-cd%d", busid, devid);
+        break;
+    case VIR_DOMAIN_DISK_BUS_FDC:
+        ret = virAsprintf(&devname, "floppy%d", devid);
+        break;
+    case VIR_DOMAIN_DISK_BUS_VIRTIO:
+        ret = virAsprintf(&devname, "virtio%d", devid);
+        break;
+    case VIR_DOMAIN_DISK_BUS_XEN:
+        ret = virAsprintf(&devname, "xenblk%d", devid);
+        break;
+    default:
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT,
+                         _("Unsupported disk name mapping for bus '%s'"),
+                         virDomainDiskBusTypeToString(disk->bus));
+        return -1;
+    }
+
+    if (ret == -1) {
+        virReportOOMError(NULL);
+        return -1;
+    }
+
+    disk->info.alias = devname;
+
+    return 0;
+}
+
+
+/* Our custom -drive naming scheme used with id= */
+static int qemuAssignDeviceDiskAliasCustom(virDomainDiskDefPtr disk)
+{
+    const char *prefix = virDomainDiskBusTypeToString(disk->bus);
+    if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
+        if (virAsprintf(&disk->info.alias, "%s%d-%d-%d", prefix,
+                        disk->info.addr.drive.controller,
+                        disk->info.addr.drive.bus,
+                        disk->info.addr.drive.unit) < 0)
+            goto no_memory;
+    } else {
+        int idx = virDiskNameToIndex(disk->dst);
+        if (virAsprintf(&disk->info.alias, "%s-disk%d", prefix, idx) < 0)
+            goto no_memory;
+    }
+
+    return 0;
+
+no_memory:
+    virReportOOMError(NULL);
+    return -1;
+}
+
+
 static int
-qemuAssignDeviceAliases(virDomainDefPtr def)
+qemuAssignDeviceDiskAlias(virDomainDiskDefPtr def, int qemuCmdFlags)
+{
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
+        if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
+            return qemuAssignDeviceDiskAliasCustom(def);
+        else
+            return qemuAssignDeviceDiskAliasFixed(def);
+    } else {
+        return qemuAssignDeviceDiskAliasLegacy(def);
+    }
+}
+
+
+int
+qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx)
+{
+    if (idx == -1) {
+        int i;
+        idx = 0;
+        for (i = 0 ; i < def->nnets ; i++) {
+            int thisidx;
+            if ((thisidx = qemuDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                                 _("Unable to determine device index for network device"));
+                return -1;
+            }
+            if (thisidx >= idx)
+                idx = thisidx + 1;
+        }
+    }
+
+    if (virAsprintf(&net->info.alias, "net%d", idx) < 0) {
+        virReportOOMError(NULL);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int
+qemuAssignDeviceAliases(virDomainDefPtr def, int qemuCmdFlags)
 {
     int i;
 
     for (i = 0; i < def->ndisks ; i++) {
-        const char *prefix = virDomainDiskBusTypeToString(def->disks[i]->bus);
-        if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
-            if (virAsprintf(&def->disks[i]->info.alias, "%s%d-%d-%d", prefix,
-                            def->disks[i]->info.addr.drive.controller,
-                            def->disks[i]->info.addr.drive.bus,
-                            def->disks[i]->info.addr.drive.unit) < 0)
-                goto no_memory;
-        } else {
-            int idx = virDiskNameToIndex(def->disks[i]->dst);
-            if (virAsprintf(&def->disks[i]->info.alias, "%s-disk%d", prefix, idx) < 0)
-                goto no_memory;
-        }
+        if (qemuAssignDeviceDiskAlias(def->disks[i], qemuCmdFlags) < 0)
+            return -1;
     }
-    for (i = 0; i < def->nnets ; i++) {
-        if (virAsprintf(&def->nets[i]->info.alias, "net%d", i) < 0)
-            goto no_memory;
+    if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) ||
+        (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+        for (i = 0; i < def->nnets ; i++) {
+            if (qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0)
+                return -1;
+        }
     }
 
+    if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE))
+        return 0;
+
     for (i = 0; i < def->nsounds ; i++) {
         if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0)
             goto no_memory;
@@ -1921,92 +2057,6 @@ error:
 }
 
 
-static char *qemuDiskLegacyName(const virDomainDiskDefPtr disk)
-{
-    char *devname;
-
-    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-        STREQ(disk->dst, "hdc"))
-        devname = strdup("cdrom");
-    else
-        devname = strdup(disk->dst);
-
-    if (!devname)
-        virReportOOMError(NULL);
-
-    return NULL;
-}
-
-/* Return the -drive QEMU disk name for use in monitor commands */
-static char *qemuDiskDriveName(const virDomainDiskDefPtr disk)
-{
-    int busid, devid;
-    int ret;
-    char *devname;
-
-    if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
-        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot convert disk '%s' to bus/device index"),
-                         disk->dst);
-        return NULL;
-    }
-
-    switch (disk->bus) {
-    case VIR_DOMAIN_DISK_BUS_IDE:
-        if (disk->device== VIR_DOMAIN_DISK_DEVICE_DISK)
-            ret = virAsprintf(&devname, "ide%d-hd%d", busid, devid);
-        else
-            ret = virAsprintf(&devname, "ide%d-cd%d", busid, devid);
-        break;
-    case VIR_DOMAIN_DISK_BUS_SCSI:
-        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
-            ret = virAsprintf(&devname, "scsi%d-hd%d", busid, devid);
-        else
-            ret = virAsprintf(&devname, "scsi%d-cd%d", busid, devid);
-        break;
-    case VIR_DOMAIN_DISK_BUS_FDC:
-        ret = virAsprintf(&devname, "floppy%d", devid);
-        break;
-    case VIR_DOMAIN_DISK_BUS_VIRTIO:
-        ret = virAsprintf(&devname, "virtio%d", devid);
-        break;
-    case VIR_DOMAIN_DISK_BUS_XEN:
-        ret = virAsprintf(&devname, "xenblk%d", devid);
-        break;
-    default:
-        qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT,
-                         _("Unsupported disk name mapping for bus '%s'"),
-                         virDomainDiskBusTypeToString(disk->bus));
-        return NULL;
-    }
-
-    if (ret == -1) {
-        virReportOOMError(NULL);
-        return NULL;
-    }
-
-    return devname;
-}
-
-static int
-qemuAssignDiskAliases(virDomainDefPtr def, int qemuCmdFlags)
-{
-    int i;
-
-    for (i = 0 ; i < def->ndisks ; i++) {
-        if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE)
-            def->disks[i]->info.alias =
-                qemuDiskDriveName(def->disks[i]);
-        else
-            def->disks[i]->info.alias =
-                qemuDiskLegacyName(def->disks[i]);
-
-        if (!def->disks[i]->info.alias)
-            return -1;
-    }
-    return 0;
-}
-
 static int
 qemuBuildDeviceAddressStr(virBufferPtr buf,
                           virDomainDeviceInfoPtr info)
@@ -2040,34 +2090,6 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
 }
 
 
-int
-qemuAssignNetNames(virDomainDefPtr def,
-                   virDomainNetDefPtr net)
-{
-    int i;
-    int lastidx = -1;
-
-    for (i = 0; i < def->nnets && def->nets[i] != net ; i++) {
-        int idx;
-
-        if ((idx = qemuDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0) {
-            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
-                             _("Unable to determine device index for network device"));
-            return -1;
-        }
-
-        if (idx > lastidx)
-            lastidx = idx;
-    }
-
-    if (virAsprintf(&net->info.alias, "net%d", lastidx + 1) < 0) {
-        virReportOOMError(NULL);
-        return -1;
-    }
-
-    return 0;
-}
-
 #define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
 
@@ -2983,11 +3005,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
     uname_normalize(&ut);
 
-    if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
-        qemuAssignDeviceAliases(def);
-    } else {
-        qemuAssignDiskAliases(def, qemuCmdFlags);
-    }
+    if (qemuAssignDeviceAliases(def, qemuCmdFlags) < 0)
+        return -1;
 
     virUUIDFormat(def->uuid, uuid);
 
@@ -3540,12 +3559,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
                     goto no_memory;
             }
 
-            if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
-                !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
-                if (qemuAssignNetNames(def, net) < 0)
-                    goto no_memory;
-            }
-
             /* Possible combinations:
              *
              *  1. Old way:   -net nic,model=e1000,vlan=1 -net tap,vlan=1
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 7b439fd..b7b1666 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -247,9 +247,6 @@ int         qemudNetworkIfaceConnect    (virConnectPtr conn,
                                          virDomainNetDefPtr net,
                                          int qemuCmdFlags);
 
-int         qemuAssignNetNames          (virDomainDefPtr def,
-                                         virDomainNetDefPtr net);
-
 int         qemudProbeMachineTypes      (const char *binary,
                                          virCapsGuestMachinePtr **machines,
                                          int *nmachines);
@@ -286,6 +283,7 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
 int  qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs);
 
 int qemuDomainNetVLAN(virDomainNetDefPtr def);
+int qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx);
 
 
 #endif /* __QEMUD_CONF_H */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f00bb75..23bbd6b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5625,9 +5625,11 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
         goto no_memory;
 
-    if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
-        qemuAssignNetNames(vm->def, net) < 0)
-        goto cleanup;
+    if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) ||
+        (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+        if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
+            goto cleanup;
+    }
 
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
         qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
@@ -5635,6 +5637,12 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 
     vlan = qemuDomainNetVLAN(net);
 
+    if (vlan < 0) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s",
+                         _("Unable to attach network devices without vlan"));
+        goto cleanup;
+    }
+
     if (tapfd != -1) {
         if (virAsprintf(&tapfd_name, "fd-%s", net->info.alias) < 0)
             goto no_memory;
-- 
1.6.5.2




More information about the libvir-list mailing list