[PATCH 4/8] qemu: block: Ensure that <dataStore> is in appropriate state

Peter Krempa posted 8 patches 1 month ago
[PATCH 4/8] qemu: block: Ensure that <dataStore> is in appropriate state
Posted by Peter Krempa 1 month ago
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@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