Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_hotplug.c | 65 +++++++++++++++++++++++++++++++++++++----
1 file changed, 60 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 3c6c0da3a0..6dbff23aa0 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -605,6 +605,54 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
}
+static int
+qemuDomainStorageSourcePrepareDisk(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk,
+ bool teardown)
+{
+ int rc;
+ bool adjustMemlock = false;
+ bool reattach = false;
+
+ if (!virDomainDefHasNVMeDisk(vm->def) &&
+ !virStorageSourceChainHasNVMe(disk->src))
+ return 0;
+
+ if (teardown) {
+ adjustMemlock = true;
+ reattach = true;
+ goto rollback;
+ }
+
+ /* Tentatively add disk to domain def so that memlock limit can be computed. */
+ vm->def->disks[vm->def->ndisks++] = disk;
+ rc = qemuDomainAdjustMaxMemLock(vm);
+ vm->def->disks[--vm->def->ndisks] = NULL;
+
+ if (rc < 0)
+ return -1;
+
+ adjustMemlock = true;
+
+ if (qemuHostdevPrepareNVMeDevices(driver, vm->def->name, &disk, 1) < 0)
+ return -1;
+
+ reattach = true;
+
+ return 0;
+
+ rollback:
+ if (reattach)
+ qemuHostdevReAttachNVMeDevices(driver, vm->def->name, &disk, 1);
+
+ if (adjustMemlock)
+ qemuDomainAdjustMaxMemLock(vm);
+
+ return 0;
+}
+
+
/**
* qemuDomainAttachDiskGeneric:
*
@@ -623,8 +671,14 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
VIR_AUTOPTR(virJSONValue) corProps = NULL;
VIR_AUTOFREE(char *) corAlias = NULL;
+ if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks + 1) < 0)
+ return -1;
+
+ if (qemuDomainStorageSourcePrepareDisk(driver, vm, disk, false) < 0)
+ return -1;
+
if (qemuDomainStorageSourceChainAccessAllow(driver, vm, disk->src) < 0)
- return -1;
+ goto cleanup;
if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
goto cleanup;
@@ -649,9 +703,6 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
if (!(devstr = qemuBuildDiskDeviceStr(vm->def, disk, 0, priv->qemuCaps)))
goto cleanup;
- if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks + 1) < 0)
- goto cleanup;
-
if (qemuHotplugAttachManagedPR(driver, vm, disk->src, QEMU_ASYNC_JOB_NONE) <
0)
goto cleanup;
@@ -683,8 +734,10 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
ret = 0;
cleanup:
- if (ret < 0)
+ if (ret < 0) {
ignore_value(qemuDomainStorageSourceChainAccessRevoke(driver, vm,
disk->src));
+ qemuDomainStorageSourcePrepareDisk(driver, vm, disk, true);
+ }
qemuDomainSecretDiskDestroy(disk);
VIR_FREE(devstr);
return ret;
@@ -4267,6 +4320,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
dev.data.disk = disk;
ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
+ qemuDomainStorageSourcePrepareDisk(driver, vm, disk, true);
+
if (virStorageSourceChainHasManagedPR(disk->src) &&
qemuHotplugRemoveManagedPR(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
goto cleanup;
--
2.21.0