[PATCH 0/2] qemu: Fix --keep-relative for block-commit/pull with blockdev

Peter Krempa (2): qemu: block: Support VIR_DOMAIN_BLOCK_COMMIT/PULL/REBASE_RELATIVE with blockdev qemuDomainSnapshotDiskPrepareOne: Don't load the relative path with blockdev src/qemu/qemu_block.c | 46 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 5 +++++ src/qemu/qemu_driver.c | 13 ++++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) -- 2.24.1

Preservation of the relative relationship requires us to load the backing store strings from the disk images. With blockdev we stopped detecting the backing chain if it's specified in the XML so the relative links were not loaded at that point. To preserve the functionality from the pre-blockdev without accessing the backing chain unnecessarily during VM startup we must refresh the relative links when relative block commit or block pull is requested. https://bugzilla.redhat.com/show_bug.cgi?id=1818655 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 46 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 5 +++++ src/qemu/qemu_driver.c | 8 ++++++++ 3 files changed, 59 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 648c3f1026..fe5a0a6a7d 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3378,3 +3378,49 @@ qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src) return virBufferContentAndReset(&buf); } + + +/** + * qemuBlockUpdateRelativeBacking: + * @vm: domain object + * @src: starting point of the update + * @topsrc: top level image in the backing chain (used to get security label) + * + * Reload data necessary for keeping backing store links starting from @src + * relative. + */ +int +qemuBlockUpdateRelativeBacking(virDomainObjPtr vm, + virStorageSourcePtr src, + virStorageSourcePtr topsrc) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virQEMUDriverPtr driver = priv->driver; + virStorageSourcePtr n; + + for (n = src; virStorageSourceHasBacking(n); n = n->backingStore) { + g_autofree char *backingStoreStr = NULL; + int rc; + + if (n->backingStore->relPath) + break; + + if (!virStorageFileSupportsBackingChainTraversal(n)) + continue; + + if (qemuDomainStorageFileInit(driver, vm, n, topsrc) < 0) + return -1; + + rc = virStorageFileGetBackingStoreStr(n, &backingStoreStr); + + virStorageFileDeinit(n); + + if (rc < 0) + return rc; + + if (backingStoreStr && virStorageIsRelative(backingStoreStr)) + n->backingStore->relPath = g_steal_pointer(&backingStoreStr); + } + + return 0; +} diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 8b57ffd8a5..2ad2ce1a1f 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -261,3 +261,8 @@ qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src); char * qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src); + +int +qemuBlockUpdateRelativeBacking(virDomainObjPtr vm, + virStorageSourcePtr src, + virStorageSourcePtr topsrc); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 570dc059e9..ae38b9c914 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17466,6 +17466,10 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm, goto endjob; } + if (blockdev && + qemuBlockUpdateRelativeBacking(vm, disk->src, disk->src) < 0) + goto endjob; + if (virStorageFileGetRelativeBackingPath(disk->src->backingStore, baseSource, &backingPath) < 0) @@ -18593,6 +18597,10 @@ qemuDomainBlockCommit(virDomainPtr dom, goto endjob; } + if (blockdev && top_parent && + qemuBlockUpdateRelativeBacking(vm, top_parent, disk->src) < 0) + goto endjob; + if (virStorageFileGetRelativeBackingPath(topSource, baseSource, &backingPath) < 0) goto endjob; -- 2.24.1

Since we are refreshing the relative paths when doing the blockjobs we no longer need to load them upfront when doing the snapshot. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ae38b9c914..78024614cf 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15167,8 +15167,9 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver, dd->initialized = true; /* relative backing store paths need to be updated so that relative - * block commit still works */ - if (reuse) { + * block commit still works. With blockdev we must update it when doing + * commit anyways so it's skipped here */ + if (reuse && !blockdev) { if (supportsBacking) { g_autofree char *backingStoreStr = NULL; -- 2.24.1

On a Monday in 2020, Peter Krempa wrote:
Peter Krempa (2): qemu: block: Support VIR_DOMAIN_BLOCK_COMMIT/PULL/REBASE_RELATIVE with blockdev qemuDomainSnapshotDiskPrepareOne: Don't load the relative path with blockdev
src/qemu/qemu_block.c | 46 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 5 +++++ src/qemu/qemu_driver.c | 13 ++++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa