virDomainDeviceDef oldDev = { .type = dev->type };
int ret = -1;
- if (virDomainDiskTranslateSourcePool(disk) < 0)
- goto cleanup;
-
- if (qemuDomainDetermineDiskChain(driver, vm, disk, true) < 0)
- goto cleanup;
-
if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def,
disk->bus, disk->dst))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
goto cleanup;
}
- /* Add the new disk src into shared disk hash table */
- if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
- goto cleanup;
-
if (qemuDomainChangeEjectableMedia(driver, vm, orig_disk,
- dev->data.disk->src, force) < 0) {
- ignore_value(qemuRemoveSharedDisk(driver, dev->data.disk,
- vm->def->name));
+ dev->data.disk->src, force) < 0)
goto cleanup;
- }
dev->data.disk->src = NULL;
}
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
qemuDomainObjPrivatePtr priv = vm->privateData;
virStorageSourcePtr oldsrc = disk->src;
+ bool sharedAdded = false;
int ret = -1;
int rc;
disk->src = newsrc;
+ if (virDomainDiskTranslateSourcePool(disk) < 0)
+ goto cleanup;
+
+ if (qemuAddSharedDisk(driver, disk, vm->def->name) < 0)
+ goto cleanup;
+
+ sharedAdded = true;
+
+ if (qemuDomainDetermineDiskChain(driver, vm, disk, true) < 0)
+ goto cleanup;
+
if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0)
goto cleanup;
virDomainAuditDisk(vm, oldsrc, newsrc, "update", rc >= 0);
- if (rc < 0) {
- ignore_value(qemuHotplugPrepareDiskAccess(driver, vm, disk, newsrc, true));
+ if (rc < 0)
goto cleanup;
- }
/* remove the old source from shared device list */
disk->src = oldsrc;
oldsrc = NULL;
disk->src = newsrc;
- ignore_value(qemuHotplugRemoveManagedPR(driver, vm, QEMU_ASYNC_JOB_NONE));
-
ret = 0;
cleanup:
+ /* undo changes to the new disk */
+ if (ret < 0) {
+ if (sharedAdded)
+ ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
+
+ ignore_value(qemuHotplugPrepareDiskAccess(driver, vm, disk, newsrc, true));
+ }
+
+ /* remove PR manager object if unneeded */
+ ignore_value(qemuHotplugRemoveManagedPR(driver, vm, QEMU_ASYNC_JOB_NONE));
+
+ /* revert old image do the disk definition */
if (oldsrc)
disk->src = oldsrc;
{
size_t i;
virDomainDiskDefPtr disk = dev->data.disk;
- virDomainDiskDefPtr orig_disk = NULL;
int ret = -1;
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM ||
+ disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cdrom/floppy device hotplug isn't supported"));
+ return -1;
+ }
+
if (virDomainDiskTranslateSourcePool(disk) < 0)
goto cleanup;
goto cleanup;
switch ((virDomainDiskDevice) disk->device) {
- case VIR_DOMAIN_DISK_DEVICE_CDROM:
- case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
- if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def,
- disk->bus, disk->dst))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("No device with bus '%s' and target '%s'. "
- "cdrom and floppy device hotplug isn't supported "
- "by libvirt"),
- virDomainDiskBusTypeToString(disk->bus),
- disk->dst);
- goto cleanup;
- }
-
- if (qemuDomainChangeEjectableMedia(driver, vm, orig_disk,
- disk->src, false) < 0)
- goto cleanup;
-
- disk->src = NULL;
- ret = 0;
- break;
-
case VIR_DOMAIN_DISK_DEVICE_DISK:
case VIR_DOMAIN_DISK_DEVICE_LUN:
for (i = 0; i < vm->def->ndisks; i++) {
}
break;
+ case VIR_DOMAIN_DISK_DEVICE_CDROM:
+ case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
case VIR_DOMAIN_DISK_DEVICE_LAST:
break;
}
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
+ virDomainDiskDefPtr disk = dev->data.disk;
+ virDomainDiskDefPtr orig_disk = NULL;
+
+ /* this API overloads media change semantics on disk hotplug
+ * for devices supporting media changes */
+ if ((disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM ||
+ disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) &&
+ (orig_disk = virDomainDiskFindByBusAndDst(vm->def, disk->bus, disk->dst))) {
+ if (qemuDomainChangeEjectableMedia(driver, vm, orig_disk,
+ disk->src, false) < 0)
+ return -1;
+
+ disk->src = NULL;
+ return 0;
+ }
+
return qemuDomainAttachDeviceDiskLiveInternal(driver, vm, dev);
}