[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen staging] qcow: Tolerate backing_fmt=



commit 344acbd62ffdbeb7f803644ad46a8129059f6823
Author:     Eric Blake <eblake@xxxxxxxxxx>
AuthorDate: Mon Jul 6 15:39:49 2020 -0500
Commit:     Kevin Wolf <kwolf@xxxxxxxxxx>
CommitDate: Tue Jul 14 15:18:59 2020 +0200

    qcow: Tolerate backing_fmt=
    
    qcow has no space in the metadata to store a backing format, and there
    are existing qcow images backed both by raw or by other formats
    (usually qcow) images, reliant on probing to tell the difference.  On
    the bright side, because we probe every time, raw files are marked as
    probed and we thus forbid a commit action into the backing file where
    guest-controlled contents could change the result of the probe next
    time around (the iotest added here proves that).
    
    Still, allowing the user to specify the backing format during
    creation, even if we can't record it, is a good thing.  This patch
    blindly allows any value that resolves to a known driver, even if the
    user's request is a mismatch from what probing finds; then the next
    patch will further enhance things to verify that the user's request
    matches what we actually probe.  With this and the next patch in
    place, we will finally be ready to deprecate the creation of images
    where a backing format was not explicitly specified by the user.
    
    Note that this is only for QemuOpts usage; there is no change to the
    QAPI to allow a format through -blockdev.
    
    Add a new iotest 301 just for qcow, to demonstrate the latest
    behavior, and to make it easier to show the improvements made in the
    next patch.
    
    Signed-off-by: Eric Blake <eblake@xxxxxxxxxx>
    Message-Id: <20200706203954.341758-6-eblake@xxxxxxxxxx>
    Signed-off-by: Kevin Wolf <kwolf@xxxxxxxxxx>
---
 block/qcow.c               | 20 ++++++++++-
 tests/qemu-iotests/301     | 88 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/301.out | 60 +++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |  1 +
 4 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/block/qcow.c b/block/qcow.c
