[libvirt] [PATCH 20/34] Assign device aliases for all devices at startup

Daniel P. Berrange berrange at redhat.com
Fri Jan 8 17:23:16 UTC 2010


When starting a guest, give every device a unique alias. This will
be used for the 'id' parameter in -device args in later patches.
It can also be used to uniquely identify devices in the monitor

For old QEMU without -device, assign disk names based on QEMU's
historical naming scheme.

* src/qemu/qemu_conf.c: Assign unique device aliases
* src/qemu/qemu_driver.c: Remove obsolete qemudDiskDeviceName
  and use the device alias in eject & blockstats commands
---
 src/qemu/qemu_conf.c   |  173 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_driver.c |  104 ++++++-----------------------
 2 files changed, 195 insertions(+), 82 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 3718470..5dcd50f 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1460,6 +1460,173 @@ cleanup:
     return tapfd;
 }
 
+
+static int
+qemuAssignDeviceAliases(virDomainDefPtr def)
+{
+    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;
+        }
+    }
+    for (i = 0; i < def->nnets ; i++) {
+        if (def->nets[i]->model) {
+            if (virAsprintf(&def->nets[i]->info.alias, "%s-nic%d", def->nets[i]->model, i) < 0)
+                goto no_memory;
+        } else {
+            if (virAsprintf(&def->nets[i]->info.alias, "nic%d", i) < 0)
+                goto no_memory;
+        }
+    }
+
+    for (i = 0; i < def->nsounds ; i++) {
+        if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0)
+            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;
+        }
+    }
+    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;
+    }
+    for (i = 0; i < def->ninputs ; i++) {
+        if (virAsprintf(&def->inputs[i]->info.alias, "input%d", i) < 0)
+            goto no_memory;
+    }
+    for (i = 0; i < def->nparallels ; i++) {
+        if (virAsprintf(&def->parallels[i]->info.alias, "parallel%d", i) < 0)
+            goto no_memory;
+    }
+    for (i = 0; i < def->nserials ; i++) {
+        if (virAsprintf(&def->serials[i]->info.alias, "serial%d", i) < 0)
+            goto no_memory;
+    }
+    for (i = 0; i < def->nchannels ; i++) {
+        if (virAsprintf(&def->channels[i]->info.alias, "channel%d", i) < 0)
+            goto no_memory;
+    }
+    if (def->watchdog) {
+        if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0)
+            goto no_memory;
+    }
+
+    return 0;
+
+    no_memory:
+    virReportOOMError(NULL);
+    return -1;
+}
+
+
+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;
+        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 const char *
 qemuNetTypeToHostNet(int type)
 {
@@ -2077,6 +2244,11 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
     uname_normalize(&ut);
 
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
+        qemuAssignDeviceAliases(def);
+    else
+        qemuAssignDiskAliases(def, qemuCmdFlags);
+
     virUUIDFormat(def->uuid, uuid);
 
     /* Migration is very annoying due to wildly varying syntax & capabilities
@@ -2550,6 +2722,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
             ADD_ARG_SPACE;
             if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
+                !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
                 qemuAssignNetNames(def, net) < 0)
                 goto no_memory;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 01dc3c5..37b2730 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5305,63 +5305,13 @@ cleanup:
     return ret;
 }
 
-/* Return the disks name for use in monitor commands */
-static char *qemudDiskDeviceName(const virConnectPtr conn,
-                                 const virDomainDiskDefPtr disk) {
-
-    int busid, devid;
-    int ret;
-    char *devname;
-
-    if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
-        qemudReportError(conn, 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;
-        default:
-            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
-                             _("Unsupported disk name mapping for bus '%s'"),
-                             virDomainDiskBusTypeToString(disk->bus));
-            return NULL;
-    }
-
-    if (ret == -1) {
-        virReportOOMError(conn);
-        return NULL;
-    }
-
-    return devname;
-}
 
 static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
                                            struct qemud_driver *driver,
                                            virDomainObjPtr vm,
-                                           virDomainDeviceDefPtr dev,
-                                           unsigned int qemuCmdFlags)
+                                           virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr origdisk = NULL, newdisk;
-    char *devname = NULL;
     int i;
     int ret;
 
@@ -5383,29 +5333,18 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
         return -1;
     }
 
-    if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
-        if (!(devname = qemudDiskDeviceName(conn, newdisk)))
-            return -1;
-    } else {
-        /* Back compat for no -drive option */
-        if (newdisk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
-            devname = strdup(newdisk->dst);
-        else if (newdisk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-                 STREQ(newdisk->dst, "hdc"))
-            devname = strdup("cdrom");
-        else {
-            qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("Emulator version does not support removable "
-                               "media for device '%s' and target '%s'"),
-                               virDomainDiskDeviceTypeToString(newdisk->device),
-                               newdisk->dst);
-            return -1;
-        }
+    if (!origdisk->info.alias) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("missing disk device alias name for %s"), origdisk->dst);
+        return -1;
+    }
 
-        if (!devname) {
-            virReportOOMError(conn);
-            return -1;
-        }
+    if (origdisk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
+        origdisk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
+        qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("Removable media not supported for %s device"),
+                         virDomainDiskDeviceTypeToString(newdisk->device));
+        return -1;
     }
 
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -5418,9 +5357,11 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
             else if (origdisk->driverType)
                 format = origdisk->driverType;
         }
-        ret = qemuMonitorChangeMedia(priv->mon, devname, newdisk->src, format);
+        ret = qemuMonitorChangeMedia(priv->mon,
+                                     origdisk->info.alias,
+                                     newdisk->src, format);
     } else {
-        ret = qemuMonitorEjectMedia(priv->mon, devname);
+        ret = qemuMonitorEjectMedia(priv->mon, origdisk->info.alias);
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
@@ -5430,7 +5371,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
         newdisk->src = NULL;
         origdisk->type = newdisk->type;
     }
-    VIR_FREE(devname);
 
     return ret;
 }
@@ -5976,7 +5916,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
             if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
                 goto endjob;
 
-            ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev, qemuCmdFlags);
+            ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev);
             break;
 
         case VIR_DOMAIN_DISK_DEVICE_DISK:
@@ -6712,7 +6652,6 @@ qemudDomainBlockStats (virDomainPtr dom,
                        struct _virDomainBlockStats *stats)
 {
     struct qemud_driver *driver = dom->conn->privateData;
-    const char *qemu_dev_name = NULL;
     int i, ret = -1;
     virDomainObjPtr vm;
     virDomainDiskDefPtr disk = NULL;
@@ -6750,14 +6689,16 @@ qemudDomainBlockStats (virDomainPtr dom,
         goto endjob;
     }
 
-    qemu_dev_name = qemudDiskDeviceName(dom->conn, disk);
-    if (!qemu_dev_name)
+    if (!disk->info.alias) {
+        qemudReportError(dom->conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("missing disk device alias name for %s"), disk->dst);
         goto endjob;
+    }
 
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuDomainObjEnterMonitor(vm);
     ret = qemuMonitorGetBlockStatsInfo(priv->mon,
-                                       qemu_dev_name,
+                                       disk->info.alias,
                                        &stats->rd_req,
                                        &stats->rd_bytes,
                                        &stats->wr_req,
@@ -6770,7 +6711,6 @@ endjob:
         vm = NULL;
 
 cleanup:
-    VIR_FREE(qemu_dev_name);
     if (vm)
         virDomainObjUnlock(vm);
     return ret;
-- 
1.6.5.2




More information about the libvir-list mailing list