[PATCH v2 0/3] qemu: Fix hotplug and blockcopy to VDPA disks

Content-type: text/plain v2: - also deal with blockcopy (requires more helpers) Peter Krempa (3): qemu: process: Extract host setup of disk device into helpers qemu: hotplug: Setup host side of VDPA device for disk hotplug qemu: Setup host side of VDPA device for block copy src/qemu/qemu_block.c | 4 +++ src/qemu/qemu_driver.c | 12 +++++++ src/qemu/qemu_hotplug.c | 3 ++ src/qemu/qemu_process.c | 76 ++++++++++++++++++++++++++++++++++++----- src/qemu/qemu_process.h | 7 ++++ 5 files changed, 93 insertions(+), 9 deletions(-) -- 2.41.0

Currently the code sets up only VDPA backends but will be used later in hotplug code too. This patch also uses normal forward iteration in the loop in qemuProcessPrepareHostStorage as we don't need to remove disks from the disk list at that point. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_process.c | 76 ++++++++++++++++++++++++++++++++++++----- src/qemu/qemu_process.h | 7 ++++ 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 63c0c62a46..1ef032dbd2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6777,6 +6777,69 @@ qemuProcessPrepareHostStorageSourceVDPA(virStorageSource *src, } +/** + * See qemuProcessPrepareHostStorageSourceChain + */ +int +qemuProcessPrepareHostStorageSource(virDomainObj *vm, + virStorageSource *src) +{ + /* connect to any necessary vdpa block devices */ + if (qemuProcessPrepareHostStorageSourceVDPA(src, vm->privateData) < 0) + return -1; + + return 0; +} + + +/** + * qemuProcessPrepareHostStorageSourceChain: + * + * @vm: domain object + * @chain: source chain + * + * Prepare the host side of a disk for use with the VM. Note that this function + * accesses host resources. + */ +int +qemuProcessPrepareHostStorageSourceChain(virDomainObj *vm, + virStorageSource *chain) +{ + virStorageSource *n; + + for (n = chain; virStorageSourceIsBacking(n); n = n->backingStore) { + if (qemuProcessPrepareHostStorageSource(vm, n) < 0) + return -1; + } + + return 0; +} + + +/** + * qemuProcessPrepareHostStorageDisk: + * + * @vm: domain object + * @disk: disk definition object + * + * Prepare the host side of a disk for use with the VM. Note that this function + * accesses host resources. + * + * Note that this function does not call qemuDomainDetermineDiskChain as that is + * needed in qemuProcessPrepareHostStorage to remove disks based on the startup + * policy, thus other callers need to call it explicitly. + */ +int +qemuProcessPrepareHostStorageDisk(virDomainObj *vm, + virDomainDiskDef *disk) +{ + if (qemuProcessPrepareHostStorageSourceChain(vm, disk->src) < 0) + return -1; + + return 0; +} + + static int qemuProcessPrepareHostStorage(virQEMUDriver *driver, virDomainObj *vm, @@ -6813,16 +6876,11 @@ qemuProcessPrepareHostStorage(virQEMUDriver *driver, return -1; } - /* connect to any necessary vdpa block devices */ - for (i = vm->def->ndisks; i > 0; i--) { - size_t idx = i - 1; - virDomainDiskDef *disk = vm->def->disks[idx]; - virStorageSource *src; + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDef *disk = vm->def->disks[i]; - for (src = disk->src; virStorageSourceIsBacking(src); src = src->backingStore) { - if (qemuProcessPrepareHostStorageSourceVDPA(src, vm->privateData) < 0) - return -1; - } + if (qemuProcessPrepareHostStorageDisk(vm, disk) < 0) + return -1; } return 0; diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index ef05b46892..c1ea949215 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -133,6 +133,13 @@ int qemuProcessPrepareHost(virQEMUDriver *driver, virDomainObj *vm, unsigned int flags); +int qemuProcessPrepareHostStorageSource(virDomainObj *vm, + virStorageSource *src); +int qemuProcessPrepareHostStorageSourceChain(virDomainObj *vm, + virStorageSource *chain); +int qemuProcessPrepareHostStorageDisk(virDomainObj *vm, + virDomainDiskDef *disk); + int qemuProcessDeleteThreadContext(virDomainObj *vm); int qemuProcessLaunch(virConnectPtr conn, -- 2.41.0

The code which opens the VDPA device and prepares it for FD passing was not called in the hotplug code path, preventing hotplug of VDPA disks with: error: internal error: argument key 'path' must not have null value Use the new helper qemuProcessPrepareHostStorageDisk to setup the VDPA definition. Closes: https://gitlab.com/libvirt/libvirt/-/issues/539 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 1f7f5bdd26..fec7c4be4e 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1007,6 +1007,9 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver, if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL) < 0) goto cleanup; + if (qemuProcessPrepareHostStorageDisk(vm, disk) < 0) + goto cleanup; + if (qemuHotplugAttachManagedPR(vm, disk->src, VIR_ASYNC_JOB_NONE) < 0) goto cleanup; -- 2.41.0

Setup the VDPA bits of the appropriate part of the image chain for block copy. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 4 ++++ src/qemu/qemu_driver.c | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 41038fb994..42c12a5e9b 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -23,6 +23,7 @@ #include "qemu_domain.h" #include "qemu_alias.h" #include "qemu_security.h" +#include "qemu_process.h" #include "storage_source.h" #include "viralloc.h" @@ -3675,6 +3676,9 @@ qemuBlockPivot(virDomainObj *vm, virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY) && virStorageSourceHasBacking(disk->mirror)) { + if (qemuProcessPrepareHostStorageSourceChain(vm, disk->mirror->backingStore) < 0) + return -1; + if (!(chainattachdata = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->mirror->backingStore))) return -1; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 86da8da777..d00d2a27c6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14290,10 +14290,16 @@ qemuDomainBlockCopyCommon(virDomainObj *vm, if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY)) { g_autoptr(virStorageSource) terminator = virStorageSourceNew(); + if (qemuProcessPrepareHostStorageSource(vm, mirror) < 0) + goto endjob; + if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(mirror, terminator))) goto endjob; } else { + if (qemuProcessPrepareHostStorageSourceChain(vm, mirror) < 0) + goto endjob; + if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(mirror))) goto endjob; } @@ -14308,6 +14314,9 @@ qemuDomainBlockCopyCommon(virDomainObj *vm, if (mirror_shallow) { /* if external backing store is populated we'll need to open it */ if (virStorageSourceHasBacking(mirror)) { + if (qemuProcessPrepareHostStorageSourceChain(vm, mirror->backingStore) < 0) + goto endjob; + if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(mirror->backingStore))) goto endjob; @@ -14321,6 +14330,9 @@ qemuDomainBlockCopyCommon(virDomainObj *vm, mirrorBacking = mirror->backingStore; } + if (qemuProcessPrepareHostStorageSource(vm, mirror) < 0) + goto endjob; + if (!(crdata = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(mirror, mirrorBacking))) goto endjob; -- 2.41.0
participants (1)
-
Peter Krempa