mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
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
This commit is contained in:
parent
a6e7ba9464
commit
053307175c
@ -1460,6 +1460,176 @@ cleanup:
|
|||||||
return tapfd;
|
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 *
|
static const char *
|
||||||
qemuNetTypeToHostNet(int type)
|
qemuNetTypeToHostNet(int type)
|
||||||
{
|
{
|
||||||
@ -2077,6 +2247,11 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
|
|
||||||
uname_normalize(&ut);
|
uname_normalize(&ut);
|
||||||
|
|
||||||
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
|
||||||
|
qemuAssignDeviceAliases(def);
|
||||||
|
else
|
||||||
|
qemuAssignDiskAliases(def, qemuCmdFlags);
|
||||||
|
|
||||||
virUUIDFormat(def->uuid, uuid);
|
virUUIDFormat(def->uuid, uuid);
|
||||||
|
|
||||||
/* Migration is very annoying due to wildly varying syntax & capabilities
|
/* Migration is very annoying due to wildly varying syntax & capabilities
|
||||||
@ -2551,6 +2726,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
|
|
||||||
ADD_ARG_SPACE;
|
ADD_ARG_SPACE;
|
||||||
if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
|
if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
|
||||||
|
!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
|
||||||
qemuAssignNetNames(def, net) < 0)
|
qemuAssignNetNames(def, net) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
@ -5326,63 +5326,13 @@ cleanup:
|
|||||||
return ret;
|
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,
|
static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDeviceDefPtr dev,
|
virDomainDeviceDefPtr dev)
|
||||||
unsigned int qemuCmdFlags)
|
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr origdisk = NULL, newdisk;
|
virDomainDiskDefPtr origdisk = NULL, newdisk;
|
||||||
char *devname = NULL;
|
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -5404,29 +5354,18 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
|
if (!origdisk->info.alias) {
|
||||||
if (!(devname = qemudDiskDeviceName(conn, newdisk)))
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
return -1;
|
_("missing disk device alias name for %s"), origdisk->dst);
|
||||||
} else {
|
return -1;
|
||||||
/* 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 (!devname) {
|
if (origdisk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
|
||||||
virReportOOMError(conn);
|
origdisk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
||||||
return -1;
|
qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
}
|
_("Removable media not supported for %s device"),
|
||||||
|
virDomainDiskDeviceTypeToString(newdisk->device));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
@ -5439,9 +5378,11 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|||||||
else if (origdisk->driverType)
|
else if (origdisk->driverType)
|
||||||
format = origdisk->driverType;
|
format = origdisk->driverType;
|
||||||
}
|
}
|
||||||
ret = qemuMonitorChangeMedia(priv->mon, devname, newdisk->src, format);
|
ret = qemuMonitorChangeMedia(priv->mon,
|
||||||
|
origdisk->info.alias,
|
||||||
|
newdisk->src, format);
|
||||||
} else {
|
} else {
|
||||||
ret = qemuMonitorEjectMedia(priv->mon, devname);
|
ret = qemuMonitorEjectMedia(priv->mon, origdisk->info.alias);
|
||||||
}
|
}
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
@ -5451,7 +5392,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
|
|||||||
newdisk->src = NULL;
|
newdisk->src = NULL;
|
||||||
origdisk->type = newdisk->type;
|
origdisk->type = newdisk->type;
|
||||||
}
|
}
|
||||||
VIR_FREE(devname);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -5997,7 +5937,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
|
|||||||
if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
|
if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev, qemuCmdFlags);
|
ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
||||||
@ -6733,7 +6673,6 @@ qemudDomainBlockStats (virDomainPtr dom,
|
|||||||
struct _virDomainBlockStats *stats)
|
struct _virDomainBlockStats *stats)
|
||||||
{
|
{
|
||||||
struct qemud_driver *driver = dom->conn->privateData;
|
struct qemud_driver *driver = dom->conn->privateData;
|
||||||
const char *qemu_dev_name = NULL;
|
|
||||||
int i, ret = -1;
|
int i, ret = -1;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
virDomainDiskDefPtr disk = NULL;
|
virDomainDiskDefPtr disk = NULL;
|
||||||
@ -6771,14 +6710,16 @@ qemudDomainBlockStats (virDomainPtr dom,
|
|||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_dev_name = qemudDiskDeviceName(dom->conn, disk);
|
if (!disk->info.alias) {
|
||||||
if (!qemu_dev_name)
|
qemudReportError(dom->conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("missing disk device alias name for %s"), disk->dst);
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
}
|
||||||
|
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
qemuDomainObjEnterMonitor(vm);
|
qemuDomainObjEnterMonitor(vm);
|
||||||
ret = qemuMonitorGetBlockStatsInfo(priv->mon,
|
ret = qemuMonitorGetBlockStatsInfo(priv->mon,
|
||||||
qemu_dev_name,
|
disk->info.alias,
|
||||||
&stats->rd_req,
|
&stats->rd_req,
|
||||||
&stats->rd_bytes,
|
&stats->rd_bytes,
|
||||||
&stats->wr_req,
|
&stats->wr_req,
|
||||||
@ -6791,7 +6732,6 @@ endjob:
|
|||||||
vm = NULL;
|
vm = NULL;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(qemu_dev_name);
|
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user