aboutsummaryrefslogtreecommitdiff
path: root/tests/qemu-iotests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/qemu-iotests')
-rwxr-xr-xtests/qemu-iotests/0319
-rwxr-xr-xtests/qemu-iotests/0367
-rwxr-xr-xtests/qemu-iotests/03919
-rwxr-xr-xtests/qemu-iotests/0514
-rw-r--r--tests/qemu-iotests/051.out10
-rwxr-xr-xtests/qemu-iotests/0543
-rwxr-xr-xtests/qemu-iotests/0597
-rw-r--r--tests/qemu-iotests/059.out8
-rwxr-xr-xtests/qemu-iotests/06021
-rwxr-xr-xtests/qemu-iotests/06125
-rwxr-xr-xtests/qemu-iotests/0652
-rwxr-xr-xtests/qemu-iotests/0833
-rwxr-xr-xtests/qemu-iotests/08573
-rwxr-xr-xtests/qemu-iotests/091105
-rw-r--r--tests/qemu-iotests/091.out28
-rwxr-xr-xtests/qemu-iotests/check18
-rw-r--r--tests/qemu-iotests/common.qemu200
-rw-r--r--tests/qemu-iotests/group1
18 files changed, 439 insertions, 104 deletions
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/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
@@ -358,4 +358,14 @@ wrote 4096/4096 bytes at offset 0
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
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/059 b/tests/qemu-iotests/059
index ca5aa16ff7..26a2fd3e0e 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -104,6 +104,13 @@ 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
_img_info
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 3371c867bb..eba0dedda0 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2046,10 +2046,18 @@ 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
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
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/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
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 <http://www.gnu.org/licenses/>.
+#
+
+# 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/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`
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 <http://www.gnu.org/licenses/>.
+#
+
+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
+}
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