]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: copy: Accept 'format' parameter when copying to a non-existing img
authorPeter Krempa <pkrempa@redhat.com>
Tue, 1 Jul 2014 11:52:51 +0000 (13:52 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 1 Jul 2014 15:45:26 +0000 (17:45 +0200)
We have the following matrix of possible arguments handled by the logic
statement touched by this patch:
       | flags & _REUSE_EXT | !(flags & _REUSE_EXT)
-------+--------------------+----------------------
 format| (1)                | (2)
-------+--------------------+----------------------
!format| (3)                | (4)
-------+--------------------+----------------------

In cases 1 and 2 the user provided a format, in cases 3 and 4 not. The
user requests to use a pre-existing image in 1 and 3 and libvirt will
create a new image in 2 and 4.

The difference between cases 3 and 4 is that for 3 the format is probed
from the user-provided image, whereas in 4 we just use the existing disk
format.

The current code would treat cases 1,3 and 4 correctly but in case 2 the
format provided by the user would be ignored.

The particular piece of code was broken in commit 35c7701c64508f975dfeb8
but since it was introduced a few commits before that it was never
released as working.

src/qemu/qemu_driver.c

index 775f6ab3ef467ea21a64e386ad44d709e872404f..d45a16107aba8b5f3409367f9e417fc10a32307e 100644 (file)
@@ -15356,29 +15356,34 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
     /* XXX Allow non-file mirror destinations */
     mirror->type = VIR_STORAGE_TYPE_FILE;
 
+    if (format) {
+        if ((mirror->format = virStorageFileFormatTypeFromString(format)) <= 0) {
+            virReportError(VIR_ERR_INVALID_ARG, _("unrecognized format '%s'"),
+                           format);
+            goto endjob;
+        }
+    } else {
+        if (!(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)) {
+            mirror->format = disk->src->format;
+        } else {
+            /* If the user passed the REUSE_EXT flag, then either they
+             * also passed the RAW flag (and format is non-NULL), or it is
+             * safe for us to probe the format from the file that we will
+             * be using.  */
+            mirror->format = virStorageFileProbeFormat(dest, cfg->user,
+                                                       cfg->group);
+        }
+    }
+
+    /* pre-create the image file */
     if (!(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)) {
         int fd = qemuOpenFile(driver, vm, dest, O_WRONLY | O_TRUNC | O_CREAT,
                               &need_unlink, NULL);
         if (fd < 0)
             goto endjob;
         VIR_FORCE_CLOSE(fd);
-        if (!format)
-            mirror->format = disk->src->format;
-    } else if (format) {
-        mirror->format = virStorageFileFormatTypeFromString(format);
-        if (mirror->format <= 0) {
-            virReportError(VIR_ERR_INVALID_ARG, _("unrecognized format '%s'"),
-                           format);
-            goto endjob;
-        }
-    } else {
-        /* If the user passed the REUSE_EXT flag, then either they
-         * also passed the RAW flag (and format is non-NULL), or it is
-         * safe for us to probe the format from the file that we will
-         * be using.  */
-        mirror->format = virStorageFileProbeFormat(dest, cfg->user,
-                                                   cfg->group);
     }
+
     if (!format && mirror->format > 0)
         format = virStorageFileFormatTypeToString(mirror->format);
     if (VIR_STRDUP(mirror->path, dest) < 0)