virDomainDeviceDefPtr dev)
{
virDomainDiskDefPtr disk = dev->data.disk;
+ virDomainDiskDefPtr orig_disk = NULL;
+ virDomainDeviceDefPtr dev_copy = NULL;
+ virDomainDiskDefPtr tmp = NULL;
virCgroupPtr cgroup = NULL;
+ virCapsPtr caps = NULL;
int ret = -1;
if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) {
switch (disk->device) {
case VIR_DOMAIN_DISK_DEVICE_CDROM:
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;
case VIR_DOMAIN_DISK_DEVICE_DISK:
case VIR_DOMAIN_DISK_DEVICE_LUN:
ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
if (cgroup)
virCgroupFree(&cgroup);
+ virObjectUnref(caps);
+ virDomainDeviceDefFree(dev_copy);
return ret;
}
bool force)
{
virDomainDiskDefPtr disk = dev->data.disk;
+ virDomainDiskDefPtr orig_disk = NULL;
+ virDomainDiskDefPtr tmp = NULL;
virCgroupPtr cgroup = NULL;
+ virDomainDeviceDefPtr dev_copy = NULL;
+ virCapsPtr caps = NULL;
int ret = -1;
if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
switch (disk->device) {
case VIR_DOMAIN_DISK_DEVICE_CDROM:
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
- ret = qemuDomainChangeEjectableMedia(driver, vm, disk, force);
- if (ret == 0)
+ 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, force);
+ if (ret == 0) {
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;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
end:
if (cgroup)
virCgroupFree(&cgroup);
+ virObjectUnref(caps);
+ virDomainDeviceDefFree(dev_copy);
return ret;
}
int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
+ virDomainDiskDefPtr origdisk,
bool force)
{
- virDomainDiskDefPtr origdisk = NULL;
- int i;
int ret = -1;
char *driveAlias = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
int retries = CHANGE_MEDIA_RETRIES;
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) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing disk device alias name for %s"), origdisk->dst);