diff --git a/MAINTAINERS b/MAINTAINERS index 02b85ee4cd37eab10a0d73be0b198af1d1d87304..c19133f1a3bf3f896d9e01667a3c721f0bfd28ad 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 @@ -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 +S: Supported +F: block/vmdk.c + +RBD +M: Josh Durgin +S: Supported +F: block/rbd.c + +Sheepdog +M: MORITA Kazutaka +M: Liu Yuan +S: Supported +F: block/sheepdog.c + +VHDX +M: Jeff Cody +S: Supported +F: block/vhdx* + +VDI +M: Stefan Weil +S: Maintained +F: block/vdi.c + +iSCSI +M: Ronnie Sahlberg +M: Paolo Bonzini +M: Peter Lieven +S: Supported +F: block/iscsi.c + +SSH +M: Richard W.M. Jones +S: Supported +F: block/ssh.c diff --git a/block.c b/block.c index 6d5c80475c2b3d80f1e4641c802d2a820c06724b..382ea71f4b8c28550d4a798377fd1e6c4bae04ae 100644 --- a/block.c +++ b/block.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 f242244918e3029dad9786c1389f5358606a5dcc..791083a0efadf9125b5b80893a0ab794f8671952 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 ace5d962e8eb77206b69b898e7f87e748676a688..f836c8e745c4c37631ca50c11b98e3ecadc1708d 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 2741e4de10b9989ca916bfe90357680c2f4fbf54..2bad5a39b4f7f5ccf78596bfb0fc5bac9911280c 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 86e6bffdc493a1113c0984a7e9d4c35b87ddcc2f..330aa4a3a4edcf2de146685841589e6671c8bfb7 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 ad4a9e5c3ab7f2d4239924fd211ab07da2a4d126..508428ff32e02786f0c18ada55be87c602e8860f 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 cd5791eb74df05f296df4fb479d0c873dc69a70b..495dae8c396a44a5ba2a720908157e6bce3e20b5 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 76c98a7265550f889b84fc23a6467c30054cab57..83fa4852ce1b5d7e1b78592715c8b4e4f7516b16 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 bf3fb4f8a6555592082ae6366e07a8a200d8d243..b6b5644cb6afaf7441f950c85ff1e652c79bdbff 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 6661c0395d4cbcec3849cb25921053d08ebb0343..5d40265fb372eab24bbe0c138a8f5fca77c2f8e3 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 42314e9c009b1af9a60d9726696a644aa2650143..4fd1c2dcd218ecf87e18b7a6b4542c4acd892ea0 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 9b9d118ef35612fbcdb8b66b79b468a16c6b6ae1..9def7fcc8ca49c5a72a1e778d2e1c862f6041f1c 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"<&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"<&1 |\ + _filter_testdir | _filter_imgfmt + # Cleanup status=0 diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out index 68f65d5e199ea4d7289bddcfd0a0595f89d5177d..d141e0579fafce1ad1dbcc8aa8a6458b393704ee 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 0a4971d4375f89f068f23e4e50f27170a4fa4c41..3a75bda5ebf0840ffea1ff3b631578858c5711a4 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -77,6 +77,13 @@ 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 === 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 15deef6dc391811dcb105ecc4c3a16c381d93449..8769c8e66e71812f0dadf1bbe574dd05bef0226e 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 364881429cc4670552eb86ab01208da65d8e0adf..b48306d5ab844cc4bdff55015ff0ba731d80172a 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 0000000000000000000000000000000000000000..392db54999405bbf709548637fa7c2e2efef3ac4 --- /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 . +# + +# 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 0000000000000000000000000000000000000000..c9b00763b28fec42e948c430b5b0c8acfa0df3f7 --- /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 b18b241f8d31376ce69655fd775c58df7aa5e646..b63b18c7aa37fc5c511c62877217f7f650f1c071 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 a59568d07077c711d3218733d44a1605e8ded2ab..04da942a2590c248f33f03a22c67b46a77884004 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; diff --git a/vl.c b/vl.c index 4ad15b808c0fcfe0a09a9df806f1bf3ed3ce3cc9..a585257096738a41f0f0be6c545b1043adfce26c 100644 --- a/vl.c +++ b/vl.c @@ -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);