diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ef87a6ef05..91ac3640d3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7600,7 +7600,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, switch ((virDomainDeviceType)dev->type) { case VIR_DOMAIN_DEVICE_DISK: qemuDomainObjCheckDiskTaint(driver, vm, dev->data.disk, NULL); - ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev, false); + ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev); if (!ret) { alias = dev->data.disk->info.alias; dev->data.disk = NULL; @@ -7851,6 +7851,12 @@ qemuDomainChangeDiskLive(virDomainObjPtr vm, 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, @@ -7879,8 +7885,18 @@ qemuDomainChangeDiskLive(virDomainObjPtr vm, goto cleanup; } - if (qemuDomainAttachDeviceDiskLive(driver, vm, dev, force) < 0) + /* 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)); + goto cleanup; + } + + dev->data.disk->src = NULL; } orig_disk->startupPolicy = dev->data.disk->startupPolicy; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index ccf3336633..86afda636e 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -722,7 +722,7 @@ qemuDomainChangeMediaBlockdev(virQEMUDriverPtr driver, * * Returns 0 on success, -1 on error and reports libvirt error */ -static int +int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, @@ -1049,22 +1049,10 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver, } -/** - * qemuDomainAttachDeviceDiskLive: - * @driver: qemu driver struct - * @vm: domain object - * @dev: device to attach (expected type is DISK) - * @forceMediaChange: Forcibly open the drive if changing media - * - * Attach a new disk or in case of cdroms/floppies change the media in the drive. - * This function handles all the necessary steps to attach a new storage source - * to the VM. If @forceMediaChange is true the drive is opened forcibly. - */ int qemuDomainAttachDeviceDiskLive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - bool forceMediaChange) + virDomainDeviceDefPtr dev) { size_t i; virDomainDiskDefPtr disk = dev->data.disk; @@ -1098,7 +1086,7 @@ qemuDomainAttachDeviceDiskLive(virQEMUDriverPtr driver, } if (qemuDomainChangeEjectableMedia(driver, vm, orig_disk, - disk->src, forceMediaChange) < 0) + disk->src, false) < 0) goto cleanup; disk->src = NULL; diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index c085c45082..0297e42a98 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -28,6 +28,12 @@ # include "qemu_domain.h" # include "domain_conf.h" +int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk, + virStorageSourcePtr newsrc, + bool force); + void qemuDomainDelTLSObjects(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuDomainAsyncJob asyncJob, @@ -54,8 +60,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver, virDomainControllerDefPtr controller); int qemuDomainAttachDeviceDiskLive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - bool forceMediaChange); + virDomainDeviceDefPtr dev); int qemuDomainAttachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainNetDefPtr net); diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index e0e248556f..5b1e0db104 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -120,7 +120,7 @@ testQemuHotplugAttach(virDomainObjPtr vm, /* conn in only used for storage pool and secrets lookup so as long * as we don't use any of them, passing NULL should be safe */ - ret = qemuDomainAttachDeviceDiskLive(&driver, vm, dev, false); + ret = qemuDomainAttachDeviceDiskLive(&driver, vm, dev); break; case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr);