]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: Add support for networked disks for block pull/block rebase
authorPeter Krempa <pkrempa@redhat.com>
Mon, 28 Apr 2014 13:39:19 +0000 (15:39 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 8 Jul 2014 09:55:26 +0000 (11:55 +0200)
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_driver.c

index fa5f9c34b832ef1b95c29aa2899f51e25c1d93be..e1425e158cf5ef38fc327b2bcffdb1913ec1c5d3 100644 (file)
@@ -15046,6 +15046,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",
@@ -15053,6 +15055,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;
@@ -15113,10 +15122,35 @@ 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_CHANGE_BACKING_FILE)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("this QEMU binary doesn't support relative "
+                                 "block pull/rebase"));
+                goto endjob;
+            }
+
+            if (virStorageFileGetRelativeBackingPath(disk->src->backingStore,
+                                                     baseSource,
+                                                     &backingPath) < 0)
+                goto endjob;
+
+
+            if (!backingPath) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("can't keep relative backing relationship"));
+                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;
@@ -15191,6 +15225,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
     }
 
  cleanup:
+    VIR_FREE(basePath);
+    VIR_FREE(backingPath);
     VIR_FREE(device);
     if (vm)
         virObjectUnlock(vm);
@@ -15441,7 +15477,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;