From f915db07ef9c368ea6db6430256de064fdd1525f Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Sat, 3 May 2014 16:47:08 +0200 Subject: iotests: Use configured python Currently, QEMU's iotests rely on /usr/bin/env to start the correct Python (that is, at least Python 2.4, but not 3). On systems where Python 3 is the default, the user has no clean way of making the iotests use the correct binary. This commit makes the iotests use the Python selected by configure. Signed-off-by: Max Reitz Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/031 | 9 +++++---- tests/qemu-iotests/036 | 7 ++++--- tests/qemu-iotests/039 | 19 ++++++++++--------- tests/qemu-iotests/054 | 3 ++- tests/qemu-iotests/060 | 21 +++++++++++---------- tests/qemu-iotests/061 | 25 +++++++++++++------------ tests/qemu-iotests/065 | 2 +- tests/qemu-iotests/083 | 3 ++- tests/qemu-iotests/check | 18 ++++++++++++++++-- 9 files changed, 64 insertions(+), 43 deletions(-) (limited to 'tests') diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031 index 1d920ea87a..5aefb88b60 100755 --- a/tests/qemu-iotests/031 +++ b/tests/qemu-iotests/031 @@ -35,6 +35,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter . ./common.pattern @@ -56,22 +57,22 @@ for IMGOPTS in "compat=0.10" "compat=1.1"; do echo === Create image with unknown header extension === echo _make_test_img 64M - ./qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test header extension" - ./qcow2.py "$TEST_IMG" dump-header + $PYTHON qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test header extension" + $PYTHON qcow2.py "$TEST_IMG" dump-header _check_test_img echo echo === Rewrite header with no backing file === echo $QEMU_IMG rebase -u -b "" "$TEST_IMG" - ./qcow2.py "$TEST_IMG" dump-header + $PYTHON qcow2.py "$TEST_IMG" dump-header _check_test_img echo echo === Add a backing file and format === echo $QEMU_IMG rebase -u -b "/some/backing/file/path" -F host_device "$TEST_IMG" - ./qcow2.py "$TEST_IMG" dump-header + $PYTHON qcow2.py "$TEST_IMG" dump-header done # success, all done diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036 index 03b6aa9de7..29c35d1004 100755 --- a/tests/qemu-iotests/036 +++ b/tests/qemu-iotests/036 @@ -38,6 +38,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter . ./common.pattern @@ -53,15 +54,15 @@ IMGOPTS="compat=1.1" echo === Create image with unknown autoclear feature bit === echo _make_test_img 64M -./qcow2.py "$TEST_IMG" set-feature-bit autoclear 63 -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 63 +$PYTHON qcow2.py "$TEST_IMG" dump-header echo echo === Repair image === echo _check_test_img -r all -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header # success, all done echo "*** done" diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039 index b9cbe99560..b7b70300fc 100755 --- a/tests/qemu-iotests/039 +++ b/tests/qemu-iotests/039 @@ -38,6 +38,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter @@ -58,7 +59,7 @@ _make_test_img $size $QEMU_IO -c "write -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io # The dirty bit must not be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features _check_test_img echo @@ -73,7 +74,7 @@ $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" | _filter_qemu_io ulimit -c "$old_ulimit" # The dirty bit must be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features _check_test_img echo @@ -82,7 +83,7 @@ echo "== Read-only access must still work ==" $QEMU_IO -r -c "read -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io # The dirty bit must be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features echo echo "== Repairing the image file must succeed ==" @@ -90,7 +91,7 @@ echo "== Repairing the image file must succeed ==" _check_test_img -r all # The dirty bit must not be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features echo echo "== Data should still be accessible after repair ==" @@ -109,12 +110,12 @@ $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" | _filter_qemu_io ulimit -c "$old_ulimit" # The dirty bit must be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features $QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io # The dirty bit must not be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features echo echo "== Creating an image file with lazy_refcounts=off ==" @@ -128,7 +129,7 @@ $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" | _filter_qemu_io ulimit -c "$old_ulimit" # The dirty bit must not be set since lazy_refcounts=off -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features _check_test_img echo @@ -144,8 +145,8 @@ $QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IMG commit "$TEST_IMG" # The dirty bit must not be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features -./qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features _check_test_img TEST_IMG="$TEST_IMG".base _check_test_img diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054 index c8b7082b4e..a5ebf99450 100755 --- a/tests/qemu-iotests/054 +++ b/tests/qemu-iotests/054 @@ -35,6 +35,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter @@ -49,7 +50,7 @@ _make_test_img $((1024*1024))T echo echo "creating too large image (1 EB) using qcow2.py" _make_test_img 4G -./qcow2.py "$TEST_IMG" set-header size $((1024 ** 6)) +$PYTHON qcow2.py "$TEST_IMG" set-header size $((1024 ** 6)) _check_test_img # success, all done diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index f0116aab1d..5447b27a1a 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -35,6 +35,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter @@ -68,13 +69,13 @@ poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00" _check_test_img # The corrupt bit should not be set anyway -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Try to write something, thereby forcing the corrupt bit to be set $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io # The corrupt bit must now be set -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Try to open the image R/W (which should fail) $QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \ @@ -99,19 +100,19 @@ poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01" # Redirect new data cluster onto refcount block poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00" _check_test_img -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Try to fix it _check_test_img -r all # The corrupt bit should be cleared -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Look if it's really really fixed $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features echo echo "=== Testing cluster data reference into inactive L2 table ===" @@ -124,13 +125,13 @@ $QEMU_IO -c "$OPEN_RW" -c "write -P 2 0 512" | _filter_qemu_io poke_file "$TEST_IMG" "$l2_offset_after_snapshot" \ "\x80\x00\x00\x00\x00\x04\x00\x00" _check_test_img -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features $QEMU_IO -c "$OPEN_RW" -c "write -P 3 0 512" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features _check_test_img -r all -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features $QEMU_IO -c "$OPEN_RW" -c "write -P 4 0 512" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features # Check data $QEMU_IO -c "$OPEN_RO" -c "read -P 4 0 512" | _filter_qemu_io diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 index d3a6b388b5..0de789734f 100755 --- a/tests/qemu-iotests/061 +++ b/tests/qemu-iotests/061 @@ -35,6 +35,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter @@ -48,9 +49,9 @@ echo "=== Testing version downgrade with zero expansion ===" echo IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M $QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG" -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io _check_test_img @@ -59,9 +60,9 @@ echo "=== Testing dirty version downgrade ===" echo IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M $QEMU_IO -c "write -P 0x2a 0 128k" -c flush -c abort "$TEST_IMG" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG" -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IO -c "read -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io _check_test_img @@ -69,11 +70,11 @@ echo echo "=== Testing version downgrade with unknown compat/autoclear flags ===" echo IMGOPTS="compat=1.1" _make_test_img 64M -./qcow2.py "$TEST_IMG" set-feature-bit compatible 42 -./qcow2.py "$TEST_IMG" set-feature-bit autoclear 42 -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit compatible 42 +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 42 +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG" -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header _check_test_img echo @@ -81,9 +82,9 @@ echo "=== Testing version upgrade and resize ===" echo IMGOPTS="compat=0.10" _make_test_img 64M $QEMU_IO -c "write -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "compat=1.1,lazy_refcounts=on,size=128M" "$TEST_IMG" -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IO -c "read -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io _check_test_img @@ -92,9 +93,9 @@ echo "=== Testing dirty lazy_refcounts=off ===" echo IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M $QEMU_IO -c "write -P 0x2a 0 128k" -c flush -c abort "$TEST_IMG" | _filter_qemu_io -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "lazy_refcounts=off" "$TEST_IMG" -./qcow2.py "$TEST_IMG" dump-header +$PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IO -c "read -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io _check_test_img diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065 index ab5445f62d..e89b61d70b 100755 --- a/tests/qemu-iotests/065 +++ b/tests/qemu-iotests/065 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # # Test for additional information emitted by qemu-img info on qcow2 # images diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083 index f764534782..6a52c96bba 100755 --- a/tests/qemu-iotests/083 +++ b/tests/qemu-iotests/083 @@ -29,6 +29,7 @@ tmp=/tmp/$$ status=1 # failure is the default! # get standard environment, filters and checks +. ./common.env . ./common.rc . ./common.filter @@ -81,7 +82,7 @@ EOF nbd_url="nbd:127.0.0.1:$port:exportname=foo" fi - ./nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null & + $PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null & wait_for_tcp_port "127.0.0.1:$port" $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | filter_nbd diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index e2ed5a95f8..ca2ee43d3b 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -34,6 +34,13 @@ timestamp=${TIMESTAMP:=false} # generic initialization iam=check +# we need common.env +if ! . ./common.env +then + echo "$iam: failed to source common.env" + exit 1 +fi + # we need common.config if ! . ./common.config then @@ -215,9 +222,16 @@ do start=`_wallclock` $timestamp && echo -n " ["`date "+%T"`"]" - [ ! -x $seq ] && chmod u+x $seq # ensure we can run it + + if [ "$(head -n 1 $seq)" == "#!/usr/bin/env python" ]; then + run_command="$PYTHON $seq" + else + [ ! -x $seq ] && chmod u+x $seq # ensure we can run it + run_command="./$seq" + fi + MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ - ./$seq >$tmp.out 2>&1 + $run_command >$tmp.out 2>&1 sts=$? $timestamp && _timestamp stop=`_wallclock` -- cgit v1.2.1 From 74fe188cd1a27a5565787152d8620f8b8d04c4f9 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 6 May 2014 21:08:45 +0800 Subject: vmdk: Implement .bdrv_get_info() This will return cluster_size and needs_compressed_writes to caller, if all the extents have the same value (or there's only one extent). Otherwise return -ENOTSUP. cluster_size is only reported for sparse formats. Signed-off-by: Fam Zheng Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/059.out | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 3371c867bb..14c0957126 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -2050,6 +2050,7 @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least image: TEST_DIR/iotest-version3.IMGFMT file format: IMGFMT virtual size: 1.0G (1073741824 bytes) +cluster_size: 65536 === Testing 4TB monolithicFlat creation and IO === Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104 -- cgit v1.2.1 From 10f08a0a3435afea441db8d0981dbad49042c7cf Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 6 May 2014 21:08:46 +0800 Subject: qemu-iotests: Test converting to streamOptimized from small cluster size Signed-off-by: Fam Zheng Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/059 | 7 +++++++ tests/qemu-iotests/059.out | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'tests') diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059 index ca5aa16ff7..26a2fd3e0e 100755 --- a/tests/qemu-iotests/059 +++ b/tests/qemu-iotests/059 @@ -103,6 +103,13 @@ IMGOPTS="subformat=monolithicSparse" _make_test_img 100G truncate -s 10M $TEST_IMG _img_info +echo +echo "=== Converting to streamOptimized from image with small cluster size===" +TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 IMGOPTS="cluster_size=4096" _make_test_img 1G +$QEMU_IO -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io +$QEMU_IO -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io +$QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1 + echo echo "=== Testing version 3 ===" _use_sample_img iotest-version3.vmdk.bz2 diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 14c0957126..eba0dedda0 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -2046,6 +2046,13 @@ RW 12582912 VMFS "dummy.IMGFMT" 1 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes +=== Converting to streamOptimized from image with small cluster size=== +Formatting 'TEST_DIR/t.vmdk.IMGFMT', fmt=IMGFMT size=1073741824 +wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 512/512 bytes at offset 10240 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + === Testing version 3 === image: TEST_DIR/iotest-version3.IMGFMT file format: IMGFMT -- cgit v1.2.1 From b1e6fc0817dca14a3581d7b0979a5885608981f2 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 6 May 2014 12:11:42 +0200 Subject: block: Fix open flags with BDRV_O_SNAPSHOT The immediately visible effect of this patch is that it fixes committing a temporary snapshot to its backing file. Previously, it would fail with a "permission denied" error because bdrv_inherited_flags() forced the backing file to be read-only, ignoring the r/w reopen of bdrv_commit(). The bigger problem this revealed is that the original open flags must actually only be applied to the temporary snapshot, and the original image file must be treated as a backing file of the temporary snapshot and get the right flags for that. Reported-by: Jan Kiszka Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/051 | 4 ++++ tests/qemu-iotests/051.out | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'tests') diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 073dc7a2d3..c4af131a66 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -233,6 +233,10 @@ echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="$TEST_IMG", $QEMU_IO -c "read -P 0x22 0 4k" "$TEST_IMG" | _filter_qemu_io +echo -e 'qemu-io ide0-hd0 "write -P 0x33 0 4k"\ncommit ide0-hd0' | run_qemu -drive file="$TEST_IMG",snapshot=on | _filter_qemu_io + +$QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 01b0384472..31e329e893 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -356,6 +356,16 @@ wrote 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) (qemu) qququiquit +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x3qemu-io ide0-hd0 "write -P 0x33qemu-io ide0-hd0 "write -P 0x33 qemu-io ide0-hd0 "write -P 0x33 0qemu-io ide0-hd0 "write -P 0x33 0 qemu-io ide0-hd0 "write -P 0x33 0 4qemu-io ide0-hd0 "write -P 0x33 0 4kqemu-io ide0-hd0 "write -P 0x33 0 4k" +wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +(qemu) ccocomcommcommicommitcommit commit icommit idcommit idecommit ide0commit ide0-commit ide0-hcommit ide0-hdcommit ide0-hd0 +(qemu) qququiquit + read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) *** done -- cgit v1.2.1 From e940bc13ee15d6304f3a467961b9f33fc0f25595 Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Wed, 30 Apr 2014 10:55:08 -0400 Subject: block: qemu-iotests - add common.qemu, for bash-controlled qemu tests This creates some common functions for bash language qemu-iotests to control, and communicate with, a running QEMU process. 4 functions are introduced: 1. _launch_qemu() This launches the QEMU process(es), and sets up the file descriptors and fifos for communication. You can choose to launch each QEMU process listening for either QMP or HMP monitor. You can call this function multiple times, and save the handle returned from each. The returned handle is in $QEMU_HANDLE. You must copy this value. Commands 2 and 3 use the handle received from _launch_qemu(), to talk to the appropriate process. 2. _send_qemu_cmd() Sends a command string, specified by $2, to QEMU. If $3 is non-NULL, _send_qemu_cmd() will wait to receive $3 as a required result string from QEMU. Failure to receive $3 will cause the test to fail. The command can optionally be retried $qemu_cmd_repeat number of times. Set $qemu_error_no_exit to not force the test the fail on exit; in this case, $QEMU_STATUS[$1] will be set to -1 on failure. 3. _timed_wait_for() Waits for a response, for up to a default of 10 seconds. If $2 is not seen in that time (anywhere in the response), then the test fails. Primarily used by _send_qemu_cmd, but could be useful standalone, as well. To prevent automatic exit (and therefore test failure), set $qemu_error_no_exit to a non-NULL value. If $silent is a non-NULL value, then output to stdout will be suppressed. 4. _cleanup_qemu() Kills the running QEMU processes, and removes the fifos. Signed-off-by: Jeff Cody Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/common.qemu | 200 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 tests/qemu-iotests/common.qemu (limited to 'tests') diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu new file mode 100644 index 0000000000..918af3102c --- /dev/null +++ b/tests/qemu-iotests/common.qemu @@ -0,0 +1,200 @@ +#!/bin/bash +# +# This allows for launching of multiple QEMU instances, with independent +# communication possible to each instance. +# +# Each instance can choose, at launch, to use either the QMP or the +# HMP (monitor) interface. +# +# All instances are cleaned up via _cleanup_qemu, including killing the +# running qemu instance. +# +# 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 . +# + +QEMU_COMM_TIMEOUT=10 + +QEMU_FIFO_IN="${TEST_DIR}/qmp-in-$$" +QEMU_FIFO_OUT="${TEST_DIR}/qmp-out-$$" + +QEMU_PID= +_QEMU_HANDLE=0 +QEMU_HANDLE=0 + +# If bash version is >= 4.1, these will be overwritten and dynamic +# file descriptor values assigned. +_out_fd=3 +_in_fd=4 + +# Wait for expected QMP response from QEMU. Will time out +# after 10 seconds, which counts as failure. +# +# Override QEMU_COMM_TIMEOUT for a timeout different than the +# default 10 seconds +# +# $1: The handle to use +# $2+ All remaining arguments comprise the string to search for +# in the response. +# +# If $silent is set to anything but an empty string, then +# response is not echoed out. +function _timed_wait_for() +{ + local h=${1} + shift + + QEMU_STATUS[$h]=0 + while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]} + do + if [ -z "${silent}" ]; then + echo "${resp}" | _filter_testdir | _filter_qemu \ + | _filter_qemu_io | _filter_qmp + fi + grep -q "${*}" < <(echo ${resp}) + if [ $? -eq 0 ]; then + return + fi + done + QEMU_STATUS[$h]=-1 + if [ -z "${qemu_error_no_exit}" ]; then + echo "Timeout waiting for ${*} on handle ${h}" + exit 1 # Timeout means the test failed + fi +} + + +# Sends QMP or HMP command to QEMU, and waits for the expected response +# +# $1: QEMU handle to use +# $2: String of the QMP command to send +# ${@: -1} (Last string passed) +# String that the QEMU response should contain. If it is a null +# string, do not wait for a response +# +# Set qemu_cmd_repeat to the number of times to repeat the cmd +# until either timeout, or a response. If it is not set, or <=0, +# then the command is only sent once. +# +# If $qemu_error_no_exit is set, then even if the expected response +# is not seen, we will not exit. $QEMU_STATUS[$1] will be set it -1 in +# that case. +function _send_qemu_cmd() +{ + local h=${1} + local count=1 + local cmd= + local use_error=${qemu_error_no_exit} + shift + + if [ ${qemu_cmd_repeat} -gt 0 ] 2>/dev/null; then + count=${qemu_cmd_repeat} + use_error="no" + fi + # This array element extraction is done to accomodate pathnames with spaces + cmd=${@: 1:${#@}-1} + shift $(($# - 1)) + + while [ ${count} -gt 0 ] + do + echo "${cmd}" >&${QEMU_IN[${h}]} + if [ -n "${1}" ]; then + qemu_error_no_exit=${use_error} _timed_wait_for ${h} "${1}" + if [ ${QEMU_STATUS[$h]} -eq 0 ]; then + return + fi + fi + let count--; + done + if [ ${QEMU_STATUS[$h]} -ne 0 ] && [ -z "${qemu_error_no_exit}" ]; then + echo "Timeout waiting for ${1} on handle ${h}" + exit 1 #Timeout means the test failed + fi +} + + +# Launch a QEMU process. +# +# Input parameters: +# $qemu_comm_method: set this variable to 'monitor' (case insensitive) +# to use the QEMU HMP monitor for communication. +# Otherwise, the default of QMP is used. +# Returns: +# $QEMU_HANDLE: set to a handle value to communicate with this QEMU instance. +# +function _launch_qemu() +{ + local comm= + local fifo_out= + local fifo_in= + + if (shopt -s nocasematch; [[ "${qemu_comm_method}" == "monitor" ]]) + then + comm="-monitor stdio" + else + local qemu_comm_method="qmp" + comm="-monitor none -qmp stdio" + fi + + fifo_out=${QEMU_FIFO_OUT}_${_QEMU_HANDLE} + fifo_in=${QEMU_FIFO_IN}_${_QEMU_HANDLE} + mkfifo "${fifo_out}" + mkfifo "${fifo_in}" + + "${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" 2>&1 \ + >"${fifo_out}" \ + <"${fifo_in}" & + QEMU_PID[${_QEMU_HANDLE}]=$! + + if [[ "${BASH_VERSINFO[0]}" -ge "5" || + ("${BASH_VERSINFO[0]}" -ge "4" && "${BASH_VERSINFO[1]}" -ge "1") ]] + then + # bash >= 4.1 required for automatic fd + exec {_out_fd}<"${fifo_out}" + exec {_in_fd}>"${fifo_in}" + else + let _out_fd++ + let _in_fd++ + eval "exec ${_out_fd}<'${fifo_out}'" + eval "exec ${_in_fd}>'${fifo_in}'" + fi + + QEMU_OUT[${_QEMU_HANDLE}]=${_out_fd} + QEMU_IN[${_QEMU_HANDLE}]=${_in_fd} + QEMU_STATUS[${_QEMU_HANDLE}]=0 + + if [ "${qemu_comm_method}" == "qmp" ] + then + # Don't print response, since it has version information in it + silent=yes _timed_wait_for ${_QEMU_HANDLE} "capabilities" + fi + QEMU_HANDLE=${_QEMU_HANDLE} + let _QEMU_HANDLE++ +} + + +# Silenty kills the QEMU process +function _cleanup_qemu() +{ + # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices + for i in "${!QEMU_OUT[@]}" + do + kill -KILL ${QEMU_PID[$i]} 2>/dev/null + wait ${QEMU_PID[$i]} 2>/dev/null # silent kill + rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}" + eval "exec ${QEMU_IN[$i]}<&-" # close file descriptors + eval "exec ${QEMU_OUT[$i]}<&-" + done +} -- cgit v1.2.1 From e86e8697708ada85ce4b8f9df00342912f7ca14c Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Wed, 30 Apr 2014 10:55:09 -0400 Subject: block: qemu-iotests - update 085 to use common.qemu The new functionality of common.qemu implements the QEMU control and communication functionality that was originally in test 085. This removes that now-duplicate functionality, and uses the common.qemu functions. The QEMU commandline changes slightly due to this; in addition to monitor and qmp i/o options, the new QEMU commandline from inside common.qemu now introduces -machine accel=qtest. Reviewed-by: Benoit Canet Reviewed-by: Fam Zheng Signed-off-by: Jeff Cody Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/085 | 73 +++++++++----------------------------------------- 1 file changed, 12 insertions(+), 61 deletions(-) (limited to 'tests') diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085 index 33c8dc410a..56cd6f89b7 100755 --- a/tests/qemu-iotests/085 +++ b/tests/qemu-iotests/085 @@ -30,10 +30,6 @@ 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" @@ -42,10 +38,7 @@ MAX_SNAPSHOTS=10 _cleanup() { - kill -KILL ${qemu_pid} - wait ${qemu_pid} 2>/dev/null # silent kill - - rm -f "${QMP_IN}" "${QMP_OUT}" + _cleanup_qemu for i in $(seq 1 ${MAX_SNAPSHOTS}) do rm -f "${TEST_DIR}/${i}-${snapshot_virt0}" @@ -59,43 +52,12 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks . ./common.rc . ./common.filter +. ./common.qemu _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() @@ -104,7 +66,7 @@ function create_single_snapshot() 'arguments': { 'device': 'virtio0', 'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"', 'format': 'qcow2' } }" - send_qmp_cmd "${cmd}" "return" + _send_qemu_cmd $h "${cmd}" "return" } # ${1}: unique identifier for the snapshot filename @@ -120,14 +82,11 @@ function create_group_snapshot() 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ] } }" - send_qmp_cmd "${cmd}" "return" + _send_qemu_cmd $h "${cmd}" "return" } size=128M -mkfifo "${QMP_IN}" -mkfifo "${QMP_OUT}" - _make_test_img $size mv "${TEST_IMG}" "${TEST_IMG}.orig" _make_test_img $size @@ -136,23 +95,15 @@ 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" +qemu_comm_method="qmp" +_launch_qemu -drive file="${TEST_IMG}.orig",if=virtio -drive file="${TEST_IMG}",if=virtio +h=$QEMU_HANDLE echo echo === Sending capabilities === echo -send_qmp_cmd "{ 'execute': 'qmp_capabilities' }" "return" +_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return" echo echo === Create a single snapshot on virtio0 === @@ -165,16 +116,16 @@ echo echo === Invalid command - missing device and nodename === echo -send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync', - 'arguments': { 'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}', +_send_qemu_cmd $h "{ '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', +_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync', + 'arguments': { 'device': 'virtio0', 'format': 'qcow2' } }" "error" echo echo -- cgit v1.2.1 From fd040174ac7c302365c1d6dc5646f957972d67d6 Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Wed, 30 Apr 2014 10:55:10 -0400 Subject: block: qemu-iotests - test for live migration This is an initial, simple live migration test from one running VM to another, using monitor commands. This is also an example of using the new common.qemu functions for controlling multiple running qemu instances, for tests that need a live qemu vm. Reviewed-by: Fam Zheng Signed-off-by: Jeff Cody Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/091 | 105 +++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/091.out | 28 ++++++++++++ tests/qemu-iotests/group | 1 + 3 files changed, 134 insertions(+) create mode 100755 tests/qemu-iotests/091 create mode 100644 tests/qemu-iotests/091.out (limited to 'tests') diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091 new file mode 100755 index 0000000000..384b3ace54 --- /dev/null +++ b/tests/qemu-iotests/091 @@ -0,0 +1,105 @@ +#!/bin/bash +# +# Live migration test +# +# Performs a migration from one VM to another via monitor commands +# +# 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! + +MIG_FIFO="${TEST_DIR}/migrate" + +_cleanup() +{ + rm -f "${MIG_FIFO}" + _cleanup_qemu + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +size=1G + +_make_test_img $size + +mkfifo "${MIG_FIFO}" + +echo +echo === Starting QEMU VM1 === +echo + +qemu_comm_method="monitor" +_launch_qemu -drive file="${TEST_IMG}",cache=none,id=disk +h1=$QEMU_HANDLE + +echo +echo === Starting QEMU VM2 === +echo +_launch_qemu -drive file="${TEST_IMG}",cache=none,id=disk \ + -incoming "exec: cat '${MIG_FIFO}'" +h2=$QEMU_HANDLE + +echo +echo === VM 1: Migrate from VM1 to VM2 === +echo + +silent=yes +_send_qemu_cmd $h1 'qemu-io disk "write -P 0x22 0 4M"' "(qemu)" +echo "vm1: qemu-io disk write complete" +_send_qemu_cmd $h1 "migrate \"exec: cat > '${MIG_FIFO}'\"" "(qemu)" +echo "vm1: live migration started" +qemu_cmd_repeat=20 _send_qemu_cmd $h1 "info migrate" "completed" +echo "vm1: live migration completed" + +echo +echo === VM 2: Post-migration, write to disk, verify running === +echo + +_send_qemu_cmd $h2 'qemu-io disk "write 4M 1M"' "(qemu)" +echo "vm2: qemu-io disk write complete" +qemu_cmd_repeat=20 _send_qemu_cmd $h2 "info status" "running" +echo "vm2: qemu process running successfully" + +echo "vm2: flush io, and quit" +_send_qemu_cmd $h2 'qemu-io disk flush' "(qemu)" +_send_qemu_cmd $h2 'quit' "" + +echo "Check image pattern" +${QEMU_IO} -c "read -P 0x22 0 4M" "${TEST_IMG}" | _filter_testdir | _filter_qemu_io + +echo "Running 'qemu-img check -r all \$TEST_IMG'" +"${QEMU_IMG}" check -r all "${TEST_IMG}" 2>&1 | _filter_testdir | _filter_qemu + +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/091.out b/tests/qemu-iotests/091.out new file mode 100644 index 0000000000..a2e0122966 --- /dev/null +++ b/tests/qemu-iotests/091.out @@ -0,0 +1,28 @@ +QA output created by 091 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 + +=== Starting QEMU VM1 === + + +=== Starting QEMU VM2 === + + +=== VM 1: Migrate from VM1 to VM2 === + +vm1: qemu-io disk write complete +vm1: live migration started +vm1: live migration completed + +=== VM 2: Post-migration, write to disk, verify running === + +vm2: qemu-io disk write complete +vm2: qemu process running successfully +vm2: flush io, and quit +Check image pattern +read 4194304/4194304 bytes at offset 0 +4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Running 'qemu-img check -r all $TEST_IMG' +No errors were found on the image. +80/16384 = 0.49% allocated, 0.00% fragmented, 0.00% compressed clusters +Image end offset: 5570560 +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index ae096638b8..cd3e4d2c27 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -96,3 +96,4 @@ 087 rw auto 088 rw auto 090 rw auto quick +091 rw auto -- cgit v1.2.1