mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
qemu: Remove the shared disk entry if the operation is ejecting or updating
For both AttachDevice and UpdateDevice APIs, if the disk device is 'cdrom' or 'floppy', the operations could be ejecting, updating, and inserting. For either ejecting or updating, the shared disk entry of the original disk src has to be removed, because it's not useful anymore. And since the original disk def will be changed, new disk def passed as argument will be free'ed in qemuDomainChangeEjectableMedia, so we need to copy the orignal disk def before qemuDomainChangeEjectableMedia, to use it for qemuRemoveSharedDisk.
This commit is contained in:
parent
0db7ff59cc
commit
d0172d2b1b
@ -3359,6 +3359,26 @@ virDomainDiskFindControllerModel(virDomainDefPtr def,
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virDomainDiskDefPtr
|
||||||
|
virDomainDiskFindByBusAndDst(virDomainDefPtr def,
|
||||||
|
int bus,
|
||||||
|
char *dst)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0 ; i < def->ndisks ; i++) {
|
||||||
|
if (def->disks[i]->bus == bus &&
|
||||||
|
STREQ(def->disks[i]->dst, dst)) {
|
||||||
|
return def->disks[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
|
virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
|
||||||
{
|
{
|
||||||
|
@ -1936,6 +1936,9 @@ void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
|
|||||||
int virDomainDiskFindControllerModel(virDomainDefPtr def,
|
int virDomainDiskFindControllerModel(virDomainDefPtr def,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
int controllerType);
|
int controllerType);
|
||||||
|
virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def,
|
||||||
|
int bus,
|
||||||
|
char *dst);
|
||||||
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
||||||
void virDomainFSDefFree(virDomainFSDefPtr def);
|
void virDomainFSDefFree(virDomainFSDefPtr def);
|
||||||
void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
|
void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
|
||||||
|
@ -143,6 +143,7 @@ virDomainDiskDefGetSecurityLabelDef;
|
|||||||
virDomainDiskDeviceTypeToString;
|
virDomainDiskDeviceTypeToString;
|
||||||
virDomainDiskErrorPolicyTypeFromString;
|
virDomainDiskErrorPolicyTypeFromString;
|
||||||
virDomainDiskErrorPolicyTypeToString;
|
virDomainDiskErrorPolicyTypeToString;
|
||||||
|
virDomainDiskFindByBusAndDst;
|
||||||
virDomainDiskFindControllerModel;
|
virDomainDiskFindControllerModel;
|
||||||
virDomainDiskGeometryTransTypeFromString;
|
virDomainDiskGeometryTransTypeFromString;
|
||||||
virDomainDiskGeometryTransTypeToString;
|
virDomainDiskGeometryTransTypeToString;
|
||||||
|
@ -5704,7 +5704,11 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
|
|||||||
virDomainDeviceDefPtr dev)
|
virDomainDeviceDefPtr dev)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr disk = dev->data.disk;
|
virDomainDiskDefPtr disk = dev->data.disk;
|
||||||
|
virDomainDiskDefPtr orig_disk = NULL;
|
||||||
|
virDomainDeviceDefPtr dev_copy = NULL;
|
||||||
|
virDomainDiskDefPtr tmp = NULL;
|
||||||
virCgroupPtr cgroup = NULL;
|
virCgroupPtr cgroup = NULL;
|
||||||
|
virCapsPtr caps = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) {
|
if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) {
|
||||||
@ -5737,7 +5741,37 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
|
|||||||
switch (disk->device) {
|
switch (disk->device) {
|
||||||
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
||||||
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
||||||
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, false);
|
if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def,
|
||||||
|
disk->bus, disk->dst))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("No device with bus '%s' and target '%s'"),
|
||||||
|
virDomainDiskBusTypeToString(disk->bus),
|
||||||
|
disk->dst);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
tmp = dev->data.disk;
|
||||||
|
dev->data.disk = orig_disk;
|
||||||
|
|
||||||
|
if (!(dev_copy = virDomainDeviceDefCopy(caps, vm->def, dev))) {
|
||||||
|
dev->data.disk = tmp;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
dev->data.disk = tmp;
|
||||||
|
|
||||||
|
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, false);
|
||||||
|
|
||||||
|
/* Need to remove the shared disk entry for the original disk src
|
||||||
|
* if the operation is either ejecting or updating.
|
||||||
|
*/
|
||||||
|
if (ret == 0 &&
|
||||||
|
orig_disk->src &&
|
||||||
|
STRNEQ_NULLABLE(orig_disk->src, disk->src))
|
||||||
|
ignore_value(qemuRemoveSharedDisk(driver, dev_copy->data.disk,
|
||||||
|
vm->def->name));
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
||||||
case VIR_DOMAIN_DISK_DEVICE_LUN:
|
case VIR_DOMAIN_DISK_DEVICE_LUN:
|
||||||
@ -5777,6 +5811,8 @@ end:
|
|||||||
ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
|
ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
|
||||||
if (cgroup)
|
if (cgroup)
|
||||||
virCgroupFree(&cgroup);
|
virCgroupFree(&cgroup);
|
||||||
|
virObjectUnref(caps);
|
||||||
|
virDomainDeviceDefFree(dev_copy);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5955,7 +5991,11 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
|
|||||||
bool force)
|
bool force)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr disk = dev->data.disk;
|
virDomainDiskDefPtr disk = dev->data.disk;
|
||||||
|
virDomainDiskDefPtr orig_disk = NULL;
|
||||||
|
virDomainDiskDefPtr tmp = NULL;
|
||||||
virCgroupPtr cgroup = NULL;
|
virCgroupPtr cgroup = NULL;
|
||||||
|
virDomainDeviceDefPtr dev_copy = NULL;
|
||||||
|
virCapsPtr caps = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
|
if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
|
||||||
@ -5976,9 +6016,37 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
|
|||||||
switch (disk->device) {
|
switch (disk->device) {
|
||||||
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
||||||
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
||||||
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, force);
|
if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def,
|
||||||
if (ret == 0)
|
disk->bus, disk->dst))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("No device with bus '%s' and target '%s'"),
|
||||||
|
virDomainDiskBusTypeToString(disk->bus),
|
||||||
|
disk->dst);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
tmp = dev->data.disk;
|
||||||
|
dev->data.disk = orig_disk;
|
||||||
|
|
||||||
|
if (!(dev_copy = virDomainDeviceDefCopy(caps, vm->def, dev))) {
|
||||||
|
dev->data.disk = tmp;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
dev->data.disk = tmp;
|
||||||
|
|
||||||
|
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, force);
|
||||||
|
if (ret == 0) {
|
||||||
dev->data.disk = NULL;
|
dev->data.disk = NULL;
|
||||||
|
/* Need to remove the shared disk entry for the original
|
||||||
|
* disk src if the operation is either ejecting or updating.
|
||||||
|
*/
|
||||||
|
if (orig_disk->src && STRNEQ_NULLABLE(orig_disk->src, disk->src))
|
||||||
|
ignore_value(qemuRemoveSharedDisk(driver, dev_copy->data.disk,
|
||||||
|
vm->def->name));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
@ -5995,6 +6063,8 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
|
|||||||
end:
|
end:
|
||||||
if (cgroup)
|
if (cgroup)
|
||||||
virCgroupFree(&cgroup);
|
virCgroupFree(&cgroup);
|
||||||
|
virObjectUnref(caps);
|
||||||
|
virDomainDeviceDefFree(dev_copy);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,32 +53,15 @@
|
|||||||
int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
|
virDomainDiskDefPtr origdisk,
|
||||||
bool force)
|
bool force)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr origdisk = NULL;
|
|
||||||
int i;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char *driveAlias = NULL;
|
char *driveAlias = NULL;
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
int retries = CHANGE_MEDIA_RETRIES;
|
int retries = CHANGE_MEDIA_RETRIES;
|
||||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
||||||
if (vm->def->disks[i]->bus == disk->bus &&
|
|
||||||
STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
|
||||||
origdisk = vm->def->disks[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!origdisk) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("No device with bus '%s' and target '%s'"),
|
|
||||||
virDomainDiskBusTypeToString(disk->bus),
|
|
||||||
disk->dst);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!origdisk->info.alias) {
|
if (!origdisk->info.alias) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("missing disk device alias name for %s"), origdisk->dst);
|
_("missing disk device alias name for %s"), origdisk->dst);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
|
virDomainDiskDefPtr orig_disk,
|
||||||
bool force);
|
bool force);
|
||||||
int qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
|
int qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user