提交 05330717 编写于 作者: D Daniel P. Berrange

Assign device aliases for all devices at startup

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
上级 a6e7ba94
......@@ -1460,6 +1460,176 @@ 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;
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 const char *
qemuNetTypeToHostNet(int type)
{
......@@ -2077,6 +2247,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
......@@ -2551,6 +2726,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;
......
......@@ -5326,63 +5326,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;
......@@ -5404,29 +5354,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;
......@@ -5439,9 +5378,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);
......@@ -5451,7 +5392,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
newdisk->src = NULL;
origdisk->type = newdisk->type;
}
VIR_FREE(devname);
return ret;
}
......@@ -5997,7 +5937,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:
......@@ -6733,7 +6673,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;
......@@ -6771,14 +6710,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,
......@@ -6791,7 +6732,6 @@ endjob:
vm = NULL;
cleanup:
VIR_FREE(qemu_dev_name);
if (vm)
virDomainObjUnlock(vm);
return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册