From: Peter Krempa Date: Tue, 26 Nov 2024 08:12:01 +0000 (+0100) Subject: qemu: block: Ensure that is in appropriate state X-Git-Tag: v10.10.0-rc2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=754ca45c454d16ba56b5457fcf7ab42804f6ba8c;p=thirdparty%2Flibvirt.git qemu: block: Ensure that is in appropriate state In contrast to normal backing chain members where qemu does honour the 'auto-read-only' property the 'data-file' nodes are not automatically reopened by qemu. Libvirt now has the infrastructure to reopen them explicitly so use it for all transitions of the 'commit' block job. Signed-off-by: Peter Krempa Reviewed-by: Jiri Denemark --- diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index af317a1f1f..35dca8ee7b 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3696,6 +3696,15 @@ qemuBlockCommit(virDomainObj *vm, false, false, false) < 0) goto cleanup; + if (baseSource->dataFileStore) { + if (qemuDomainStorageSourceAccessAllow(driver, vm, baseSource->dataFileStore, + false, false, false) < 0) + goto cleanup; + + if (qemuBlockReopenReadWrite(vm, baseSource->dataFileStore, asyncJob) < 0) + goto cleanup; + } + if (top_parent && top_parent != disk->src) { /* While top_parent is topmost image, we don't need to remember its * owner as it will be overwritten upon finishing the commit. Hence, @@ -3703,6 +3712,15 @@ qemuBlockCommit(virDomainObj *vm, if (qemuDomainStorageSourceAccessAllow(driver, vm, top_parent, false, false, false) < 0) goto cleanup; + + if (top_parent->dataFileStore) { + if (qemuDomainStorageSourceAccessAllow(driver, vm, top_parent->dataFileStore, + false, false, false) < 0) + goto cleanup; + + if (qemuBlockReopenReadWrite(vm, top_parent->dataFileStore, asyncJob) < 0) + goto cleanup; + } } if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource, @@ -3748,12 +3766,25 @@ qemuBlockCommit(virDomainObj *vm, if (rc < 0 && clean_access) { virErrorPtr orig_err; virErrorPreserveLast(&orig_err); + /* Revert access to read-only, if possible. */ + if (baseSource->dataFileStore) { + qemuDomainStorageSourceAccessAllow(driver, vm, baseSource->dataFileStore, + true, false, false); + qemuBlockReopenReadOnly(vm, baseSource->dataFileStore, asyncJob); + } qemuDomainStorageSourceAccessAllow(driver, vm, baseSource, true, false, false); - if (top_parent && top_parent != disk->src) + if (top_parent && top_parent != disk->src) { + if (top_parent->dataFileStore) { + qemuDomainStorageSourceAccessAllow(driver, vm, top_parent->dataFileStore, + true, false, false); + + qemuBlockReopenReadWrite(vm, top_parent->dataFileStore, asyncJob); + } qemuDomainStorageSourceAccessAllow(driver, vm, top_parent, true, false, false); + } virErrorRestore(&orig_err); } diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index c35321790e..4e77543fa8 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1064,11 +1064,25 @@ qemuBlockJobProcessEventCompletedCommit(virQEMUDriver *driver, return; /* revert access to images */ + if (job->data.commit.base->dataFileStore) { + qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base->dataFileStore, + true, false, false); + qemuBlockReopenReadOnly(vm, job->data.commit.base->dataFileStore, asyncJob); + } qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base, true, false, false); - if (job->data.commit.topparent != job->disk->src) + + if (job->data.commit.topparent != job->disk->src) { + if (job->data.commit.topparent->dataFileStore) { + qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.topparent->dataFileStore, + true, false, false); + + qemuBlockReopenReadWrite(vm, job->data.commit.topparent->dataFileStore, asyncJob); + } qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.topparent, true, false, true); + } + baseparent->backingStore = NULL; job->data.commit.topparent->backingStore = job->data.commit.base;