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