index 1e134f3445..e514a86fe5 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -938,10 +938,11 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 {
     BlockdevCreateOptions *create_options = NULL;
     BlockDriverState *bs = NULL;
-    QDict *qdict;
+    QDict *qdict = NULL;
     Visitor *v;
     const char *val;
     int ret;
+    char *backing_fmt;
 
     static const QDictRenames opt_renames[] = {
         { BLOCK_OPT_BACKING_FILE,       "backing-file" },
@@ -949,6 +950,17 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
         { NULL, NULL },
     };
 
+    /*
+     * We can't actually store a backing format, but can check that
+     * the user's request made sense.
+     */
+    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+    if (backing_fmt && !bdrv_find_format(backing_fmt)) {
+        error_setg(errp, "unrecognized backing format '%s'", backing_fmt);
+        ret = -EINVAL;
+        goto fail;
+    }
+
     /* Parse options and convert legacy syntax */
     qdict = qemu_opts_to_qdict_filtered(opts, NULL, &qcow_create_opts, true);
 
@@ -1012,6 +1024,7 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver 
*drv,
 
     ret = 0;
 fail:
+    g_free(backing_fmt);
     qobject_unref(qdict);
     bdrv_unref(bs);
     qapi_free_BlockdevCreateOptions(create_options);
@@ -1146,6 +1159,11 @@ static QemuOptsList qcow_create_opts = {
             .type = QEMU_OPT_STRING,
             .help = "File name of a base image"
         },
+        {
+            .name = BLOCK_OPT_BACKING_FMT,
+            .type = QEMU_OPT_STRING,
+            .help = "Format of the backing image",
+        },
         {
             .name = BLOCK_OPT_ENCRYPT,
             .type = QEMU_OPT_BOOL,
diff --git a/tests/qemu-iotests/301 b/tests/qemu-iotests/301
new file mode 100755
index 0000000000..3823e95617
--- /dev/null
+++ b/tests/qemu-iotests/301
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+#
+# Test qcow backing file warnings
+#
+# Copyright (C) 2020 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+    _cleanup_test_img
+    _rm_test_img "$TEST_IMG.qcow2"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow
+_supported_proto file
+_supported_os Linux
+
+size=32M
+
+echo
+echo "== qcow backed by qcow =="
+
+TEST_IMG="$TEST_IMG.base" _make_test_img $size
+_make_test_img -b "$TEST_IMG.base" $size
+_img_info
+_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $size
+_img_info
+
+echo
+echo "== mismatched command line detection =="
+
+_make_test_img -b "$TEST_IMG.base" -F vmdk
+_make_test_img -b "$TEST_IMG.base" -F vmdk $size
+echo
+# Use of -u bypasses the backing format sanity check
+_make_test_img -u -b "$TEST_IMG.base" -F vmdk
+_make_test_img -u -b "$TEST_IMG.base" -F vmdk $size
+echo
+# But the format must still be recognized
+_make_test_img -b "$TEST_IMG.base" -F garbage $size
+_make_test_img -u -b "$TEST_IMG.base" -F garbage $size
+_img_info
+
+echo
+echo "== qcow backed by raw =="
+
+rm "$TEST_IMG.base"
+truncate --size=$size "$TEST_IMG.base"
+_make_test_img -b "$TEST_IMG.base" $size
+_img_info
+_make_test_img -b "$TEST_IMG.base" -F raw $size
+_img_info
+
+echo
+echo "== commit cannot change type of raw backing file =="
+TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 _make_test_img $size
+truncate --size=$size "$TEST_IMG.qcow2"
+$QEMU_IMG convert -n -f raw -O $IMGFMT "$TEST_IMG.qcow2" "$TEST_IMG"
+$QEMU_IMG commit -f $IMGFMT "$TEST_IMG" && echo "unexpected success"
+TEST_IMG="$TEST_IMG.base" _img_info
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/301.out b/tests/qemu-iotests/301.out
new file mode 100644
index 0000000000..adaf11d42d
--- /dev/null
+++ b/tests/qemu-iotests/301.out
@@ -0,0 +1,60 @@
+QA output created by 301
+
+== qcow backed by qcow ==
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=33554432
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 32 MiB (33554432 bytes)
+cluster_size: 512
+backing file: TEST_DIR/t.IMGFMT.base
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 32 MiB (33554432 bytes)
+cluster_size: 512
+backing file: TEST_DIR/t.IMGFMT.base
+
+== mismatched command line detection ==
+qemu-img: TEST_DIR/t.IMGFMT: invalid VMDK image descriptor
+Could not open backing image to determine size.
+qemu-img: warning: Could not verify backing image. This may become an error in 
future versions.
+invalid VMDK image descriptor
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=vmdk
+
+qemu-img: TEST_DIR/t.IMGFMT: Image creation needs a size parameter
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=vmdk
+
+qemu-img: warning: Could not verify backing image. This may become an error in 
future versions.
+Unknown driver 'garbage'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=garbage
+qemu-img: TEST_DIR/t.IMGFMT: unrecognized backing format 'garbage'
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=garbage
+qemu-img: TEST_DIR/t.IMGFMT: unrecognized backing format 'garbage'
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 32 MiB (33554432 bytes)
+cluster_size: 512
+backing file: TEST_DIR/t.IMGFMT.base
+
+== qcow backed by raw ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 32 MiB (33554432 bytes)
+cluster_size: 512
+backing file: TEST_DIR/t.IMGFMT.base
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 
backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 32 MiB (33554432 bytes)
+cluster_size: 512
+backing file: TEST_DIR/t.IMGFMT.base
+
+== commit cannot change type of raw backing file ==
+Formatting 'TEST_DIR/t.qcow.IMGFMT', fmt=IMGFMT size=33554432
+qemu-img: Block job failed: Operation not permitted
+image: TEST_DIR/t.IMGFMT.base
+file format: raw
+virtual size: 32 MiB (33554432 bytes)
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 9b07a7ed03..a4f9e11e7a 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -306,3 +306,4 @@
 295 rw
 296 rw
 297 meta
+301 backing quick
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.