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 <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_block.c | 33 ++++++++++++++++++++++++++++++++- src/qemu/qemu_blockjob.c | 16 +++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) 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; -- 2.47.0