From 85c09bc016076d59561449e786b7cd2138ea9446 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Wed, 29 Jan 2014 19:59:55 +0530 Subject: [PATCH 01/19] gluster: Change licence to GPLv2+ Pipe handling mechanism in gluster driver was based on similar implementation in RBD driver and hence had GPLv2 and associated copyright information. After changing gluster driver to coroutine based implementation, the pipe handling code no longer exists and hence change gluster driver's licence to GPLv2+ and remove RBD copyrights. Signed-off-by: Bharata B Rao Acked-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block/gluster.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/block/gluster.c b/block/gluster.c index fe7a10c30b..8b6ae1c74f 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -3,17 +3,9 @@ * * Copyright (C) 2012 Bharata B Rao * - * Pipe handling mechanism in AIO implementation is derived from - * block/rbd.c. Hence, + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. * - * Copyright (C) 2010-2011 Christian Brunner , - * Josh Durgin - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. */ #include #include "block/block_int.h" From b1f7d84fd2197337c0e71701b0c04174be98df77 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Wed, 29 Jan 2014 19:59:56 +0530 Subject: [PATCH 02/19] gluster: Remove unused defines and header include Remove the definitions of GLUSTER_FD_WRITE and GLUSTER_FD_READ which are no longer used. Also sockets.h isn't needed any more. Signed-off-by: Bharata B Rao Acked-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block/gluster.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/block/gluster.c b/block/gluster.c index 8b6ae1c74f..a44d612923 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -9,7 +9,6 @@ */ #include #include "block/block_int.h" -#include "qemu/sockets.h" #include "qemu/uri.h" typedef struct GlusterAIOCB { @@ -24,9 +23,6 @@ typedef struct BDRVGlusterState { struct glfs_fd *fd; } BDRVGlusterState; -#define GLUSTER_FD_READ 0 -#define GLUSTER_FD_WRITE 1 - typedef struct GlusterConf { char *server; int port; From 64bb01aa35a24bea7ad0a1a8713991bab5020d12 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Mon, 3 Mar 2014 14:54:07 +0100 Subject: [PATCH 03/19] qemu-img convert: Fix progress output Initialise progress output only when the -p and -q options have already been parsed, otherwise it's always disabled. Reported-by: Peter Lieven Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- qemu-img.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 886db881b3..2e40cc1e69 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1162,9 +1162,6 @@ static int img_convert(int argc, char **argv) Error *local_err = NULL; QemuOpts *sn_opts = NULL; - /* Initialize before goto out */ - qemu_progress_init(progress, 1.0); - fmt = NULL; out_fmt = "raw"; cache = "unsafe"; @@ -1197,17 +1194,17 @@ static int img_convert(int argc, char **argv) error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); ret = -1; - goto out; + goto fail_getopt; case '6': error_report("option -6 is deprecated, please use \'-o " "compat6\' instead!"); ret = -1; - goto out; + goto fail_getopt; case 'o': if (!is_valid_option_list(optarg)) { error_report("Invalid option list: %s", optarg); ret = -1; - goto out; + goto fail_getopt; } if (!options) { options = g_strdup(optarg); @@ -1227,7 +1224,7 @@ static int img_convert(int argc, char **argv) error_report("Failed in parsing snapshot param '%s'", optarg); ret = -1; - goto out; + goto fail_getopt; } } else { snapshot_name = optarg; @@ -1241,7 +1238,7 @@ static int img_convert(int argc, char **argv) if (sval < 0 || *end) { error_report("Invalid minimum zero buffer size for sparse output specified"); ret = -1; - goto out; + goto fail_getopt; } min_sparse = sval / BDRV_SECTOR_SIZE; @@ -1262,9 +1259,12 @@ static int img_convert(int argc, char **argv) } } + /* Initialize before goto out */ if (quiet) { progress = 0; } + qemu_progress_init(progress, 1.0); + bs_n = argc - optind - 1; out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; @@ -1667,7 +1667,6 @@ out: free_option_parameters(create_options); free_option_parameters(param); qemu_vfree(buf); - g_free(options); if (sn_opts) { qemu_opts_del(sn_opts); } @@ -1682,6 +1681,9 @@ out: } g_free(bs); } +fail_getopt: + g_free(options); + if (ret) { return 1; } From 2fa4c042bc55ec10b9ca16163697d02cddd2d768 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Mon, 3 Mar 2014 14:53:04 +0100 Subject: [PATCH 04/19] qemu-iotests: Test progress output for conversion Signed-off-by: Kevin Wolf --- tests/qemu-iotests/086 | 65 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/086.out | 18 +++++++++++ tests/qemu-iotests/group | 1 + 3 files changed, 84 insertions(+) create mode 100755 tests/qemu-iotests/086 create mode 100644 tests/qemu-iotests/086.out diff --git a/tests/qemu-iotests/086 b/tests/qemu-iotests/086 new file mode 100755 index 0000000000..48fe85bc43 --- /dev/null +++ b/tests/qemu-iotests/086 @@ -0,0 +1,65 @@ +#!/bin/bash +# +# Test qemu-img progress output +# +# Copyright (C) 2014 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 . +# + +# creator +owner=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +function run_qemu_img() +{ + echo + echo Testing: "$@" | _filter_testdir +} + +size=128M + +_make_test_img $size +$QEMU_IO -c 'write 0 1M' $TEST_IMG | _filter_qemu_io +$QEMU_IO -c 'write 2M 1M' $TEST_IMG | _filter_qemu_io +$QEMU_IO -c 'write 4M 1M' $TEST_IMG | _filter_qemu_io +$QEMU_IO -c 'write 32M 1M' $TEST_IMG | _filter_qemu_io + +$QEMU_IMG convert -p -O $IMGFMT -f $IMGFMT "$TEST_IMG" "$TEST_IMG".base 2>&1 |\ + _filter_testdir | sed -e 's/\r/\n/g' + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/086.out b/tests/qemu-iotests/086.out new file mode 100644 index 0000000000..9c0bf23718 --- /dev/null +++ b/tests/qemu-iotests/086.out @@ -0,0 +1,18 @@ +QA output created by 086 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +wrote 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1048576/1048576 bytes at offset 2097152 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1048576/1048576 bytes at offset 4194304 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1048576/1048576 bytes at offset 33554432 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + (0.00/100%) + (25.00/100%) + (50.00/100%) + (75.00/100%) + (100.00/100%) + (100.00/100%) + +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 8dd8553035..901730d31b 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -85,3 +85,4 @@ 079 rw auto 081 rw auto 082 rw auto quick +086 rw auto quick From f47c3f5a800a927238d20de9f99b5c77f0bc3fe0 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 5 Mar 2014 15:45:00 +0100 Subject: [PATCH 05/19] iscsi: Use bs->sg for everything else than disks The current iscsi block driver code makes the rather arbitrary decision that TYPE_MEDIUM_CHANGER and TYPE_TAPE devices have bs->sg = 1 and all other device types are disks. Instead of this, check for TYPE_DISK to expose the disk interface and make everything else bs->sg = 1. In particular, this includes devices with TYPE_STORAGE_ARRAY, which is what LUN 0 of an iscsi target is. (See https://bugzilla.redhat.com/show_bug.cgi?id=1067784 for the exact scenario.) Signed-off-by: Kevin Wolf Reviewed-by: Benoit Canet Acked-by: Paolo Bonzini --- block/iscsi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 0a15f53f8c..b490e98c05 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1231,12 +1231,11 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); bs->request_alignment = iscsilun->block_size; - /* Medium changer or tape. We dont have any emulation for this so this must - * be sg ioctl compatible. We force it to be sg, otherwise qemu will try - * to read from the device to guess the image format. + /* We don't have any emulation for devices other than disks and CD-ROMs, so + * this must be sg ioctl compatible. We force it to be sg, otherwise qemu + * will try to read from the device to guess the image format. */ - if (iscsilun->type == TYPE_MEDIUM_CHANGER || - iscsilun->type == TYPE_TAPE) { + if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) { bs->sg = 1; } From 47ea2de2d68b6c5319308b7de1980f463b7c125c Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 5 Mar 2014 15:49:55 +0100 Subject: [PATCH 06/19] block: Fix bs->request_alignment assertion for bs->sg=1 For sg backends, bs->request_alignment is meaningless and may be 0. Signed-off-by: Kevin Wolf Reviewed-by: Benoit Canet Acked-by: Paolo Bonzini --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.c b/block.c index 38bbdf3083..f01b91cef1 100644 --- a/block.c +++ b/block.c @@ -935,7 +935,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, bdrv_refresh_limits(bs); assert(bdrv_opt_mem_align(bs) != 0); - assert(bs->request_alignment != 0); + assert((bs->request_alignment != 0) || bs->sg); #ifndef _WIN32 if (bs->is_temporary) { From 90ce8a061bdcc485a56142cae68cfbfff270e634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Canet?= Date: Wed, 5 Mar 2014 23:48:29 +0100 Subject: [PATCH 07/19] block: make bdrv_swap rebuild the bs graph node list field. Moving only the node_name one field could lead to some inconsitencies where a node_name was defined on a bs which was not registered in the graph node list. bdrv_swap between a named node bs and a non named node bs would lead to this. bdrv_make_anon would then crash because it would try to remove the bs from the graph node list while it is not in it. This patch remove named node bses from the graph node list before doing the swap then insert them back. Signed-off-by: Benoit Canet Reviewed-by: Max Reitz Signed-off-by: Kevin Wolf --- block.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index f01b91cef1..7330a87b10 100644 --- a/block.c +++ b/block.c @@ -1847,11 +1847,6 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest, pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name), bs_src->device_name); bs_dest->device_list = bs_src->device_list; - - /* keep the same entry in graph_bdrv_states - * We do want to swap name but don't want to swap linked list entries - */ - bs_dest->node_list = bs_src->node_list; } /* @@ -1870,6 +1865,17 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old) { BlockDriverState tmp; + /* The code needs to swap the node_name but simply swapping node_list won't + * work so first remove the nodes from the graph list, do the swap then + * insert them back if needed. + */ + if (bs_new->node_name[0] != '\0') { + QTAILQ_REMOVE(&graph_bdrv_states, bs_new, node_list); + } + if (bs_old->node_name[0] != '\0') { + QTAILQ_REMOVE(&graph_bdrv_states, bs_old, node_list); + } + /* bs_new must be anonymous and shouldn't have anything fancy enabled */ assert(bs_new->device_name[0] == '\0'); assert(QLIST_EMPTY(&bs_new->dirty_bitmaps)); @@ -1898,6 +1904,14 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old) assert(bs_new->io_limits_enabled == false); assert(!throttle_have_timer(&bs_new->throttle_state)); + /* insert the nodes back into the graph node list if needed */ + if (bs_new->node_name[0] != '\0') { + QTAILQ_INSERT_TAIL(&graph_bdrv_states, bs_new, node_list); + } + if (bs_old->node_name[0] != '\0') { + QTAILQ_INSERT_TAIL(&graph_bdrv_states, bs_old, node_list); + } + bdrv_rebind(bs_new); bdrv_rebind(bs_old); } From 50c75136beec0180171971c88bb6e3fa3aa66463 Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Tue, 4 Mar 2014 10:35:48 -0500 Subject: [PATCH 08/19] block: mirror - remove code cruft that has no function Originally, this built up the error message with the backing filename, so that errp was set as follows: error_set(errp, QERR_OPEN_FILE_FAILED, backing_filename); However, we now propagate the local_error from the bdrv_open_backing_file() call instead, making these 2 lines useless code. Signed-off-by: Jeff Cody Reviewed-by: Benoit Canet Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- block/mirror.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index e683959570..dd5ee056b4 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -520,9 +520,6 @@ static void mirror_complete(BlockJob *job, Error **errp) ret = bdrv_open_backing_file(s->target, NULL, &local_err); if (ret < 0) { - char backing_filename[PATH_MAX]; - bdrv_get_full_backing_filename(s->target, backing_filename, - sizeof(backing_filename)); error_propagate(errp, local_err); return; } From cd5d031e75751838fb40f7b5a5f60fc15d543c55 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Wed, 5 Mar 2014 22:41:36 +0100 Subject: [PATCH 09/19] block: Keep "filename" option after parsing Currently, bdrv_file_open() always removes the "filename" option from the options QDict after bdrv_parse_filename() has been (successfully) called. However, for drivers with bdrv_needs_filename, it makes more sense for bdrv_parse_filename() to overwrite the "filename" option and for bdrv_file_open() to fetch the filename from there. Since there currently are no drivers that implement bdrv_parse_filename() and have bdrv_needs_filename set, this does not change current behavior. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Kevin Wolf --- block.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index 7330a87b10..e7387f1556 100644 --- a/block.c +++ b/block.c @@ -1017,7 +1017,12 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename, ret = -EINVAL; goto fail; } - qdict_del(*options, "filename"); + + if (!drv->bdrv_needs_filename) { + qdict_del(*options, "filename"); + } else { + filename = qdict_get_str(*options, "filename"); + } } if (!drv->bdrv_file_open) { From 078896a9eeeaf7c301bbc59fc791c3331324285f Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Wed, 5 Mar 2014 22:41:37 +0100 Subject: [PATCH 10/19] block/raw-posix: Implement bdrv_parse_filename() The "file" protocol driver should strip the "file:" prefix from filenames if present. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Kevin Wolf --- block/raw-posix.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/raw-posix.c b/block/raw-posix.c index 161ea14812..892145ce08 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -336,6 +336,17 @@ error: } #endif +static void raw_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* The filename does not have to be prefixed by the protocol name, since + * "file" is the default protocol; therefore, the return value of this + * function call can be ignored. */ + strstart(filename, "file:", &filename); + + qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); +} + static QemuOptsList raw_runtime_opts = { .name = "raw", .head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), @@ -1412,6 +1423,7 @@ static BlockDriver bdrv_file = { .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, .bdrv_probe = NULL, /* no probe for protocols */ + .bdrv_parse_filename = raw_parse_filename, .bdrv_file_open = raw_open, .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, From 464d9f641d5a2382bd43d10ae41355edf69338b1 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Wed, 5 Mar 2014 22:41:38 +0100 Subject: [PATCH 11/19] block/raw-posix: Strip "file:" prefix on creation The bdrv_create() implementation of the block/raw-posix "file" protocol driver should strip the "file:" prefix from filenames if present. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Kevin Wolf --- block/raw-posix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/raw-posix.c b/block/raw-posix.c index 892145ce08..e6b4c1fe02 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1241,6 +1241,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, int result = 0; int64_t total_size = 0; + strstart(filename, "file:", &filename); + /* Read out options */ while (options && options->name) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) { From 7dc74db88b1eb3cff12174d0448ecfb6cd0e2469 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Wed, 5 Mar 2014 22:41:39 +0100 Subject: [PATCH 12/19] block/raw-win32: Implement bdrv_parse_filename() The "file" protocol driver should strip the "file:" prefix from filenames if present. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Kevin Wolf --- block/raw-win32.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/raw-win32.c b/block/raw-win32.c index ae1c8e6cca..0755434732 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -251,6 +251,17 @@ static void raw_parse_flags(int flags, int *access_flags, DWORD *overlapped) } } +static void raw_parse_filename(const char *filename, QDict *options, + Error **errp) +{ + /* The filename does not have to be prefixed by the protocol name, since + * "file" is the default protocol; therefore, the return value of this + * function call can be ignored. */ + strstart(filename, "file:", &filename); + + qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); +} + static QemuOptsList raw_runtime_opts = { .name = "raw", .head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), @@ -504,6 +515,7 @@ static BlockDriver bdrv_file = { .protocol_name = "file", .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, + .bdrv_parse_filename = raw_parse_filename, .bdrv_file_open = raw_open, .bdrv_close = raw_close, .bdrv_create = raw_create, From d5546c5e776ac8f6277ddfdd59df9888e7919c2f Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Wed, 5 Mar 2014 22:41:40 +0100 Subject: [PATCH 13/19] block/raw-win32: Strip "file:" prefix on creation The bdrv_create() implementation of the block/raw-win32 "file" protocol driver should strip the "file:" prefix from filenames if present. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Kevin Wolf --- block/raw-win32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/raw-win32.c b/block/raw-win32.c index 0755434732..99547488e4 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -481,6 +481,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, int fd; int64_t total_size = 0; + strstart(filename, "file:", &filename); + /* Read out options */ while (options && options->name) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) { From 8ae8e904fcba484ff7c3f8f31339b56ebd88fbad Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 6 Mar 2014 15:43:42 +0100 Subject: [PATCH 14/19] blockdev: Fail blockdev-add with encrypted images Encrypted images need a password before they can be used, and we don't want blockdev-add to create BDSes that aren't fully initialised. So for now simply forbid encrypted images; we can come back to it later if we need the functionality. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- blockdev.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index 357f7607ff..561cb816e4 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2266,6 +2266,7 @@ void qmp_block_job_complete(const char *device, Error **errp) void qmp_blockdev_add(BlockdevOptions *options, Error **errp) { QmpOutputVisitor *ov = qmp_output_visitor_new(); + DriveInfo *dinfo; QObject *obj; QDict *qdict; Error *local_err = NULL; @@ -2301,12 +2302,18 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) qdict_flatten(qdict); - blockdev_init(NULL, qdict, &local_err); + dinfo = blockdev_init(NULL, qdict, &local_err); if (local_err) { error_propagate(errp, local_err); goto fail; } + if (bdrv_key_required(dinfo->bdrv)) { + drive_uninit(dinfo); + error_setg(errp, "blockdev-add doesn't support encrypted devices"); + goto fail; + } + fail: qmp_output_visitor_cleanup(ov); } From c6e0bd9b7037937aafeb1d34ec17975a7d685bb7 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 6 Mar 2014 15:47:32 +0100 Subject: [PATCH 15/19] blockdev: Fix NULL pointer dereference in blockdev-add If aio=native, we check that cache.direct is set as well. If however cache wasn't specified at all, qemu just segfaulted. The old condition didn't make any sense anyway because it effectively only checked for the default cache mode case, but not for an explicitly set cache.direct=off mode. Signed-off-by: Kevin Wolf Reviewed-by: Benoit Canet Reviewed-by: Eric Blake --- blockdev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/blockdev.c b/blockdev.c index 561cb816e4..c3422a1d41 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2283,8 +2283,10 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) * * For now, simply forbidding the combination for all drivers will do. */ if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) { - bool direct = options->cache->has_direct && options->cache->direct; - if (!options->has_cache && !direct) { + bool direct = options->has_cache && + options->cache->has_direct && + options->cache->direct; + if (!direct) { error_setg(errp, "aio=native requires cache.direct=true"); goto fail; } From c75203c8d343dc71d95144862bbb47290689c455 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 6 Mar 2014 15:52:14 +0100 Subject: [PATCH 16/19] qemu-iotests: Test a few blockdev-add error cases Signed-off-by: Kevin Wolf Reviewed-by: Benoit Canet --- tests/qemu-iotests/087 | 122 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/087.out | 40 ++++++++++++ tests/qemu-iotests/group | 1 + 3 files changed, 163 insertions(+) create mode 100755 tests/qemu-iotests/087 create mode 100644 tests/qemu-iotests/087.out diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 new file mode 100755 index 0000000000..53b6c43bff --- /dev/null +++ b/tests/qemu-iotests/087 @@ -0,0 +1,122 @@ +#!/bin/bash +# +# Test unsupported blockdev-add cases +# +# Copyright (C) 2014 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 . +# + +# creator +owner=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +function do_run_qemu() +{ + echo Testing: "$@" + $QEMU -nographic -qmp stdio -serial none "$@" + echo +} + +function run_qemu() +{ + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g' +} + +size=128M + +_make_test_img $size + +echo +echo === Missing ID === +echo + +run_qemu < Date: Thu, 6 Mar 2014 16:34:46 +0100 Subject: [PATCH 17/19] block: Fix error path segfault in bdrv_open() Using an invalid option for a block device that is opened with BDRV_O_PROTOCOL led to drv = NULL, and when trying to include the driver name in the error message, qemu dereferenced it: $ x86_64-softmmu/qemu-system-x86_64 -drive file=/tmp/test.qcow2,file.foo=bar Segmentation fault (core dumped) With this patch applied, the expected error message is printed: $ x86_64-softmmu/qemu-system-x86_64 -drive file=/tmp/test.qcow2,file.foo=bar qemu-system-x86_64: -drive file=/tmp/test.qcow2,file.foo=bar: could not open disk image /tmp/test.qcow2: Block protocol 'file' doesn't support the option 'foo' Signed-off-by: Kevin Wolf Reviewed-by: Benoit Canet --- block.c | 1 + tests/qemu-iotests/051 | 9 +++++++++ tests/qemu-iotests/051.out | 15 +++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/block.c b/block.c index e7387f1556..f1ef4b0109 100644 --- a/block.c +++ b/block.c @@ -1234,6 +1234,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, ret = bdrv_file_open(bs, filename, &options, flags & ~BDRV_O_PROTOCOL, &local_err); if (!ret) { + drv = bs->drv; goto done; } else if (bs->drv) { goto close_and_fail; diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 46345fb155..14694e176b 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -77,6 +77,15 @@ run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=on run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=1234 run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=foo +echo +echo === Unknown protocol option === +echo + +run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt= +run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=on +run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=1234 +run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=foo + echo echo === Invalid format === echo diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 7de18704f8..f5e33ff395 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -17,6 +17,21 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt' +=== Unknown protocol option === + +Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt= +QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt' + +Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on +QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt' + +Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234 +QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt' + +Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo +QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt' + + === Invalid format === Testing: -drive file=TEST_DIR/t.qcow2,format=foo From 2c02f88780aa611d669f73b7677aeadc1211de7e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 21 Feb 2014 14:03:01 +0000 Subject: [PATCH 18/19] hw/ide/ahci.h: Avoid shifting left into sign bit Add 'U' suffixes to avoid undefined behaviour shifting left into the signed bit of a signed integer type. Clang's sanitizer will warn about this: hw/ide/ahci.c:1210:27: runtime error: left shift of 1 by 31 places cannot be represented in type 'int' Signed-off-by: Peter Maydell Reviewed-by: Peter Crosthwaite Signed-off-by: Kevin Wolf --- hw/ide/ahci.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index 20e412c240..9a4064f892 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -40,7 +40,7 @@ #define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \ AHCI_RX_FIS_SZ) -#define AHCI_IRQ_ON_SG (1 << 31) +#define AHCI_IRQ_ON_SG (1U << 31) #define AHCI_CMD_ATAPI (1 << 5) #define AHCI_CMD_WRITE (1 << 6) #define AHCI_CMD_PREFETCH (1 << 7) @@ -61,7 +61,7 @@ /* HOST_CTL bits */ #define HOST_CTL_RESET (1 << 0) /* reset controller; self-clear */ #define HOST_CTL_IRQ_EN (1 << 1) /* global IRQ enable */ -#define HOST_CTL_AHCI_EN (1 << 31) /* AHCI enabled */ +#define HOST_CTL_AHCI_EN (1U << 31) /* AHCI enabled */ /* HOST_CAP bits */ #define HOST_CAP_SSC (1 << 14) /* Slumber capable */ @@ -69,7 +69,7 @@ #define HOST_CAP_CLO (1 << 24) /* Command List Override support */ #define HOST_CAP_SSS (1 << 27) /* Staggered Spin-up */ #define HOST_CAP_NCQ (1 << 30) /* Native Command Queueing */ -#define HOST_CAP_64 (1 << 31) /* PCI DAC (64-bit DMA) support */ +#define HOST_CAP_64 (1U << 31) /* PCI DAC (64-bit DMA) support */ /* registers for each SATA port */ #define PORT_LST_ADDR 0x00 /* command list DMA addr */ @@ -89,7 +89,7 @@ #define PORT_RESERVED 0x3c /* reserved */ /* PORT_IRQ_{STAT,MASK} bits */ -#define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */ +#define PORT_IRQ_COLD_PRES (1U << 31) /* cold presence detect */ #define PORT_IRQ_TF_ERR (1 << 30) /* task file error */ #define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */ #define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */ @@ -151,7 +151,7 @@ #define PORT_IRQ_STAT_HBDS (1 << 28) /* Host Bus Data Error Status */ #define PORT_IRQ_STAT_HBFS (1 << 29) /* Host Bus Fatal Error Status */ #define PORT_IRQ_STAT_TFES (1 << 30) /* Task File Error Status */ -#define PORT_IRQ_STAT_CPDS (1 << 31) /* Code Port Detect Status */ +#define PORT_IRQ_STAT_CPDS (1U << 31) /* Code Port Detect Status */ /* ap->flags bits */ #define AHCI_FLAG_NO_NCQ (1 << 24) From 4089f7c6a0d91020ca60ce8300784c93dd9ddcbe Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Fri, 28 Feb 2014 21:08:11 -0500 Subject: [PATCH 19/19] block: qemu-iotests 085 - live snapshots tests This adds tests for live snapshots, both through the single snapshot command, and the transaction group snapshot command. The snapshots are done through the QMP interface, using the following commands for snapshots: Single snapshot: { 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'...', 'format': 'qcow2' } }" Group snapshot: { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': '...' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': '...' } } ] } } Signed-off-by: Jeff Cody Reviewed-by: Benoit Canet Signed-off-by: Kevin Wolf --- tests/qemu-iotests/085 | 192 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/085.out | 55 +++++++++++ tests/qemu-iotests/group | 1 + 3 files changed, 248 insertions(+) create mode 100755 tests/qemu-iotests/085 create mode 100644 tests/qemu-iotests/085.out diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085 new file mode 100755 index 0000000000..33c8dc410a --- /dev/null +++ b/tests/qemu-iotests/085 @@ -0,0 +1,192 @@ +#!/bin/bash +# +# Live snapshot tests +# +# This tests live snapshots of images on a running QEMU instance, using +# QMP commands. Both single disk snapshots, and transactional group +# snapshots are performed. +# +# Copyright (C) 2014 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 . +# + +# creator +owner=jcody@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +status=1 # failure is the default! +qemu_pid= + +QMP_IN="${TEST_DIR}/qmp-in-$$" +QMP_OUT="${TEST_DIR}/qmp-out-$$" + +snapshot_virt0="snapshot-v0.qcow2" +snapshot_virt1="snapshot-v1.qcow2" + +MAX_SNAPSHOTS=10 + +_cleanup() +{ + kill -KILL ${qemu_pid} + wait ${qemu_pid} 2>/dev/null # silent kill + + rm -f "${QMP_IN}" "${QMP_OUT}" + for i in $(seq 1 ${MAX_SNAPSHOTS}) + do + rm -f "${TEST_DIR}/${i}-${snapshot_virt0}" + rm -f "${TEST_DIR}/${i}-${snapshot_virt1}" + done + _cleanup_test_img + +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +# Wait for expected QMP response from QEMU. Will time out +# after 10 seconds, which counts as failure. +# +# $1 is the string to expect +# +# If $silent is set to anything but an empty string, then +# response is not echoed out. +function timed_wait_for() +{ + while read -t 10 resp <&5 + do + if [ "${silent}" == "" ]; then + echo "${resp}" | _filter_testdir | _filter_qemu + fi + grep -q "${1}" < <(echo ${resp}) + if [ $? -eq 0 ]; then + return + fi + done + echo "Timeout waiting for ${1}" + exit 1 # Timeout means the test failed +} + +# Sends QMP command to QEMU, and waits for the expected response +# +# ${1}: String of the QMP command to send +# ${2}: String that the QEMU response should contain +function send_qmp_cmd() +{ + echo "${1}" >&6 + timed_wait_for "${2}" +} + +# ${1}: unique identifier for the snapshot filename +function create_single_snapshot() +{ + cmd="{ 'execute': 'blockdev-snapshot-sync', + 'arguments': { 'device': 'virtio0', + 'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"', + 'format': 'qcow2' } }" + send_qmp_cmd "${cmd}" "return" +} + +# ${1}: unique identifier for the snapshot filename +function create_group_snapshot() +{ + cmd="{ 'execute': 'transaction', 'arguments': + {'actions': [ + { 'type': 'blockdev-snapshot-sync', 'data' : + { 'device': 'virtio0', + 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt0}"' } }, + { 'type': 'blockdev-snapshot-sync', 'data' : + { 'device': 'virtio1', + 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ] + } }" + + send_qmp_cmd "${cmd}" "return" +} + +size=128M + +mkfifo "${QMP_IN}" +mkfifo "${QMP_OUT}" + +_make_test_img $size +mv "${TEST_IMG}" "${TEST_IMG}.orig" +_make_test_img $size + +echo +echo === Running QEMU === +echo + +"${QEMU}" -nographic -monitor none -serial none -qmp stdio\ + -drive file="${TEST_IMG}.orig",if=virtio\ + -drive file="${TEST_IMG}",if=virtio 2>&1 >"${QMP_OUT}" <"${QMP_IN}"& +qemu_pid=$! + +# redirect fifos to file descriptors, to keep from blocking +exec 5<"${QMP_OUT}" +exec 6>"${QMP_IN}" + +# Don't print response, since it has version information in it +silent=yes timed_wait_for "capabilities" + +echo +echo === Sending capabilities === +echo + +send_qmp_cmd "{ 'execute': 'qmp_capabilities' }" "return" + +echo +echo === Create a single snapshot on virtio0 === +echo + +create_single_snapshot 1 + + +echo +echo === Invalid command - missing device and nodename === +echo + +send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync', + 'arguments': { 'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}', + 'format': 'qcow2' } }" "error" + +echo +echo === Invalid command - missing snapshot-file === +echo + +send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync', + 'arguments': { 'device': 'virtio0', + 'format': 'qcow2' } }" "error" +echo +echo +echo === Create several transactional group snapshots === +echo + +for i in $(seq 2 ${MAX_SNAPSHOTS}) +do + create_group_snapshot ${i} +done + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out new file mode 100644 index 0000000000..0f2b17f99e --- /dev/null +++ b/tests/qemu-iotests/085.out @@ -0,0 +1,55 @@ +QA output created by 085 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 + +=== Running QEMU === + + +=== Sending capabilities === + +{"return": {}} + +=== Create a single snapshot on virtio0 === + +Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2.orig' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} + +=== Invalid command - missing device and nodename === + +{"error": {"class": "GenericError", "desc": "Cannot find device= nor node_name="}} + +=== Invalid command - missing snapshot-file === + +{"error": {"class": "GenericError", "desc": "Parameter 'snapshot-file' is missing"}} + + +=== Create several transactional group snapshots === + +Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/1-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/2-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/2-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/3-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/3-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/4-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/4-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/5-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/5-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/6-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/6-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/7-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/7-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/8-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/8-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/9-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/9-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off +{"return": {}} +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 9ec62d2e44..e96eafdf43 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -85,5 +85,6 @@ 079 rw auto 081 rw auto 082 rw auto quick +085 rw auto quick 086 rw auto quick 087 rw auto quick