[libvirt PATCH 6/6] qemu: block: extend pull job completion with 'top' handling

Pavel Mores pmores at redhat.com
Wed Mar 4 10:12:40 UTC 2020


'top' handling basically requires two changes: besides the obvious
adjustments to the code that fixes our backing chains (for both
active and inactive configuration) after a pull, we need to make
the top image read-only again if it's not identical with the
active layer (it had to be made writable before submitting QMP
block-stream to allow QEMU to fix the backing chain in top's
qcow2).

Signed-off-by: Pavel Mores <pmores at redhat.com>
---
 src/qemu/qemu_blockjob.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index e19a2ad76b..2e53821d43 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -962,6 +962,7 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver,
     virDomainDiskDefPtr cfgdisk = NULL;
     virStorageSourcePtr cfgbase = NULL;
     virStorageSourcePtr cfgbaseparent = NULL;
+    virStorageSourcePtr cfgtop = NULL;
     virStorageSourcePtr n;
     virStorageSourcePtr tmp;
 
@@ -994,16 +995,40 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver,
         }
     }
 
-    tmp = job->disk->src->backingStore;
-    job->disk->src->backingStore = job->data.pull.base;
+    if (job->data.pull.top) {
+        cfgtop = cfgdisk->src->backingStore;
+        for (n = job->disk->src->backingStore; n && n != job->data.pull.top; n = n->backingStore) {
+            if (cfgtop)
+                cfgtop = cfgtop->backingStore;
+        }
+    }
+
+    if (job->data.pull.top && job->data.pull.top != job->disk->src) {
+        if (qemuDomainStorageSourceAccessAllow(driver, vm, job->data.pull.top, true, false) < 0) {
+            virReportError(VIR_ERR_ACCESS_DENIED, "can't reset 'top' to read-only");
+        }
+    }
+
+    if (job->data.pull.top) {
+        tmp = job->data.pull.top->backingStore;
+        job->data.pull.top->backingStore = job->data.pull.base;
+    } else {
+        tmp = job->disk->src->backingStore;
+        job->disk->src->backingStore = job->data.pull.base;
+    }
     if (baseparent)
         baseparent->backingStore = NULL;
     qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, tmp);
     virObjectUnref(tmp);
 
     if (cfgdisk) {
-        tmp = cfgdisk->src->backingStore;
-        cfgdisk->src->backingStore = cfgbase;
+        if (job->data.pull.top) {
+            tmp = cfgtop->backingStore;
+            cfgtop->backingStore = cfgbase;
+        } else {
+            tmp = cfgdisk->src->backingStore;
+            cfgdisk->src->backingStore = cfgbase;
+        }
         if (cfgbaseparent)
             cfgbaseparent->backingStore = NULL;
         virObjectUnref(tmp);
-- 
2.24.1




More information about the libvir-list mailing list