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(a)redhat.com>
---
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