diff options
author | Anthony Liguori <aliguori@amazon.com> | 2013-11-19 12:59:09 -0800 |
---|---|---|
committer | Anthony Liguori <aliguori@amazon.com> | 2013-11-19 12:59:09 -0800 |
commit | 7af31519e220efc0572cacec5ac65dc54e73985d (patch) | |
tree | e078f066da8645430cf5ed0c9f0c07e823b10c30 | |
parent | 88a47b9de2c01121e153b1feb24cdb2e033b2f04 (diff) | |
parent | 06d22aa36706a3d6051b74c8a183ab554a0cb808 (diff) |
Merge remote-tracking branch 'kwolf/tags/for-anthony' into staging
Block fixes for 1.7.0
# gpg: Signature made Fri 15 Nov 2013 09:51:25 AM PST using RSA key ID C88F2FD6
# gpg: Can't check signature: public key not found
# By Max Reitz (3) and others
# Via Kevin Wolf
* kwolf/tags/for-anthony:
block: Fail if requested driver is not available
MAINTAINERS: add block driver sub-maintainers
qemu-img: Fix overwriting 'ret' before using
qemu-iotests: Test qcow2 count_contiguous_clusters()
qcow2: fix possible corruption when reading multiple clusters
qmp: access the local QemuOptsLists for drive option
MAINTAINERS: add block tree repo URLs
qemu-iotests: Extend 041 for unbacked mirroring
block/drive-mirror: Check for NULL backing_hd
qapi-schema: Update description for NewImageMode
block: Print its file name if backing file opening failed
Message-id: 1384537999-5972-1-git-send-email-kwolf@redhat.com
Signed-off-by: Anthony Liguori <aliguori@amazon.com>
-rw-r--r-- | MAINTAINERS | 42 | ||||
-rw-r--r-- | block.c | 9 | ||||
-rw-r--r-- | block/qcow2-cluster.c | 2 | ||||
-rw-r--r-- | block/raw-posix.c | 1 | ||||
-rw-r--r-- | block/raw-win32.c | 1 | ||||
-rw-r--r-- | blockdev.c | 5 | ||||
-rw-r--r-- | include/qemu/config-file.h | 1 | ||||
-rw-r--r-- | include/sysemu/sysemu.h | 2 | ||||
-rw-r--r-- | qapi-schema.json | 3 | ||||
-rw-r--r-- | qemu-img.c | 6 | ||||
-rwxr-xr-x | tests/qemu-iotests/041 | 25 | ||||
-rw-r--r-- | tests/qemu-iotests/041.out | 4 | ||||
-rwxr-xr-x | tests/qemu-iotests/048 | 34 | ||||
-rw-r--r-- | tests/qemu-iotests/048.out | 27 | ||||
-rwxr-xr-x | tests/qemu-iotests/051 | 7 | ||||
-rw-r--r-- | tests/qemu-iotests/051.out | 11 | ||||
-rw-r--r-- | tests/qemu-iotests/069.out | 2 | ||||
-rwxr-xr-x | tests/qemu-iotests/073 | 166 | ||||
-rw-r--r-- | tests/qemu-iotests/073.out | 118 | ||||
-rw-r--r-- | tests/qemu-iotests/group | 1 | ||||
-rw-r--r-- | util/qemu-config.c | 77 | ||||
-rw-r--r-- | vl.c | 3 |
22 files changed, 531 insertions, 16 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 02b85ee4cd..c19133f1a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -639,6 +639,8 @@ S: Supported F: block* F: block/ F: hw/block/ +T: git git://repo.or.cz/qemu/kevin.git block +T: git git://github.com/stefanha/qemu.git block Character Devices M: Anthony Liguori <aliguori@amazon.com> @@ -861,3 +863,43 @@ Stable 0.10 L: qemu-stable@nongnu.org T: git git://git.qemu-project.org/qemu-stable-0.10.git S: Orphan + +Block drivers +------------- +VMDK +M: Fam Zheng <famz@redhat.com> +S: Supported +F: block/vmdk.c + +RBD +M: Josh Durgin <josh.durgin@inktank.com> +S: Supported +F: block/rbd.c + +Sheepdog +M: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> +M: Liu Yuan <namei.unix@gmail.com> +S: Supported +F: block/sheepdog.c + +VHDX +M: Jeff Cody <jcody@redhat.com> +S: Supported +F: block/vhdx* + +VDI +M: Stefan Weil <sw@weilnetz.de> +S: Maintained +F: block/vdi.c + +iSCSI +M: Ronnie Sahlberg <ronniesahlberg@gmail.com> +M: Paolo Bonzini <pbonzini@redhat.com> +M: Peter Lieven <pl@kamp.de> +S: Supported +F: block/iscsi.c + +SSH +M: Richard W.M. Jones <rjones@redhat.com> +S: Supported +F: block/ssh.c @@ -1009,7 +1009,9 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) bdrv_unref(bs->backing_hd); bs->backing_hd = NULL; bs->open_flags |= BDRV_O_NO_BACKING; - error_propagate(errp, local_err); + error_setg(errp, "Could not open backing file: %s", + error_get_pretty(local_err)); + error_free(local_err); return ret; } pstrcpy(bs->backing_file, sizeof(bs->backing_file), @@ -1135,6 +1137,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, if (drvname) { drv = bdrv_find_format(drvname); qdict_del(options, "driver"); + if (!drv) { + error_setg(errp, "Invalid driver: '%s'", drvname); + ret = -EINVAL; + goto unlink_and_fail; + } } if (!drv) { diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index f242244918..791083a0ef 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -290,7 +290,7 @@ static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size, uint64_t *l2_table, uint64_t stop_flags) { int i; - uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW2_CLUSTER_COMPRESSED; + uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED; uint64_t first_entry = be64_to_cpu(l2_table[0]); uint64_t offset = first_entry & mask; diff --git a/block/raw-posix.c b/block/raw-posix.c index ace5d962e8..f836c8e745 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -310,7 +310,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, if (ret == -EROFS) { ret = -EACCES; } - error_setg_errno(errp, -ret, "Could not open file"); goto fail; } s->fd = fd; diff --git a/block/raw-win32.c b/block/raw-win32.c index 2741e4de10..2bad5a39b4 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -280,7 +280,6 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, } else { ret = -EINVAL; } - error_setg_errno(errp, -ret, "Could not open file"); goto fail; } diff --git a/blockdev.c b/blockdev.c index 86e6bffdc4..330aa4a3a4 100644 --- a/blockdev.c +++ b/blockdev.c @@ -47,7 +47,6 @@ #include "sysemu/arch_init.h" static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); -extern QemuOptsList qemu_common_drive_opts; static const char *const if_name[IF_COUNT] = { [IF_NONE] = "none", @@ -2029,7 +2028,9 @@ void qmp_drive_mirror(const char *device, const char *target, return; } - if (sync == MIRROR_SYNC_MODE_FULL && mode != NEW_IMAGE_MODE_EXISTING) { + if ((sync == MIRROR_SYNC_MODE_FULL || !source) + && mode != NEW_IMAGE_MODE_EXISTING) + { /* create new image w/o backing file */ assert(format && drv); bdrv_img_create(target, format, diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h index ad4a9e5c3a..508428ff32 100644 --- a/include/qemu/config-file.h +++ b/include/qemu/config-file.h @@ -8,6 +8,7 @@ QemuOptsList *qemu_find_opts(const char *group); QemuOptsList *qemu_find_opts_err(const char *group, Error **errp); void qemu_add_opts(QemuOptsList *list); +void qemu_add_drive_opts(QemuOptsList *list); int qemu_set_option(const char *str); int qemu_global_option(const char *str); void qemu_add_globals(void); diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index cd5791eb74..495dae8c39 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -193,6 +193,8 @@ QemuOpts *qemu_get_machine_opts(void); bool usb_enabled(bool default_usb); +extern QemuOptsList qemu_legacy_drive_opts; +extern QemuOptsList qemu_common_drive_opts; extern QemuOptsList qemu_drive_opts; extern QemuOptsList qemu_chardev_opts; extern QemuOptsList qemu_device_opts; diff --git a/qapi-schema.json b/qapi-schema.json index 76c98a7265..83fa4852ce 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1736,7 +1736,8 @@ # @existing: QEMU should look for an existing image file. # # @absolute-paths: QEMU should create a new image with absolute paths -# for the backing file. +# for the backing file. If there is no backing file available, the new +# image will not be backed either. # # Since: 1.1 ## diff --git a/qemu-img.c b/qemu-img.c index bf3fb4f8a6..b6b5644cb6 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1020,10 +1020,10 @@ static int img_compare(int argc, char **argv) } ret = compare_sectors(buf1, buf2, nb_sectors, &pnum); if (ret || pnum != nb_sectors) { - ret = 1; qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n", sectors_to_bytes( ret ? sector_num : sector_num + pnum)); + ret = 1; goto out; } } @@ -1045,9 +1045,9 @@ static int img_compare(int argc, char **argv) } if (ret) { if (ret < 0) { - ret = 4; error_report("Error while reading offset %" PRId64 ": %s", sectors_to_bytes(sector_num), strerror(-ret)); + ret = 4; } goto out; } @@ -1092,10 +1092,10 @@ static int img_compare(int argc, char **argv) filename_over, buf1, quiet); if (ret) { if (ret < 0) { - ret = 4; error_report("Error while reading offset %" PRId64 " of %s: %s", sectors_to_bytes(sector_num), filename_over, strerror(-ret)); + ret = 4; } goto out; } diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 6661c0395d..5d40265fb3 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -677,5 +677,30 @@ class TestSetSpeed(ImageMirroringTestCase): self.wait_ready_and_cancel() +class TestUnbackedSource(ImageMirroringTestCase): + image_len = 2 * 1024 * 1024 # MB + + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, test_img, + str(TestUnbackedSource.image_len)) + self.vm = iotests.VM().add_drive(test_img) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(target_img) + + def test_absolute_paths(self): + self.assert_no_active_block_jobs() + + for sync_mode in ['full', 'top', 'none']: + result = self.vm.qmp('drive-mirror', device='drive0', + sync=sync_mode, target=target_img, + mode='absolute-paths') + self.assert_qmp(result, 'return', {}) + self.complete_and_wait() + self.assert_no_active_block_jobs() + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index 42314e9c00..4fd1c2dcd2 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -........................ +......................... ---------------------------------------------------------------------- -Ran 24 tests +Ran 25 tests OK diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048 index 9b9d118ef3..9def7fcc8c 100755 --- a/tests/qemu-iotests/048 +++ b/tests/qemu-iotests/048 @@ -74,5 +74,39 @@ _compare io_pattern write 0 $CLUSTER_SIZE 0 1 123 _compare +# Test unaligned case of mismatch offsets in allocated clusters +_make_test_img $size +io_pattern write 0 512 0 1 100 +cp "$TEST_IMG" "$TEST_IMG2" +io_pattern write 512 512 0 1 101 +_compare + +# Test cluster allocated in one, with IO error +cat > "$TEST_DIR/blkdebug.conf"<<EOF +[inject-error] +event = "read_aio" +errno = "5" +once ="off" +EOF +_make_test_img $size +cp "$TEST_IMG" "$TEST_IMG2" +io_pattern write 512 512 0 1 102 +TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" _compare 2>&1 |\ + _filter_testdir | _filter_imgfmt + +# Test cluster allocated in one, with different sizes and IO error in the part +# that exists only in one image +cat > "$TEST_DIR/blkdebug.conf"<<EOF +[inject-error] +event = "read_aio" +errno = "5" +once ="off" +EOF +_make_test_img $size +TEST_IMG="$TEST_IMG2" _make_test_img 0 +io_pattern write 512 512 0 1 102 +TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" _compare 2>&1 |\ + _filter_testdir | _filter_imgfmt + # Cleanup status=0 diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out index 68f65d5e19..d141e0579f 100644 --- a/tests/qemu-iotests/048.out +++ b/tests/qemu-iotests/048.out @@ -1,5 +1,5 @@ QA output created by 048 -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 === IO: pattern 45 qemu-io> wrote 4096/4096 bytes at offset 524288 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -28,4 +28,29 @@ qemu-io> wrote 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qemu-io> Content mismatch at offset 0! 1 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +=== IO: pattern 100 +qemu-io> wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> === IO: pattern 101 +qemu-io> wrote 512/512 bytes at offset 512 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> Content mismatch at offset 512! +1 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +=== IO: pattern 102 +qemu-io> wrote 512/512 bytes at offset 512 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error +qemu-img: Error while reading offset 0: Input/output error +4 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=0 +=== IO: pattern 102 +qemu-io> wrote 512/512 bytes at offset 512 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io> qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error +qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error +Warning: Image size mismatch! +4 Cleanup diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 0a4971d437..3a75bda5eb 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -78,6 +78,13 @@ run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=1234 run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=foo echo +echo === Invalid format === +echo + +run_qemu -drive file="$TEST_IMG",format=foo +run_qemu -drive file="$TEST_IMG",driver=foo + +echo echo === Overriding backing file === echo diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 15deef6dc3..8769c8e66e 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -17,6 +17,15 @@ 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' +=== Invalid format === + +Testing: -drive file=TEST_DIR/t.qcow2,format=foo +QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=foo: 'foo' invalid format + +Testing: -drive file=TEST_DIR/t.qcow2,driver=foo +QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=foo: could not open disk image TEST_DIR/t.qcow2: Invalid driver: 'foo' + + === Overriding backing file === Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig -nodefaults @@ -226,6 +235,6 @@ Testing: -drive file=foo:bar QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: Unknown protocol Testing: -drive file.filename=foo:bar -QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: Could not open file: No such file or directory +QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: Could not open 'foo:bar': No such file or directory *** done diff --git a/tests/qemu-iotests/069.out b/tests/qemu-iotests/069.out index 364881429c..b48306d5ab 100644 --- a/tests/qemu-iotests/069.out +++ b/tests/qemu-iotests/069.out @@ -4,5 +4,5 @@ QA output created by 069 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file='TEST_DIR/t.IMGFMT.base' -qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open file: No such file or directory +qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory *** done diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073 new file mode 100755 index 0000000000..392db54999 --- /dev/null +++ b/tests/qemu-iotests/073 @@ -0,0 +1,166 @@ +#!/bin/bash +# +# Test count_contiguous_clusters in qcow2 +# +# Copyright (C) 2013 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/>. +# + +# 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 generic +_supported_os Linux + +CLUSTER_SIZE=64k +size=128M + +echo +echo "== creating backing file ==" + +TEST_IMG="$TEST_IMG.base" _make_test_img $size + +_make_test_img -b "$TEST_IMG.base" +$QEMU_IO -c "write -P 0xa5 0 $size" "$TEST_IMG.base" | _filter_qemu_io + +echo +echo "== normal -> unallocated ==" + +$QEMU_IO -c "write -P 0x11 0 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 0x11 0x10000 0x10000" "$TEST_IMG.base" | _filter_qemu_io + +$QEMU_IO -c "read -P 0x11 0 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== normal -> compressed ==" + +$QEMU_IO -c "write -P 0x22 0x20000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -c -P 0x22 0x30000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0x22 0x20000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== normal -> zero ==" + +$QEMU_IO -c "write -P 0x33 0x40000 0x20000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 0x33 0x40000 0x20000" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -P 0 0x40000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -z 0x50000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0 0x40000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo +echo "== unallocated -> normal ==" + +$QEMU_IO -c "write -P 0x44 0x60000 0x10000" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -P 0x44 0x70000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0x44 0x60000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== unallocated -> compressed ==" + +$QEMU_IO -c "write -P 0x55 0x80000 0x10000" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -c -P 0x55 0x90000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0x55 0x80000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== unallocated -> zero ==" + +$QEMU_IO -c "write -P 0x66 0xa0000 0x20000" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -P 0 0xa0000 0x10000" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -z 0xb0000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0 0xa0000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo +echo "== compressed -> normal ==" + +$QEMU_IO -c "write -c -P 0x77 0xc0000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 0x77 0xd0000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0x77 0xc0000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== compressed -> unallocated ==" + +$QEMU_IO -c "write -c -P 0x88 0xe0000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 0x88 0xf0000 0x10000" "$TEST_IMG.base" | _filter_qemu_io + +$QEMU_IO -c "read -P 0x88 0xe0000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== compressed -> zero ==" + +$QEMU_IO -c "write -c -P 0 0x100000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -c -P 0x99 0x110000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -z 0x110000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0 0x100000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo +echo "== zero -> normal ==" + +$QEMU_IO -c "write -P 0xaa 0x120000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 0 0x130000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -z 0x120000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0 0x120000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== zero -> unallocated ==" + +$QEMU_IO -c "write -z 0x140000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -P 0 0x150000 0x10000" "$TEST_IMG.base" | _filter_qemu_io + +$QEMU_IO -c "read -P 0 0x140000 0x20000" "$TEST_IMG" | _filter_qemu_io + +echo +echo "== zero -> compressed ==" + +$QEMU_IO -c "write -c -P 0 0x170000 0x10000" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -z 0x160000 0x10000" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IO -c "read -P 0 0x160000 0x20000" "$TEST_IMG" | _filter_qemu_io + + +_check_test_img + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/073.out b/tests/qemu-iotests/073.out new file mode 100644 index 0000000000..c9b00763b2 --- /dev/null +++ b/tests/qemu-iotests/073.out @@ -0,0 +1,118 @@ +QA output created by 073 + +== creating backing file == +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' +wrote 134217728/134217728 bytes at offset 0 +128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== normal -> unallocated == +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 65536 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 0 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== normal -> compressed == +wrote 65536/65536 bytes at offset 131072 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 196608 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 131072 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== normal -> zero == +wrote 131072/131072 bytes at offset 262144 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 131072/131072 bytes at offset 262144 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 262144 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 327680 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 262144 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + + +== unallocated -> normal == +wrote 65536/65536 bytes at offset 393216 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 458752 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 393216 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== unallocated -> compressed == +wrote 65536/65536 bytes at offset 524288 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 589824 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 524288 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== unallocated -> zero == +wrote 131072/131072 bytes at offset 655360 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 655360 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 720896 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 655360 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + + +== compressed -> normal == +wrote 65536/65536 bytes at offset 786432 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 851968 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 786432 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== compressed -> unallocated == +wrote 65536/65536 bytes at offset 917504 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 983040 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 917504 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== compressed -> zero == +wrote 65536/65536 bytes at offset 1048576 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 1114112 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 1114112 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 1048576 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + + +== zero -> normal == +wrote 65536/65536 bytes at offset 1179648 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 1245184 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 1179648 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 1179648 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== zero -> unallocated == +wrote 65536/65536 bytes at offset 1310720 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 1376256 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 1310720 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +== zero -> compressed == +wrote 65536/65536 bytes at offset 1507328 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 1441792 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 131072/131072 bytes at offset 1441792 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +No errors were found on the image. +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index b18b241f8d..b63b18c7aa 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -76,3 +76,4 @@ 068 rw auto 069 rw auto 070 rw auto +073 rw auto diff --git a/util/qemu-config.c b/util/qemu-config.c index a59568d070..04da942a25 100644 --- a/util/qemu-config.c +++ b/util/qemu-config.c @@ -8,6 +8,7 @@ #include "qmp-commands.h" static QemuOptsList *vm_config_groups[32]; +static QemuOptsList *drive_config_groups[4]; static QemuOptsList *find_list(QemuOptsList **lists, const char *group, Error **errp) @@ -77,6 +78,59 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc) return param_list; } +/* remove repeated entry from the info list */ +static void cleanup_infolist(CommandLineParameterInfoList *head) +{ + CommandLineParameterInfoList *pre_entry, *cur, *del_entry; + + cur = head; + while (cur->next) { + pre_entry = head; + while (pre_entry != cur->next) { + if (!strcmp(pre_entry->value->name, cur->next->value->name)) { + del_entry = cur->next; + cur->next = cur->next->next; + g_free(del_entry); + break; + } + pre_entry = pre_entry->next; + } + cur = cur->next; + } +} + +/* merge the description items of two parameter infolists */ +static void connect_infolist(CommandLineParameterInfoList *head, + CommandLineParameterInfoList *new) +{ + CommandLineParameterInfoList *cur; + + cur = head; + while (cur->next) { + cur = cur->next; + } + cur->next = new; +} + +/* access all the local QemuOptsLists for drive option */ +static CommandLineParameterInfoList *get_drive_infolist(void) +{ + CommandLineParameterInfoList *head = NULL, *cur; + int i; + + for (i = 0; drive_config_groups[i] != NULL; i++) { + if (!head) { + head = query_option_descs(drive_config_groups[i]->desc); + } else { + cur = query_option_descs(drive_config_groups[i]->desc); + connect_infolist(head, cur); + } + } + cleanup_infolist(head); + + return head; +} + CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option, const char *option, Error **errp) @@ -89,7 +143,12 @@ CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option, if (!has_option || !strcmp(option, vm_config_groups[i]->name)) { info = g_malloc0(sizeof(*info)); info->option = g_strdup(vm_config_groups[i]->name); - info->parameters = query_option_descs(vm_config_groups[i]->desc); + if (!strcmp("drive", vm_config_groups[i]->name)) { + info->parameters = get_drive_infolist(); + } else { + info->parameters = + query_option_descs(vm_config_groups[i]->desc); + } entry = g_malloc0(sizeof(*entry)); entry->value = info; entry->next = conf_list; @@ -109,6 +168,22 @@ QemuOptsList *qemu_find_opts_err(const char *group, Error **errp) return find_list(vm_config_groups, group, errp); } +void qemu_add_drive_opts(QemuOptsList *list) +{ + int entries, i; + + entries = ARRAY_SIZE(drive_config_groups); + entries--; /* keep list NULL terminated */ + for (i = 0; i < entries; i++) { + if (drive_config_groups[i] == NULL) { + drive_config_groups[i] = list; + return; + } + } + fprintf(stderr, "ran out of space in drive_config_groups"); + abort(); +} + void qemu_add_opts(QemuOptsList *list) { int entries, i; @@ -2867,6 +2867,9 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_QOM); qemu_add_opts(&qemu_drive_opts); + qemu_add_drive_opts(&qemu_legacy_drive_opts); + qemu_add_drive_opts(&qemu_common_drive_opts); + qemu_add_drive_opts(&qemu_drive_opts); qemu_add_opts(&qemu_chardev_opts); qemu_add_opts(&qemu_device_opts); qemu_add_opts(&qemu_netdev_opts); |