]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: block: Support VIR_DOMAIN_BLOCK_COMMIT/PULL/REBASE_RELATIVE with blockdev
authorPeter Krempa <pkrempa@redhat.com>
Mon, 30 Mar 2020 09:18:32 +0000 (11:18 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 30 Mar 2020 14:28:48 +0000 (16:28 +0200)
Preservation of the relative relationship requires us to load the
backing store strings from the disk images. With blockdev we stopped
detecting the backing chain if it's specified in the XML so the relative
links were not loaded at that point. To preserve the functionality from
the pre-blockdev without accessing the backing chain unnecessarily
during VM startup we must refresh the relative links when relative
block commit or block pull is requested.

https://bugzilla.redhat.com/show_bug.cgi?id=1818655

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_block.c
src/qemu/qemu_block.h
src/qemu/qemu_driver.c

index 648c3f10267bfc9cb9ca22710b68dc52005d1f46..fe5a0a6a7d88cd5004a3a90da2495034573b0ecd 100644 (file)
@@ -3378,3 +3378,49 @@ qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src)
 
     return virBufferContentAndReset(&buf);
 }
+
+
+/**
+ * qemuBlockUpdateRelativeBacking:
+ * @vm: domain object
+ * @src: starting point of the update
+ * @topsrc: top level image in the backing chain (used to get security label)
+ *
+ * Reload data necessary for keeping backing store links starting from @src
+ * relative.
+ */
+int
+qemuBlockUpdateRelativeBacking(virDomainObjPtr vm,
+                               virStorageSourcePtr src,
+                               virStorageSourcePtr topsrc)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverPtr driver = priv->driver;
+    virStorageSourcePtr n;
+
+    for (n = src; virStorageSourceHasBacking(n); n = n->backingStore) {
+        g_autofree char *backingStoreStr = NULL;
+        int rc;
+
+        if (n->backingStore->relPath)
+            break;
+
+        if (!virStorageFileSupportsBackingChainTraversal(n))
+            continue;
+
+        if (qemuDomainStorageFileInit(driver, vm, n, topsrc) < 0)
+            return -1;
+
+        rc = virStorageFileGetBackingStoreStr(n, &backingStoreStr);
+
+        virStorageFileDeinit(n);
+
+        if (rc < 0)
+            return rc;
+
+        if (backingStoreStr && virStorageIsRelative(backingStoreStr))
+            n->backingStore->relPath = g_steal_pointer(&backingStoreStr);
+    }
+
+    return 0;
+}
index 8b57ffd8a593390fc47ef91044b63b0a25d72ee6..2ad2ce1a1f043750929980bc93d04a7dd5276f88 100644 (file)
@@ -261,3 +261,8 @@ qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src);
 
 char *
 qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src);
+
+int
+qemuBlockUpdateRelativeBacking(virDomainObjPtr vm,
+                               virStorageSourcePtr src,
+                               virStorageSourcePtr topsrc);
index 570dc059e9ca24ea6cfc1b9925f134b40d99a1a1..ae38b9c914b68e87d6ccd3c3a7397a6b015fa159 100644 (file)
@@ -17466,6 +17466,10 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
                 goto endjob;
             }
 
+            if (blockdev &&
+                qemuBlockUpdateRelativeBacking(vm, disk->src, disk->src) < 0)
+                goto endjob;
+
             if (virStorageFileGetRelativeBackingPath(disk->src->backingStore,
                                                      baseSource,
                                                      &backingPath) < 0)
@@ -18593,6 +18597,10 @@ qemuDomainBlockCommit(virDomainPtr dom,
             goto endjob;
         }
 
+        if (blockdev && top_parent &&
+            qemuBlockUpdateRelativeBacking(vm, top_parent, disk->src) < 0)
+            goto endjob;
+
         if (virStorageFileGetRelativeBackingPath(topSource, baseSource,
                                                  &backingPath) < 0)
             goto endjob;