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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user