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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list