[libvirt] [PATCH 12/12] qemu: driver: allow remote destinations for block copy

Peter Krempa pkrempa at redhat.com
Thu Aug 8 16:00:42 UTC 2019


Now that we support blockdev for qemuDomainBlockCopy we can allow
copying to remote destinations as well.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_driver.c | 47 ++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 261a4167b5..b4eecdd8be 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18195,6 +18195,9 @@ qemuDomainBlockCopyValidateMirror(virStorageSourcePtr mirror,
     int desttype = virStorageSourceGetActualType(mirror);
     struct stat st;

+    if (!virStorageSourceIsLocalStorage(mirror))
+        return 0;
+
     if (virStorageFileAccess(mirror, F_OK) < 0) {
         if (errno != ENOENT) {
             virReportSystemError(errno, "%s",
@@ -18321,6 +18324,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     qemuBlockJobDataPtr job = NULL;
     VIR_AUTOUNREF(virStorageSourcePtr) mirror = mirrorsrc;
     bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+    bool mirror_initialized = false;
     VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
     VIR_AUTOPTR(qemuBlockStorageSourceChainData) crdata = NULL;
     virStorageSourcePtr n;
@@ -18393,15 +18397,19 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     }

     /* Prepare the destination file.  */
-    /* XXX Allow non-file mirror destinations */
-    if (!virStorageSourceIsLocalStorage(mirror)) {
+    if (!blockdev &&
+        !virStorageSourceIsLocalStorage(mirror)) {
         virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                        _("non-file destination not supported yet"));
         goto endjob;
     }

-    if (qemuDomainStorageFileInit(driver, vm, mirror, NULL) < 0)
-        goto endjob;
+    if (virStorageFileSupportsCreate(mirror) == 1) {
+        if (qemuDomainStorageFileInit(driver, vm, mirror, NULL) < 0)
+            goto endjob;
+
+        mirror_initialized = true;
+    }

     if (qemuDomainBlockCopyValidateMirror(mirror, disk->dst, &existing) < 0)
         goto endjob;
@@ -18410,12 +18418,19 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
         if (!mirror_reuse) {
             mirror->format = disk->src->format;
         } else {
-            /* If the user passed the REUSE_EXT flag, then either they
-             * can also pass the RAW flag or use XML to tell us the format.
-             * So if we get here, we assume it is safe for us to probe the
-             * format from the file that we will be using.  */
-            mirror->format = virStorageFileProbeFormat(mirror->path, cfg->user,
-                                                       cfg->group);
+            if (mirror_initialized &&
+                virStorageSourceIsLocalStorage(mirror)) {
+                /* If the user passed the REUSE_EXT flag, then either they
+                 * can also pass the RAW flag or use XML to tell us the format.
+                 * So if we get here, we assume it is safe for us to probe the
+                 * format from the file that we will be using.  */
+                mirror->format = virStorageFileProbeFormat(mirror->path, cfg->user,
+                                                           cfg->group);
+            } else {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("reused mirror destination format must be specified"));
+                goto endjob;
+            }
         }
     }

@@ -18432,12 +18447,14 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     /* pre-create the image file. In case when 'blockdev' is used this is
      * required so that libvirt can properly label the image for access by qemu */
     if (!existing) {
-        if (virStorageFileCreate(mirror) < 0) {
-            virReportSystemError(errno, "%s", _("failed to create copy target"));
-            goto endjob;
-        }
+        if (mirror_initialized) {
+            if (virStorageFileCreate(mirror) < 0) {
+                virReportSystemError(errno, "%s", _("failed to create copy target"));
+                goto endjob;
+            }

-        need_unlink = true;
+            need_unlink = true;
+        }
     }

     if (mirror->format > 0)
-- 
2.21.0




More information about the libvir-list mailing list