Now that we are able to select images from the backing chain via indexed
access we should also convert possible network sources to
qemu-compatible strings before passing them to qemu.
---
 src/qemu/qemu_capabilities.c |  5 ++++-
 src/qemu/qemu_capabilities.h |  1 +
 src/qemu/qemu_driver.c       | 44 ++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ccd9a93..7c5c989 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -257,6 +257,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
               "host-pci-multidomain",
               "msg-timestamp",
               "block-commit-backing-name",
+              "block-stream-backing-name",
     );


@@ -3102,8 +3103,10 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
         goto cleanup;

     /* TODO, WIP: We shall test this */
-    if (qemuCaps->version >= 2000000)
+    if (qemuCaps->version >= 2000000) {
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKPULL_BACKING_NAME);
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKSTREAM_BACKING_NAME);
+    }

     ret = 0;
  cleanup:
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 773298d..3938f42 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -207,6 +207,7 @@ enum virQEMUCapsFlags {
     QEMU_CAPS_HOST_PCI_MULTIDOMAIN = 166, /* support domain > 0 in host pci 
address */
     QEMU_CAPS_MSG_TIMESTAMP      = 167, /* -msg timestamp */
     QEMU_CAPS_BLOCKPULL_BACKING_NAME = 168, /* support for backing name 
tweaking */
+    QEMU_CAPS_BLOCKSTREAM_BACKING_NAME = 169, /* support for backing name 
tweaking */

     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1e7ad1a..19a6763 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14969,6 +14969,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
     virDomainDiskDefPtr disk;
     virStorageSourcePtr baseSource = NULL;
     unsigned int baseIndex = 0;
+    char *basePath = NULL;
+    char *backingPath = NULL;

     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -14976,6 +14978,13 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
         goto cleanup;
     }

+    if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE && !base) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("flag VIR_DOMAIN_BLOCK_REBASE_RELATIVE is valid only "
+                         " with non-null base "));
+        goto cleanup;
+    }
+
     priv = vm->privateData;
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC)) {
         async = true;
@@ -15037,10 +15046,34 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
                                                   base, baseIndex, NULL))))
         goto endjob;

+    if (baseSource) {
+        if (qemuGetDriveSourceString(baseSource, NULL, &basePath) < 0)
+            goto endjob;
+
+        if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE) {
+            if (!virQEMUCapsGet(priv->qemuCaps, 
QEMU_CAPS_BLOCKSTREAM_BACKING_NAME)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("this QEMU binary doesn't support relative "
+                                 "block pull/rebase"));
+                goto endjob;
+            }
+
+            if (disk->src.backingStore == baseSource) {
+                if (baseSource->backingRelative &&
+                    VIR_STRDUP(backingPath, baseSource->relPath) < 0)
+                    goto endjob;
+            } else {
+                if 
(virStorageFileGetRelativeBackingPath(disk->src.backingStore,
+                                                         baseSource,
+                                                         &backingPath) < 0)
+                    goto endjob;
+            }
+        }
+    }
+
     qemuDomainObjEnterMonitor(driver, vm);
-    ret = qemuMonitorBlockJob(priv->mon, device,
-                              baseIndex ? baseSource->path : base,
-                              NULL, bandwidth, info, mode, async);
+    ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
+                              bandwidth, info, mode, async);
     qemuDomainObjExitMonitor(driver, vm);
     if (ret < 0)
         goto endjob;
@@ -15110,6 +15143,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
     }

  cleanup:
+    VIR_FREE(basePath);
+    VIR_FREE(backingPath);
     VIR_FREE(device);
     if (vm)
         virObjectUnlock(vm);
@@ -15350,7 +15385,8 @@ qemuDomainBlockRebase(virDomainPtr dom, const char 
*path, const char *base,
     virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
                   VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
                   VIR_DOMAIN_BLOCK_REBASE_COPY |
-                  VIR_DOMAIN_BLOCK_REBASE_COPY_RAW, -1);
+                  VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
+                  VIR_DOMAIN_BLOCK_REBASE_RELATIVE, -1);

     if (!(vm = qemuDomObjFromDomain(dom)))
         return -1;
-- 
1.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to