aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-10-28 14:40:00 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-10-28 14:40:01 +0000
commitaaffb853359829a37daaf883c773e8320b55c723 (patch)
tree65d111156f4480afe7cb6c4552d490eb1947e3cd /tests
parent9bb73502321d46f4d320fa17aa38201445783fc4 (diff)
parentba9c45139e2938b8d20ce407db83a31bc9e5066c (diff)
downloadqemu-aaffb853359829a37daaf883c773e8320b55c723.zip
qemu-aaffb853359829a37daaf883c773e8320b55c723.tar.gz
qemu-aaffb853359829a37daaf883c773e8320b55c723.tar.bz2
Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2019-10-28' into staging
Block patches for softfreeze: - iotest patches - Improve performance of the mirror block job in write-blocking mode - Limit memory usage for the backup block job - Add discard and write-zeroes support to the NVMe host block driver - Fix a bug in the mirror job - Prevent the qcow2 driver from creating technically non-compliant qcow2 v3 images (where there is not enough extra data for snapshot table entries) - Allow callers of bdrv_truncate() (etc.) to determine whether the file must be resized to the exact given size or whether it is OK for block devices not to shrink # gpg: Signature made Mon 28 Oct 2019 12:13:53 GMT # gpg: using RSA key 91BEB60A30DB3E8857D11829F407DB0061D5CF40 # gpg: issuer "mreitz@redhat.com" # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" [full] # Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40 * remotes/maxreitz/tags/pull-block-2019-10-28: (69 commits) qemu-iotests: restrict 264 to qcow2 only Revert "qemu-img: Check post-truncation size" block: Pass truncate exact=true where reasonable block: Let format drivers pass @exact block: Evaluate @exact in protocol drivers block: Add @exact parameter to bdrv_co_truncate() block: Do not truncate file node when formatting block/cor: Drop cor_co_truncate() block: Handle filter truncation like native impl. iotests: Test qcow2's snapshot table handling iotests: Add peek_file* functions qcow2: Fix v3 snapshot table entry compliancy qcow2: Repair snapshot table with too many entries qcow2: Fix overly long snapshot tables qcow2: Keep track of the snapshot table length qcow2: Fix broken snapshot table entries qcow2: Add qcow2_check_fix_snapshot_table() qcow2: Separate qcow2_check_read_snapshot_table() qcow2: Write v3-compliant snapshot list on upgrade qcow2: Put qcow2_upgrade() into its own function ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rwxr-xr-xtests/qemu-iotests/0836
-rw-r--r--tests/qemu-iotests/083.out34
-rwxr-xr-xtests/qemu-iotests/09319
-rwxr-xr-xtests/qemu-iotests/13614
-rwxr-xr-xtests/qemu-iotests/1408
-rw-r--r--tests/qemu-iotests/140.out2
-rwxr-xr-xtests/qemu-iotests/1436
-rw-r--r--tests/qemu-iotests/143.out2
-rwxr-xr-xtests/qemu-iotests/1472
-rwxr-xr-xtests/qemu-iotests/1812
-rwxr-xr-xtests/qemu-iotests/1824
-rwxr-xr-xtests/qemu-iotests/1832
-rwxr-xr-xtests/qemu-iotests/1924
-rw-r--r--tests/qemu-iotests/192.out2
-rwxr-xr-xtests/qemu-iotests/1944
-rwxr-xr-xtests/qemu-iotests/2012
-rwxr-xr-xtests/qemu-iotests/2052
-rwxr-xr-xtests/qemu-iotests/2082
-rwxr-xr-xtests/qemu-iotests/2093
-rw-r--r--tests/qemu-iotests/2222
-rwxr-xr-xtests/qemu-iotests/22314
-rwxr-xr-xtests/qemu-iotests/2404
-rwxr-xr-xtests/qemu-iotests/2412
-rw-r--r--tests/qemu-iotests/2452
-rwxr-xr-xtests/qemu-iotests/261523
-rw-r--r--tests/qemu-iotests/261.out346
-rwxr-xr-xtests/qemu-iotests/2642
-rwxr-xr-xtests/qemu-iotests/2674
-rw-r--r--tests/qemu-iotests/267.out2
-rwxr-xr-xtests/qemu-iotests/check15
-rw-r--r--tests/qemu-iotests/common.filter7
-rw-r--r--tests/qemu-iotests/common.nbd2
-rw-r--r--tests/qemu-iotests/common.rc20
-rw-r--r--tests/qemu-iotests/group1
-rw-r--r--tests/qemu-iotests/iotests.py68
-rw-r--r--tests/test-block-iothread.c8
36 files changed, 1044 insertions, 98 deletions
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
index b270550..10fdfc8 100755
--- a/tests/qemu-iotests/083
+++ b/tests/qemu-iotests/083
@@ -28,7 +28,7 @@ status=1 # failure is the default!
_cleanup()
{
- rm -f nbd.sock
+ rm -f "$SOCK_DIR/nbd.sock"
rm -f nbd-fault-injector.out
rm -f nbd-fault-injector.conf
}
@@ -80,10 +80,10 @@ EOF
if [ "$proto" = "tcp" ]; then
nbd_addr="127.0.0.1:0"
else
- nbd_addr="$TEST_DIR/nbd.sock"
+ nbd_addr="$SOCK_DIR/nbd.sock"
fi
- rm -f "$TEST_DIR/nbd.sock"
+ rm -f "$SOCK_DIR/nbd.sock"
echo > "$TEST_DIR/nbd-fault-injector.out"
$PYTHON nbd-fault-injector.py $extra_args "$nbd_addr" "$TEST_DIR/nbd-fault-injector.conf" >"$TEST_DIR/nbd-fault-injector.out" 2>&1 &
diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out
index eee6dd1..2090ee6 100644
--- a/tests/qemu-iotests/083.out
+++ b/tests/qemu-iotests/083.out
@@ -110,43 +110,43 @@ read failed: Input/output error
=== Check disconnect before neg1 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect after neg1 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect 8 neg1 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect 16 neg1 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect before export ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect after export ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect 4 export ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect 12 export ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect 16 export ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect before neg2 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect after neg2 ===
@@ -154,11 +154,11 @@ read failed: Input/output error
=== Check disconnect 8 neg2 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect 10 neg2 ===
-qemu-io: can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect before request ===
@@ -195,23 +195,23 @@ read 512/512 bytes at offset 0
=== Check disconnect before neg-classic ===
-qemu-io: can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
=== Check disconnect 8 neg-classic ===
-qemu-io: can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
=== Check disconnect 16 neg-classic ===
-qemu-io: can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
=== Check disconnect 24 neg-classic ===
-qemu-io: can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
=== Check disconnect 28 neg-classic ===
-qemu-io: can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
+qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
=== Check disconnect after neg-classic ===
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
index 3c4f517..f03fa24 100755
--- a/tests/qemu-iotests/093
+++ b/tests/qemu-iotests/093
@@ -24,7 +24,7 @@ import iotests
nsec_per_sec = 1000000000
class ThrottleTestCase(iotests.QMPTestCase):
- test_img = "null-aio://"
+ test_driver = "null-aio"
max_drives = 3
def blockstats(self, device):
@@ -35,10 +35,14 @@ class ThrottleTestCase(iotests.QMPTestCase):
return stat['rd_bytes'], stat['rd_operations'], stat['wr_bytes'], stat['wr_operations']
raise Exception("Device not found for blockstats: %s" % device)
+ def required_drivers(self):
+ return [self.test_driver]
+
+ @iotests.skip_if_unsupported(required_drivers)
def setUp(self):
self.vm = iotests.VM()
for i in range(0, self.max_drives):
- self.vm.add_drive(self.test_img, "file.read-zeroes=on")
+ self.vm.add_drive(self.test_driver + "://", "file.read-zeroes=on")
self.vm.launch()
def tearDown(self):
@@ -264,16 +268,15 @@ class ThrottleTestCase(iotests.QMPTestCase):
self.assertEqual(self.blockstats('drive1')[0], 4096)
class ThrottleTestCoroutine(ThrottleTestCase):
- test_img = "null-co://"
+ test_driver = "null-co"
class ThrottleTestGroupNames(iotests.QMPTestCase):
- test_img = "null-aio://"
max_drives = 3
def setUp(self):
self.vm = iotests.VM()
for i in range(0, self.max_drives):
- self.vm.add_drive(self.test_img,
+ self.vm.add_drive("null-co://",
"throttling.iops-total=100,file.read-zeroes=on")
self.vm.launch()
@@ -376,10 +379,10 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
def test_removable_media(self):
# Add a couple of dummy nodes named cd0 and cd1
- result = self.vm.qmp("blockdev-add", driver="null-aio",
+ result = self.vm.qmp("blockdev-add", driver="null-co",
read_zeroes=True, node_name="cd0")
self.assert_qmp(result, 'return', {})
- result = self.vm.qmp("blockdev-add", driver="null-aio",
+ result = self.vm.qmp("blockdev-add", driver="null-co",
read_zeroes=True, node_name="cd1")
self.assert_qmp(result, 'return', {})
@@ -426,4 +429,6 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
if __name__ == '__main__':
+ if 'null-co' not in iotests.supported_formats():
+ iotests.notrun('null-co driver support missing')
iotests.main(supported_fmts=["raw"])
diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136
index a46a7b7..012ea11 100755
--- a/tests/qemu-iotests/136
+++ b/tests/qemu-iotests/136
@@ -30,7 +30,7 @@ bad_offset = bad_sector * 512
blkdebug_file = os.path.join(iotests.test_dir, 'blkdebug.conf')
class BlockDeviceStatsTestCase(iotests.QMPTestCase):
- test_img = "null-aio://"
+ test_driver = "null-aio"
total_rd_bytes = 0
total_rd_ops = 0
total_wr_bytes = 0
@@ -67,6 +67,10 @@ sector = "%d"
''' % (bad_sector, bad_sector))
file.close()
+ def required_drivers(self):
+ return [self.test_driver]
+
+ @iotests.skip_if_unsupported(required_drivers)
def setUp(self):
drive_args = []
drive_args.append("stats-intervals.0=%d" % interval_length)
@@ -76,8 +80,8 @@ sector = "%d"
(self.account_failed and "on" or "off"))
drive_args.append("file.image.read-zeroes=on")
self.create_blkdebug_file()
- self.vm = iotests.VM().add_drive('blkdebug:%s:%s' %
- (blkdebug_file, self.test_img),
+ self.vm = iotests.VM().add_drive('blkdebug:%s:%s://' %
+ (blkdebug_file, self.test_driver),
','.join(drive_args))
self.vm.launch()
# Set an initial value for the clock
@@ -337,7 +341,9 @@ class BlockDeviceStatsTestAccountBoth(BlockDeviceStatsTestCase):
account_failed = True
class BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
- test_img = "null-co://"
+ test_driver = "null-co"
if __name__ == '__main__':
+ if 'null-co' not in iotests.supported_formats():
+ iotests.notrun('null-co driver support missing')
iotests.main(supported_fmts=["raw"])
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
index b965b1d..8d2ce5d 100755
--- a/tests/qemu-iotests/140
+++ b/tests/qemu-iotests/140
@@ -34,7 +34,7 @@ _cleanup()
{
_cleanup_qemu
_cleanup_test_img
- rm -f "$TEST_DIR/nbd"
+ rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -69,7 +69,7 @@ _send_qemu_cmd $QEMU_HANDLE \
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'nbd-server-start',
'arguments': { 'addr': { 'type': 'unix',
- 'data': { 'path': '$TEST_DIR/nbd' }}}}" \
+ 'data': { 'path': '$SOCK_DIR/nbd' }}}}" \
'return'
_send_qemu_cmd $QEMU_HANDLE \
@@ -78,7 +78,7 @@ _send_qemu_cmd $QEMU_HANDLE \
'return'
$QEMU_IO_PROG -f raw -r -c 'read -P 42 0 64k' \
- "nbd+unix:///drv?socket=$TEST_DIR/nbd" 2>&1 \
+ "nbd+unix:///drv?socket=$SOCK_DIR/nbd" 2>&1 \
| _filter_qemu_io | _filter_nbd
_send_qemu_cmd $QEMU_HANDLE \
@@ -87,7 +87,7 @@ _send_qemu_cmd $QEMU_HANDLE \
'return'
$QEMU_IO_PROG -f raw -r -c close \
- "nbd+unix:///drv?socket=$TEST_DIR/nbd" 2>&1 \
+ "nbd+unix:///drv?socket=$SOCK_DIR/nbd" 2>&1 \
| _filter_qemu_io | _filter_nbd
_send_qemu_cmd $QEMU_HANDLE \
diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
index 67fe44a..2511eb7 100644
--- a/tests/qemu-iotests/140.out
+++ b/tests/qemu-iotests/140.out
@@ -8,7 +8,7 @@ wrote 65536/65536 bytes at offset 0
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
-qemu-io: can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: Requested export not available
+qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available
server reported: export 'drv' not present
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
index 92249ac..f649b36 100755
--- a/tests/qemu-iotests/143
+++ b/tests/qemu-iotests/143
@@ -29,7 +29,7 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_qemu
- rm -f "$TEST_DIR/nbd"
+ rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -51,12 +51,12 @@ _send_qemu_cmd $QEMU_HANDLE \
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'nbd-server-start',
'arguments': { 'addr': { 'type': 'unix',
- 'data': { 'path': '$TEST_DIR/nbd' }}}}" \
+ 'data': { 'path': '$SOCK_DIR/nbd' }}}}" \
'return'
# This should just result in a client error, not in the server crashing
$QEMU_IO_PROG -f raw -c quit \
- "nbd+unix:///no_such_export?socket=$TEST_DIR/nbd" 2>&1 \
+ "nbd+unix:///no_such_export?socket=$SOCK_DIR/nbd" 2>&1 \
| _filter_qemu_io | _filter_nbd
_send_qemu_cmd $QEMU_HANDLE \
diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
index ee71b5a..037d34a 100644
--- a/tests/qemu-iotests/143.out
+++ b/tests/qemu-iotests/143.out
@@ -1,7 +1,7 @@
QA output created by 143
{"return": {}}
{"return": {}}
-qemu-io: can't open device nbd+unix:///no_such_export?socket=TEST_DIR/nbd: Requested export not available
+qemu-io: can't open device nbd+unix:///no_such_export?socket=SOCK_DIR/nbd: Requested export not available
server reported: export 'no_such_export' not present
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
index ab8480b..03fc2fa 100755
--- a/tests/qemu-iotests/147
+++ b/tests/qemu-iotests/147
@@ -32,7 +32,7 @@ NBD_IPV6_PORT_START = NBD_PORT_END
NBD_IPV6_PORT_END = NBD_IPV6_PORT_START + 1024
test_img = os.path.join(iotests.test_dir, 'test.img')
-unix_socket = os.path.join(iotests.test_dir, 'nbd.socket')
+unix_socket = os.path.join(iotests.sock_dir, 'nbd.socket')
def flatten_sock_addr(crumpled_address):
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
index e317e63..378c289 100755
--- a/tests/qemu-iotests/181
+++ b/tests/qemu-iotests/181
@@ -26,7 +26,7 @@ echo "QA output created by $seq"
status=1 # failure is the default!
-MIG_SOCKET="${TEST_DIR}/migrate"
+MIG_SOCKET="${SOCK_DIR}/migrate"
_cleanup()
{
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
index 7f494eb..1ccb850 100755
--- a/tests/qemu-iotests/182
+++ b/tests/qemu-iotests/182
@@ -31,7 +31,7 @@ _cleanup()
{
_cleanup_test_img
rm -f "$TEST_IMG.overlay"
- rm -f "$TEST_DIR/nbd.socket"
+ rm -f "$SOCK_DIR/nbd.socket"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -133,7 +133,7 @@ success_or_failure=y _send_qemu_cmd $QEMU_HANDLE \
'addr': {
'type': 'unix',
'data': {
- 'path': '$TEST_DIR/nbd.socket'
+ 'path': '$SOCK_DIR/nbd.socket'
} } } }" \
'return' \
'error'
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
index 04fb344..bced83f 100755
--- a/tests/qemu-iotests/183
+++ b/tests/qemu-iotests/183
@@ -26,7 +26,7 @@ echo "QA output created by $seq"
status=1 # failure is the default!
-MIG_SOCKET="${TEST_DIR}/migrate"
+MIG_SOCKET="${SOCK_DIR}/migrate"
_cleanup()
{
diff --git a/tests/qemu-iotests/192 b/tests/qemu-iotests/192
index 0344322..d2ba55d 100755
--- a/tests/qemu-iotests/192
+++ b/tests/qemu-iotests/192
@@ -31,7 +31,7 @@ _cleanup()
{
_cleanup_qemu
_cleanup_test_img
- rm -f "$TEST_DIR/nbd"
+ rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -66,7 +66,7 @@ else
QEMU_COMM_TIMEOUT=1
fi
-_send_qemu_cmd $h "nbd_server_start unix:$TEST_DIR/nbd" "(qemu)"
+_send_qemu_cmd $h "nbd_server_start unix:$SOCK_DIR/nbd" "(qemu)"
_send_qemu_cmd $h "nbd_server_add -w drive0" "(qemu)"
_send_qemu_cmd $h "q" "(qemu)"
diff --git a/tests/qemu-iotests/192.out b/tests/qemu-iotests/192.out
index 1e0be4c..b9429db 100644
--- a/tests/qemu-iotests/192.out
+++ b/tests/qemu-iotests/192.out
@@ -1,7 +1,7 @@
QA output created by 192
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) nbd_server_start unix:TEST_DIR/nbd
+(qemu) nbd_server_start unix:SOCK_DIR/nbd
(qemu) nbd_server_add -w drive0
(qemu) q
*** done
diff --git a/tests/qemu-iotests/194 b/tests/qemu-iotests/194
index d746ab1..72e47e8 100755
--- a/tests/qemu-iotests/194
+++ b/tests/qemu-iotests/194
@@ -26,8 +26,8 @@ iotests.verify_platform(['linux'])
with iotests.FilePath('source.img') as source_img_path, \
iotests.FilePath('dest.img') as dest_img_path, \
- iotests.FilePath('migration.sock') as migration_sock_path, \
- iotests.FilePath('nbd.sock') as nbd_sock_path, \
+ iotests.FilePaths(['migration.sock', 'nbd.sock'], iotests.sock_dir) as \
+ [migration_sock_path, nbd_sock_path], \
iotests.VM('source') as source_vm, \
iotests.VM('dest') as dest_vm:
diff --git a/tests/qemu-iotests/201 b/tests/qemu-iotests/201
index 7abf740..86fa37e 100755
--- a/tests/qemu-iotests/201
+++ b/tests/qemu-iotests/201
@@ -24,7 +24,7 @@ echo "QA output created by $seq"
status=1 # failure is the default!
-MIG_SOCKET="${TEST_DIR}/migrate"
+MIG_SOCKET="${SOCK_DIR}/migrate"
# get standard environment, filters and checks
. ./common.rc
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
index 76f6c5f..4bb2c21 100755
--- a/tests/qemu-iotests/205
+++ b/tests/qemu-iotests/205
@@ -24,7 +24,7 @@ import iotests
import time
from iotests import qemu_img_create, qemu_io, filter_qemu_io, QemuIoInteractive
-nbd_sock = os.path.join(iotests.test_dir, 'nbd_sock')
+nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock')
nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock
disk = os.path.join(iotests.test_dir, 'disk')
diff --git a/tests/qemu-iotests/208 b/tests/qemu-iotests/208
index 1e20238..546eb1d 100755
--- a/tests/qemu-iotests/208
+++ b/tests/qemu-iotests/208
@@ -26,7 +26,7 @@ iotests.verify_image_format(supported_fmts=['generic'])
with iotests.FilePath('disk.img') as disk_img_path, \
iotests.FilePath('disk-snapshot.img') as disk_snapshot_img_path, \
- iotests.FilePath('nbd.sock') as nbd_sock_path, \
+ iotests.FilePath('nbd.sock', iotests.sock_dir) as nbd_sock_path, \
iotests.VM() as vm:
img_size = '10M'
diff --git a/tests/qemu-iotests/209 b/tests/qemu-iotests/209
index 259e991..e0f464b 100755
--- a/tests/qemu-iotests/209
+++ b/tests/qemu-iotests/209
@@ -24,7 +24,8 @@ from iotests import qemu_img_create, qemu_io, qemu_img_verbose, qemu_nbd, \
iotests.verify_image_format(supported_fmts=['qcow2'])
-disk, nbd_sock = file_path('disk', 'nbd-sock')
+disk = file_path('disk')
+nbd_sock = file_path('nbd-sock', base_dir=iotests.sock_dir)
nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock
qemu_img_create('-f', iotests.imgfmt, disk, '1M')
diff --git a/tests/qemu-iotests/222 b/tests/qemu-iotests/222
index 0ead56d..3f9f934 100644
--- a/tests/qemu-iotests/222
+++ b/tests/qemu-iotests/222
@@ -48,7 +48,7 @@ remainder = [("0xd5", "0x108000", "32k"), # Right-end of partial-left [1]
with iotests.FilePath('base.img') as base_img_path, \
iotests.FilePath('fleece.img') as fleece_img_path, \
- iotests.FilePath('nbd.sock') as nbd_sock_path, \
+ iotests.FilePath('nbd.sock', iotests.sock_dir) as nbd_sock_path, \
iotests.VM() as vm:
log('--- Setting up images ---')
diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223
index 2ba3d81..b5a80e5 100755
--- a/tests/qemu-iotests/223
+++ b/tests/qemu-iotests/223
@@ -28,7 +28,7 @@ _cleanup()
nbd_server_stop
_cleanup_test_img
_cleanup_qemu
- rm -f "$TEST_DIR/nbd"
+ rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -125,11 +125,11 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments":{"device":"n"}}' "error" # Attempt add without server
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start",
"arguments":{"addr":{"type":"unix",
- "data":{"path":"'"$TEST_DIR/nbd"'"}}}}' "return"
+ "data":{"path":"'"$SOCK_DIR/nbd"'"}}}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start",
"arguments":{"addr":{"type":"unix",
- "data":{"path":"'"$TEST_DIR/nbd"1'"}}}}' "error" # Attempt second server
-$QEMU_NBD_PROG -L -k "$TEST_DIR/nbd"
+ "data":{"path":"'"$SOCK_DIR/nbd"1'"}}}}' "error" # Attempt second server
+$QEMU_NBD_PROG -L -k "$SOCK_DIR/nbd"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments":{"device":"n", "bitmap":"b"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
@@ -145,14 +145,14 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments":{"device":"n", "name":"n2", "writable":true,
"bitmap":"b2"}}' "return"
-$QEMU_NBD_PROG -L -k "$TEST_DIR/nbd"
+$QEMU_NBD_PROG -L -k "$SOCK_DIR/nbd"
echo
echo "=== Contrast normal status to large granularity dirty-bitmap ==="
echo
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
-IMG="driver=nbd,export=n,server.type=unix,server.path=$TEST_DIR/nbd"
+IMG="driver=nbd,export=n,server.type=unix,server.path=$SOCK_DIR/nbd"
$QEMU_IO -r -c 'r -P 0x22 512 512' -c 'r -P 0 512k 512k' -c 'r -P 0x11 1m 1m' \
-c 'r -P 0x33 2m 2m' --image-opts "$IMG" | _filter_qemu_io
$QEMU_IMG map --output=json --image-opts \
@@ -164,7 +164,7 @@ echo
echo "=== Contrast to small granularity dirty-bitmap ==="
echo
-IMG="driver=nbd,export=n2,server.type=unix,server.path=$TEST_DIR/nbd"
+IMG="driver=nbd,export=n2,server.type=unix,server.path=$SOCK_DIR/nbd"
$QEMU_IMG map --output=json --image-opts \
"$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b2" | _filter_qemu_img_map
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
index f73bc07..8b4337b 100755
--- a/tests/qemu-iotests/240
+++ b/tests/qemu-iotests/240
@@ -29,7 +29,7 @@ status=1 # failure is the default!
_cleanup()
{
- rm -f "$TEST_DIR/nbd"
+ rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -135,7 +135,7 @@ echo
run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "read-zeroes": true, "node-name": "hd0", "read-only": true}}
-{ "execute": "nbd-server-start", "arguments": {"addr":{"type":"unix","data":{"path":"$TEST_DIR/nbd"}}}}
+{ "execute": "nbd-server-start", "arguments": {"addr":{"type":"unix","data":{"path":"$SOCK_DIR/nbd"}}}}
{ "execute": "nbd-server-add", "arguments": {"device":"hd0"}}
{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
diff --git a/tests/qemu-iotests/241 b/tests/qemu-iotests/241
index 58b64eb..8dae8d3 100755
--- a/tests/qemu-iotests/241
+++ b/tests/qemu-iotests/241
@@ -23,8 +23,6 @@ echo "QA output created by $seq"
status=1 # failure is the default!
-nbd_unix_socket=$TEST_DIR/test_qemu_nbd_socket
-
_cleanup()
{
_cleanup_test_img
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
index 41218d5..e66a23c 100644
--- a/tests/qemu-iotests/245
+++ b/tests/qemu-iotests/245
@@ -598,7 +598,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
##################
###### null ######
##################
- opts = {'driver': 'null-aio', 'node-name': 'root', 'size': 1024}
+ opts = {'driver': 'null-co', 'node-name': 'root', 'size': 1024}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261
new file mode 100755
index 0000000..fb96bcf
--- /dev/null
+++ b/tests/qemu-iotests/261
@@ -0,0 +1,523 @@
+#!/usr/bin/env bash
+#
+# Test case for qcow2's handling of extra data in snapshot table entries
+# (and more generally, how certain cases of broken snapshot tables are
+# handled)
+#
+# Copyright (C) 2019 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=mreitz@redhat.com
+
+seq=$(basename $0)
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+ rm -f "$TEST_IMG".v{2,3}.orig
+ rm -f "$TEST_DIR"/sn{0,1,2}{,-pre,-extra,-post}
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+# (1) We create a v2 image that supports nothing but refcount_bits=16
+# (2) We do some refcount management on our own which expects
+# refcount_bits=16
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
+
+# Parameters:
+# $1: image filename
+# $2: snapshot table entry offset in the image
+snapshot_table_entry_size()
+{
+ id_len=$(peek_file_be "$1" $(($2 + 12)) 2)
+ name_len=$(peek_file_be "$1" $(($2 + 14)) 2)
+ extra_len=$(peek_file_be "$1" $(($2 + 36)) 4)
+
+ full_len=$((40 + extra_len + id_len + name_len))
+ echo $(((full_len + 7) / 8 * 8))
+}
+
+# Parameter:
+# $1: image filename
+print_snapshot_table()
+{
+ nb_entries=$(peek_file_be "$1" 60 4)
+ offset=$(peek_file_be "$1" 64 8)
+
+ echo "Snapshots in $1:" | _filter_testdir | _filter_imgfmt
+
+ for ((i = 0; i < nb_entries; i++)); do
+ id_len=$(peek_file_be "$1" $((offset + 12)) 2)
+ name_len=$(peek_file_be "$1" $((offset + 14)) 2)
+ extra_len=$(peek_file_be "$1" $((offset + 36)) 4)
+
+ extra_ofs=$((offset + 40))
+ id_ofs=$((extra_ofs + extra_len))
+ name_ofs=$((id_ofs + id_len))
+
+ echo " [$i]"
+ echo " ID: $(peek_file_raw "$1" $id_ofs $id_len)"
+ echo " Name: $(peek_file_raw "$1" $name_ofs $name_len)"
+ echo " Extra data size: $extra_len"
+ if [ $extra_len -ge 8 ]; then
+ echo " VM state size: $(peek_file_be "$1" $extra_ofs 8)"
+ fi
+ if [ $extra_len -ge 16 ]; then
+ echo " Disk size: $(peek_file_be "$1" $((extra_ofs + 8)) 8)"
+ fi
+ if [ $extra_len -gt 16 ]; then
+ echo ' Unknown extra data:' \
+ "$(peek_file_raw "$1" $((extra_ofs + 16)) $((extra_len - 16)) \
+ | tr -d '\0')"
+ fi
+
+ offset=$((offset + $(snapshot_table_entry_size "$1" $offset)))
+ done
+}
+
+# Mark clusters as allocated; works only in refblock 0 (i.e. before
+# cluster #32768).
+# Parameters:
+# $1: Start offset of what to allocate
+# $2: End offset (exclusive)
+refblock0_allocate()
+{
+ reftable_ofs=$(peek_file_be "$TEST_IMG" 48 8)
+ refblock_ofs=$(peek_file_be "$TEST_IMG" $reftable_ofs 8)
+
+ cluster=$(($1 / 65536))
+ ecluster=$((($2 + 65535) / 65536))
+
+ while [ $cluster -lt $ecluster ]; do
+ if [ $cluster -ge 32768 ]; then
+ echo "*** Abort: Cluster $cluster exceeds refblock 0 ***"
+ exit 1
+ fi
+ poke_file "$TEST_IMG" $((refblock_ofs + cluster * 2)) '\x00\x01'
+ cluster=$((cluster + 1))
+ done
+}
+
+
+echo
+echo '=== Create v2 template ==='
+echo
+
+# Create v2 image with a snapshot table with three entries:
+# [0]: No extra data (valid with v2, not valid with v3)
+# [1]: Has extra data unknown to qemu
+# [2]: Has the 64-bit VM state size, but not the disk size (again,
+# valid with v2, not valid with v3)
+
+TEST_IMG="$TEST_IMG.v2.orig" IMGOPTS='compat=0.10' _make_test_img 64M
+$QEMU_IMG snapshot -c sn0 "$TEST_IMG.v2.orig"
+$QEMU_IMG snapshot -c sn1 "$TEST_IMG.v2.orig"
+$QEMU_IMG snapshot -c sn2 "$TEST_IMG.v2.orig"
+
+# Copy out all existing snapshot table entries
+sn_table_ofs=$(peek_file_be "$TEST_IMG.v2.orig" 64 8)
+
+# ofs: Snapshot table entry offset
+# eds: Extra data size
+# ids: Name + ID size
+# len: Total entry length
+sn0_ofs=$sn_table_ofs
+sn0_eds=$(peek_file_be "$TEST_IMG.v2.orig" $((sn0_ofs + 36)) 4)
+sn0_ids=$(($(peek_file_be "$TEST_IMG.v2.orig" $((sn0_ofs + 12)) 2) +
+ $(peek_file_be "$TEST_IMG.v2.orig" $((sn0_ofs + 14)) 2)))
+sn0_len=$(snapshot_table_entry_size "$TEST_IMG.v2.orig" $sn0_ofs)
+sn1_ofs=$((sn0_ofs + sn0_len))
+sn1_eds=$(peek_file_be "$TEST_IMG.v2.orig" $((sn1_ofs + 36)) 4)
+sn1_ids=$(($(peek_file_be "$TEST_IMG.v2.orig" $((sn1_ofs + 12)) 2) +
+ $(peek_file_be "$TEST_IMG.v2.orig" $((sn1_ofs + 14)) 2)))
+sn1_len=$(snapshot_table_entry_size "$TEST_IMG.v2.orig" $sn1_ofs)
+sn2_ofs=$((sn1_ofs + sn1_len))
+sn2_eds=$(peek_file_be "$TEST_IMG.v2.orig" $((sn2_ofs + 36)) 4)
+sn2_ids=$(($(peek_file_be "$TEST_IMG.v2.orig" $((sn2_ofs + 12)) 2) +
+ $(peek_file_be "$TEST_IMG.v2.orig" $((sn2_ofs + 14)) 2)))
+sn2_len=$(snapshot_table_entry_size "$TEST_IMG.v2.orig" $sn2_ofs)
+
+# Data before extra data
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn0-pre" bs=1 skip=$sn0_ofs count=40 \
+ &> /dev/null
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn1-pre" bs=1 skip=$sn1_ofs count=40 \
+ &> /dev/null
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn2-pre" bs=1 skip=$sn2_ofs count=40 \
+ &> /dev/null
+
+# Extra data
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn0-extra" bs=1 \
+ skip=$((sn0_ofs + 40)) count=$sn0_eds &> /dev/null
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn1-extra" bs=1 \
+ skip=$((sn1_ofs + 40)) count=$sn1_eds &> /dev/null
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn2-extra" bs=1 \
+ skip=$((sn2_ofs + 40)) count=$sn2_eds &> /dev/null
+
+# Data after extra data
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn0-post" bs=1 \
+ skip=$((sn0_ofs + 40 + sn0_eds)) count=$sn0_ids \
+ &> /dev/null
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn1-post" bs=1 \
+ skip=$((sn1_ofs + 40 + sn1_eds)) count=$sn1_ids \
+ &> /dev/null
+dd if="$TEST_IMG.v2.orig" of="$TEST_DIR/sn2-post" bs=1 \
+ skip=$((sn2_ofs + 40 + sn2_eds)) count=$sn2_ids \
+ &> /dev/null
+
+# Amend them, one by one
+# Set sn0's extra data size to 0
+poke_file "$TEST_DIR/sn0-pre" 36 '\x00\x00\x00\x00'
+truncate -s 0 "$TEST_DIR/sn0-extra"
+# Grow sn0-post to pad
+truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn0-pre") - 40)) \
+ "$TEST_DIR/sn0-post"
+
+# Set sn1's extra data size to 42
+poke_file "$TEST_DIR/sn1-pre" 36 '\x00\x00\x00\x2a'
+truncate -s 42 "$TEST_DIR/sn1-extra"
+poke_file "$TEST_DIR/sn1-extra" 16 'very important data'
+# Grow sn1-post to pad
+truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn1-pre") - 82)) \
+ "$TEST_DIR/sn1-post"
+
+# Set sn2's extra data size to 8
+poke_file "$TEST_DIR/sn2-pre" 36 '\x00\x00\x00\x08'
+truncate -s 8 "$TEST_DIR/sn2-extra"
+# Grow sn2-post to pad
+truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn2-pre") - 48)) \
+ "$TEST_DIR/sn2-post"
+
+# Construct snapshot table
+cat "$TEST_DIR"/sn0-{pre,extra,post} \
+ "$TEST_DIR"/sn1-{pre,extra,post} \
+ "$TEST_DIR"/sn2-{pre,extra,post} \
+ | dd of="$TEST_IMG.v2.orig" bs=1 seek=$sn_table_ofs conv=notrunc \
+ &> /dev/null
+
+# Done!
+TEST_IMG="$TEST_IMG.v2.orig" _check_test_img
+print_snapshot_table "$TEST_IMG.v2.orig"
+
+echo
+echo '=== Upgrade to v3 ==='
+echo
+
+cp "$TEST_IMG.v2.orig" "$TEST_IMG.v3.orig"
+$QEMU_IMG amend -o compat=1.1 "$TEST_IMG.v3.orig"
+TEST_IMG="$TEST_IMG.v3.orig" _check_test_img
+print_snapshot_table "$TEST_IMG.v3.orig"
+
+echo
+echo '=== Repair botched v3 ==='
+echo
+
+# Force the v2 file to be v3. v3 requires each snapshot table entry
+# to have at least 16 bytes of extra data, so it will not comply to
+# the qcow2 v3 specification; but we can fix that.
+cp "$TEST_IMG.v2.orig" "$TEST_IMG"
+
+# Set version
+poke_file "$TEST_IMG" 4 '\x00\x00\x00\x03'
+# Increase header length (necessary for v3)
+poke_file "$TEST_IMG" 100 '\x00\x00\x00\x68'
+# Set refcount order (necessary for v3)
+poke_file "$TEST_IMG" 96 '\x00\x00\x00\x04'
+
+_check_test_img -r all
+print_snapshot_table "$TEST_IMG"
+
+
+# From now on, just test the qcow2 version we are supposed to test.
+# (v3 by default, v2 by choice through $IMGOPTS.)
+# That works because we always write all known extra data when
+# updating the snapshot table, independent of the version.
+
+if echo "$IMGOPTS" | grep -q 'compat=\(0\.10\|v2\)' 2> /dev/null; then
+ subver=v2
+else
+ subver=v3
+fi
+
+echo
+echo '=== Add new snapshot ==='
+echo
+
+cp "$TEST_IMG.$subver.orig" "$TEST_IMG"
+$QEMU_IMG snapshot -c sn3 "$TEST_IMG"
+_check_test_img
+print_snapshot_table "$TEST_IMG"
+
+echo
+echo '=== Remove different snapshots ==='
+
+for sn in sn0 sn1 sn2; do
+ echo
+ echo "--- $sn ---"
+
+ cp "$TEST_IMG.$subver.orig" "$TEST_IMG"
+ $QEMU_IMG snapshot -d $sn "$TEST_IMG"
+ _check_test_img
+ print_snapshot_table "$TEST_IMG"
+done
+
+echo
+echo '=== Reject too much unknown extra data ==='
+echo
+
+cp "$TEST_IMG.$subver.orig" "$TEST_IMG"
+$QEMU_IMG snapshot -c sn3 "$TEST_IMG"
+
+sn_table_ofs=$(peek_file_be "$TEST_IMG" 64 8)
+sn0_ofs=$sn_table_ofs
+sn1_ofs=$((sn0_ofs + $(snapshot_table_entry_size "$TEST_IMG" $sn0_ofs)))
+sn2_ofs=$((sn1_ofs + $(snapshot_table_entry_size "$TEST_IMG" $sn1_ofs)))
+sn3_ofs=$((sn2_ofs + $(snapshot_table_entry_size "$TEST_IMG" $sn2_ofs)))
+
+# 64 kB of extra data should be rejected
+# (Note that this also induces a refcount error, because it spills
+# over to the next cluster. That's a good way to test that we can
+# handle simultaneous snapshot table and refcount errors.)
+poke_file "$TEST_IMG" $((sn3_ofs + 36)) '\x00\x01\x00\x00'
+
+# Print error
+_img_info
+echo
+_check_test_img
+echo
+
+# Should be repairable
+_check_test_img -r all
+
+echo
+echo '=== Snapshot table too big ==='
+echo
+
+sn_table_ofs=$(peek_file_be "$TEST_IMG.v3.orig" 64 8)
+
+# Fill a snapshot with 1 kB of extra data, a 65535-char ID, and a
+# 65535-char name, and repeat it as many times as necessary to fill
+# 64 MB (the maximum supported by qemu)
+
+touch "$TEST_DIR/sn0"
+
+# Full size (fixed + extra + ID + name + padding)
+sn_size=$((40 + 1024 + 65535 + 65535 + 2))
+
+# We only need the fixed part, though.
+truncate -s 40 "$TEST_DIR/sn0"
+
+# 65535-char ID string
+poke_file "$TEST_DIR/sn0" 12 '\xff\xff'
+# 65535-char name
+poke_file "$TEST_DIR/sn0" 14 '\xff\xff'
+# 1 kB of extra data
+poke_file "$TEST_DIR/sn0" 36 '\x00\x00\x04\x00'
+
+# Create test image
+_make_test_img 64M
+
+# Hook up snapshot table somewhere safe (at 1 MB)
+poke_file "$TEST_IMG" 64 '\x00\x00\x00\x00\x00\x10\x00\x00'
+
+offset=1048576
+size_written=0
+sn_count=0
+while [ $size_written -le $((64 * 1048576)) ]; do
+ dd if="$TEST_DIR/sn0" of="$TEST_IMG" bs=1 seek=$offset conv=notrunc \
+ &> /dev/null
+ offset=$((offset + sn_size))
+ size_written=$((size_written + sn_size))
+ sn_count=$((sn_count + 1))
+done
+truncate -s "$offset" "$TEST_IMG"
+
+# Give the last snapshot (the one to be removed) an L1 table so we can
+# see how that is handled when repairing the image
+# (Put it two clusters before 1 MB, and one L2 table one cluster
+# before 1 MB)
+poke_file "$TEST_IMG" $((offset - sn_size + 0)) \
+ '\x00\x00\x00\x00\x00\x0e\x00\x00'
+poke_file "$TEST_IMG" $((offset - sn_size + 8)) \
+ '\x00\x00\x00\x01'
+
+# Hook up the L2 table
+poke_file "$TEST_IMG" $((1048576 - 2 * 65536)) \
+ '\x80\x00\x00\x00\x00\x0f\x00\x00'
+
+# Make sure all of the clusters we just hooked up are allocated:
+# - The snapshot table
+# - The last snapshot's L1 and L2 table
+refblock0_allocate $((1048576 - 2 * 65536)) $offset
+
+poke_file "$TEST_IMG" 60 \
+ "$(printf '%08x' $sn_count | sed -e 's/\(..\)/\\x\1/g')"
+
+# Print error
+_img_info
+echo
+_check_test_img
+echo
+
+# Should be repairable
+_check_test_img -r all
+
+echo
+echo "$((sn_count - 1)) snapshots should remain:"
+echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots"
+echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots"
+
+echo
+echo '=== Snapshot table too big with one entry with too much extra data ==='
+echo
+
+# For this test, we reuse the image from the previous case, which has
+# a snapshot table that is right at the limit.
+# Our layout looks like this:
+# - (a number of snapshot table entries)
+# - One snapshot with $extra_data_size extra data
+# - One normal snapshot that breaks the 64 MB boundary
+# - One normal snapshot beyond the 64 MB boundary
+#
+# $extra_data_size is calculated so that simply by virtue of it
+# decreasing to 1 kB, the penultimate snapshot will fit into 64 MB
+# limit again. The final snapshot will always be beyond the limit, so
+# that we can see that the repair algorithm does still determine the
+# limit to be somewhere, even when truncating one snapshot's extra
+# data.
+
+# The last case has removed the last snapshot, so calculate
+# $old_offset to get the current image's real length
+old_offset=$((offset - sn_size))
+
+# The layout from the previous test had one snapshot beyond the 64 MB
+# limit; we want the same (after the oversized extra data has been
+# truncated to 1 kB), so we drop the last three snapshots and
+# construct them from scratch.
+offset=$((offset - 3 * sn_size))
+sn_count=$((sn_count - 3))
+
+# Assuming we had already written one of the three snapshots
+# (necessary so we can calculate $extra_data_size next).
+size_written=$((size_written - 2 * sn_size))
+
+# Increase the extra data size so we go past the limit
+# (The -1024 comes from the 1 kB of extra data we already have)
+extra_data_size=$((64 * 1048576 + 8 - sn_size - (size_written - 1024)))
+
+poke_file "$TEST_IMG" $((offset + 36)) \
+ "$(printf '%08x' $extra_data_size | sed -e 's/\(..\)/\\x\1/g')"
+
+offset=$((offset + sn_size - 1024 + extra_data_size))
+size_written=$((size_written - 1024 + extra_data_size))
+sn_count=$((sn_count + 1))
+
+# Write the two normal snapshots
+for ((i = 0; i < 2; i++)); do
+ dd if="$TEST_DIR/sn0" of="$TEST_IMG" bs=1 seek=$offset conv=notrunc \
+ &> /dev/null
+ offset=$((offset + sn_size))
+ size_written=$((size_written + sn_size))
+ sn_count=$((sn_count + 1))
+
+ if [ $i = 0 ]; then
+ # Check that the penultimate snapshot is beyond the 64 MB limit
+ echo "Snapshot table size should equal $((64 * 1048576 + 8)):" \
+ $size_written
+ echo
+ fi
+done
+
+truncate -s $offset "$TEST_IMG"
+refblock0_allocate $old_offset $offset
+
+poke_file "$TEST_IMG" 60 \
+ "$(printf '%08x' $sn_count | sed -e 's/\(..\)/\\x\1/g')"
+
+# Print error
+_img_info
+echo
+_check_test_img
+echo
+
+# Just truncating the extra data should be sufficient to shorten the
+# snapshot table so only one snapshot exceeds the extra size
+_check_test_img -r all
+
+echo
+echo '=== Too many snapshots ==='
+echo
+
+# Create a v2 image, for speeds' sake: All-zero snapshot table entries
+# are only valid in v2.
+IMGOPTS='compat=0.10' _make_test_img 64M
+
+# Hook up snapshot table somewhere safe (at 1 MB)
+poke_file "$TEST_IMG" 64 '\x00\x00\x00\x00\x00\x10\x00\x00'
+# "Create" more than 65536 snapshots (twice that many here)
+poke_file "$TEST_IMG" 60 '\x00\x02\x00\x00'
+
+# 40-byte all-zero snapshot table entries are valid snapshots, but
+# only in v2 (v3 needs 16 bytes of extra data, so we would have to
+# write 131072x '\x10').
+truncate -s $((1048576 + 40 * 131072)) "$TEST_IMG"
+
+# But let us give one of the snapshots to be removed an L1 table so
+# we can see how that is handled when repairing the image.
+# (Put it two clusters before 1 MB, and one L2 table one cluster
+# before 1 MB)
+poke_file "$TEST_IMG" $((1048576 + 40 * 65536 + 0)) \
+ '\x00\x00\x00\x00\x00\x0e\x00\x00'
+poke_file "$TEST_IMG" $((1048576 + 40 * 65536 + 8)) \
+ '\x00\x00\x00\x01'
+
+# Hook up the L2 table
+poke_file "$TEST_IMG" $((1048576 - 2 * 65536)) \
+ '\x80\x00\x00\x00\x00\x0f\x00\x00'
+
+# Make sure all of the clusters we just hooked up are allocated:
+# - The snapshot table
+# - The last snapshot's L1 and L2 table
+refblock0_allocate $((1048576 - 2 * 65536)) $((1048576 + 40 * 131072))
+
+# Print error
+_img_info
+echo
+_check_test_img
+echo
+
+# Should be repairable
+_check_test_img -r all
+
+echo
+echo '65536 snapshots should remain:'
+echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots"
+echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots"
+
+# success, all done
+echo "*** done"
+status=0
diff --git a/tests/qemu-iotests/261.out b/tests/qemu-iotests/261.out
new file mode 100644
index 0000000..2600354
--- /dev/null
+++ b/tests/qemu-iotests/261.out
@@ -0,0 +1,346 @@
+QA output created by 261
+
+=== Create v2 template ===
+
+Formatting 'TEST_DIR/t.IMGFMT.v2.orig', fmt=IMGFMT size=67108864
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT.v2.orig:
+ [0]
+ ID: 1
+ Name: sn0
+ Extra data size: 0
+ [1]
+ ID: 2
+ Name: sn1
+ Extra data size: 42
+ VM state size: 0
+ Disk size: 67108864
+ Unknown extra data: very important data
+ [2]
+ ID: 3
+ Name: sn2
+ Extra data size: 8
+ VM state size: 0
+
+=== Upgrade to v3 ===
+
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT.v3.orig:
+ [0]
+ ID: 1
+ Name: sn0
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+ [1]
+ ID: 2
+ Name: sn1
+ Extra data size: 42
+ VM state size: 0
+ Disk size: 67108864
+ Unknown extra data: very important data
+ [2]
+ ID: 3
+ Name: sn2
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+
+=== Repair botched v3 ===
+
+Repairing snapshot table entry 0 is incomplete
+Repairing snapshot table entry 2 is incomplete
+The following inconsistencies were found and repaired:
+
+ 0 leaked clusters
+ 2 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT:
+ [0]
+ ID: 1
+ Name: sn0
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+ [1]
+ ID: 2
+ Name: sn1
+ Extra data size: 42
+ VM state size: 0
+ Disk size: 67108864
+ Unknown extra data: very important data
+ [2]
+ ID: 3
+ Name: sn2
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+
+=== Add new snapshot ===
+
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT:
+ [0]
+ ID: 1
+ Name: sn0
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+ [1]
+ ID: 2
+ Name: sn1
+ Extra data size: 42
+ VM state size: 0
+ Disk size: 67108864
+ Unknown extra data: very important data
+ [2]
+ ID: 3
+ Name: sn2
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+ [3]
+ ID: 4
+ Name: sn3
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+
+=== Remove different snapshots ===
+
+--- sn0 ---
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT:
+ [0]
+ ID: 2
+ Name: sn1
+ Extra data size: 42
+ VM state size: 0
+ Disk size: 67108864
+ Unknown extra data: very important data
+ [1]
+ ID: 3
+ Name: sn2
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+
+--- sn1 ---
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT:
+ [0]
+ ID: 1
+ Name: sn0
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+ [1]
+ ID: 3
+ Name: sn2
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+
+--- sn2 ---
+No errors were found on the image.
+Snapshots in TEST_DIR/t.IMGFMT:
+ [0]
+ ID: 1
+ Name: sn0
+ Extra data size: 16
+ VM state size: 0
+ Disk size: 67108864
+ [1]
+ ID: 2
+ Name: sn1
+ Extra data size: 42
+ VM state size: 0
+ Disk size: 67108864
+ Unknown extra data: very important data
+
+=== Reject too much unknown extra data ===
+
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Too much extra metadata in snapshot table entry 3
+You can force-remove this extra metadata with qemu-img check -r all
+
+qemu-img: ERROR failed to read the snapshot table: Too much extra metadata in snapshot table entry 3
+You can force-remove this extra metadata with qemu-img check -r all
+qemu-img: Check failed: File too large
+
+Discarding too much extra metadata in snapshot table entry 3 (65536 > 1024)
+ERROR cluster 10 refcount=0 reference=1
+Rebuilding refcount structure
+Repairing cluster 1 refcount=1 reference=0
+Repairing cluster 2 refcount=1 reference=0
+The following inconsistencies were found and repaired:
+
+ 0 leaked clusters
+ 2 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+
+=== Snapshot table too big ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Snapshot table is too big
+You can force-remove all 1 overhanging snapshots with qemu-img check -r all
+
+qemu-img: ERROR failed to read the snapshot table: Snapshot table is too big
+You can force-remove all 1 overhanging snapshots with qemu-img check -r all
+qemu-img: Check failed: File too large
+
+Discarding 1 overhanging snapshots (snapshot table is too big)
+Leaked cluster 14 refcount=1 reference=0
+Leaked cluster 15 refcount=1 reference=0
+Leaked cluster 1039 refcount=1 reference=0
+Leaked cluster 1040 refcount=1 reference=0
+Repairing cluster 14 refcount=1 reference=0
+Repairing cluster 15 refcount=1 reference=0
+Repairing cluster 1039 refcount=1 reference=0
+Repairing cluster 1040 refcount=1 reference=0
+The following inconsistencies were found and repaired:
+
+ 4 leaked clusters
+ 1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+
+507 snapshots should remain:
+ qemu-img info reports 507 snapshots
+ Image header reports 507 snapshots
+
+=== Snapshot table too big with one entry with too much extra data ===
+
+Snapshot table size should equal 67108872: 67108872
+
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Too much extra metadata in snapshot table entry 505
+You can force-remove this extra metadata with qemu-img check -r all
+
+qemu-img: ERROR failed to read the snapshot table: Too much extra metadata in snapshot table entry 505
+You can force-remove this extra metadata with qemu-img check -r all
+qemu-img: Check failed: File too large
+
+Discarding too much extra metadata in snapshot table entry 505 (116944 > 1024)
+Discarding 1 overhanging snapshots (snapshot table is too big)
+Leaked cluster 1041 refcount=1 reference=0
+Leaked cluster 1042 refcount=1 reference=0
+Repairing cluster 1041 refcount=1 reference=0
+Repairing cluster 1042 refcount=1 reference=0
+The following inconsistencies were found and repaired:
+
+ 2 leaked clusters
+ 2 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+
+=== Too many snapshots ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Snapshot table too large
+
+qemu-img: ERROR snapshot table too large
+You can force-remove all 65536 overhanging snapshots with qemu-img check -r all
+qemu-img: Check failed: File too large
+
+Discarding 65536 overhanging snapshots
+Leaked cluster 14 refcount=1 reference=0
+Leaked cluster 15 refcount=1 reference=0
+Leaked cluster 56 refcount=1 reference=0
+Leaked cluster 57 refcount=1 reference=0
+Leaked cluster 58 refcount=1 reference=0
+Leaked cluster 59 refcount=1 reference=0
+Leaked cluster 60 refcount=1 reference=0
+Leaked cluster 61 refcount=1 reference=0
+Leaked cluster 62 refcount=1 reference=0
+Leaked cluster 63 refcount=1 reference=0
+Leaked cluster 64 refcount=1 reference=0
+Leaked cluster 65 refcount=1 reference=0
+Leaked cluster 66 refcount=1 reference=0
+Leaked cluster 67 refcount=1 reference=0
+Leaked cluster 68 refcount=1 reference=0
+Leaked cluster 69 refcount=1 reference=0
+Leaked cluster 70 refcount=1 reference=0
+Leaked cluster 71 refcount=1 reference=0
+Leaked cluster 72 refcount=1 reference=0
+Leaked cluster 73 refcount=1 reference=0
+Leaked cluster 74 refcount=1 reference=0
+Leaked cluster 75 refcount=1 reference=0
+Leaked cluster 76 refcount=1 reference=0
+Leaked cluster 77 refcount=1 reference=0
+Leaked cluster 78 refcount=1 reference=0
+Leaked cluster 79 refcount=1 reference=0
+Leaked cluster 80 refcount=1 reference=0
+Leaked cluster 81 refcount=1 reference=0
+Leaked cluster 82 refcount=1 reference=0
+Leaked cluster 83 refcount=1 reference=0
+Leaked cluster 84 refcount=1 reference=0
+Leaked cluster 85 refcount=1 reference=0
+Leaked cluster 86 refcount=1 reference=0
+Leaked cluster 87 refcount=1 reference=0
+Leaked cluster 88 refcount=1 reference=0
+Leaked cluster 89 refcount=1 reference=0
+Leaked cluster 90 refcount=1 reference=0
+Leaked cluster 91 refcount=1 reference=0
+Leaked cluster 92 refcount=1 reference=0
+Leaked cluster 93 refcount=1 reference=0
+Leaked cluster 94 refcount=1 reference=0
+Leaked cluster 95 refcount=1 reference=0
+Repairing cluster 14 refcount=1 reference=0
+Repairing cluster 15 refcount=1 reference=0
+Repairing cluster 56 refcount=1 reference=0
+Repairing cluster 57 refcount=1 reference=0
+Repairing cluster 58 refcount=1 reference=0
+Repairing cluster 59 refcount=1 reference=0
+Repairing cluster 60 refcount=1 reference=0
+Repairing cluster 61 refcount=1 reference=0
+Repairing cluster 62 refcount=1 reference=0
+Repairing cluster 63 refcount=1 reference=0
+Repairing cluster 64 refcount=1 reference=0
+Repairing cluster 65 refcount=1 reference=0
+Repairing cluster 66 refcount=1 reference=0
+Repairing cluster 67 refcount=1 reference=0
+Repairing cluster 68 refcount=1 reference=0
+Repairing cluster 69 refcount=1 reference=0
+Repairing cluster 70 refcount=1 reference=0
+Repairing cluster 71 refcount=1 reference=0
+Repairing cluster 72 refcount=1 reference=0
+Repairing cluster 73 refcount=1 reference=0
+Repairing cluster 74 refcount=1 reference=0
+Repairing cluster 75 refcount=1 reference=0
+Repairing cluster 76 refcount=1 reference=0
+Repairing cluster 77 refcount=1 reference=0
+Repairing cluster 78 refcount=1 reference=0
+Repairing cluster 79 refcount=1 reference=0
+Repairing cluster 80 refcount=1 reference=0
+Repairing cluster 81 refcount=1 reference=0
+Repairing cluster 82 refcount=1 reference=0
+Repairing cluster 83 refcount=1 reference=0
+Repairing cluster 84 refcount=1 reference=0
+Repairing cluster 85 refcount=1 reference=0
+Repairing cluster 86 refcount=1 reference=0
+Repairing cluster 87 refcount=1 reference=0
+Repairing cluster 88 refcount=1 reference=0
+Repairing cluster 89 refcount=1 reference=0
+Repairing cluster 90 refcount=1 reference=0
+Repairing cluster 91 refcount=1 reference=0
+Repairing cluster 92 refcount=1 reference=0
+Repairing cluster 93 refcount=1 reference=0
+Repairing cluster 94 refcount=1 reference=0
+Repairing cluster 95 refcount=1 reference=0
+The following inconsistencies were found and repaired:
+
+ 42 leaked clusters
+ 65536 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+
+65536 snapshots should remain:
+ qemu-img info reports 65536 snapshots
+ Image header reports 65536 snapshots
+*** done
diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264
index c8cd97a..1313664 100755
--- a/tests/qemu-iotests/264
+++ b/tests/qemu-iotests/264
@@ -24,6 +24,8 @@ import iotests
from iotests import qemu_img_create, qemu_io_silent_check, file_path, \
qemu_nbd_popen, log
+iotests.verify_image_format(supported_fmts=['qcow2'])
+
disk_a, disk_b, nbd_sock = file_path('disk_a', 'disk_b', 'nbd-sock')
nbd_uri = 'nbd+unix:///?socket=' + nbd_sock
size = 5 * 1024 * 1024
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
index d37a67c..170e173 100755
--- a/tests/qemu-iotests/267
+++ b/tests/qemu-iotests/267
@@ -29,7 +29,7 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
- rm -f "$TEST_DIR/nbd"
+ rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -143,7 +143,7 @@ echo
IMGOPTS="backing_file=$TEST_IMG.base" _make_test_img $size
cat <<EOF |
-nbd_server_start unix:$TEST_DIR/nbd
+nbd_server_start unix:$SOCK_DIR/nbd
nbd_server_add -w backing-fmt
savevm snap0
info snapshots
diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out
index 9d812e3..8dddb4b 100644
--- a/tests/qemu-iotests/267.out
+++ b/tests/qemu-iotests/267.out
@@ -161,7 +161,7 @@ Internal snapshots on backing file:
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=IMGFMT,file=backing-file,node-name=backing-fmt -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-fmt,node-name=fmt
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) nbd_server_start unix:TEST_DIR/nbd
+(qemu) nbd_server_start unix:SOCK_DIR/nbd
(qemu) nbd_server_add -w backing-fmt
(qemu) savevm snap0
(qemu) info snapshots
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 588c453..71fe388 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -97,6 +97,7 @@ IMGFMT -- $FULL_IMGFMT_DETAILS
IMGPROTO -- $IMGPROTO
PLATFORM -- $FULL_HOST_DETAILS
TEST_DIR -- $TEST_DIR
+SOCK_DIR -- $SOCK_DIR
SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
EOF
@@ -116,10 +117,14 @@ set_prog_path()
if [ -z "$TEST_DIR" ]; then
TEST_DIR=$PWD/scratch
fi
+mkdir -p "$TEST_DIR" || _init_error 'Failed to create TEST_DIR'
-if [ ! -e "$TEST_DIR" ]; then
- mkdir "$TEST_DIR"
+tmp_sock_dir=false
+if [ -z "$SOCK_DIR" ]; then
+ SOCK_DIR=$(mktemp -d)
+ tmp_sock_dir=true
fi
+mkdir -p "$SOCK_DIR" || _init_error 'Failed to create SOCK_DIR'
diff="diff -u"
verbose=false
@@ -534,6 +539,7 @@ if [ -z "$SAMPLE_IMG_DIR" ]; then
fi
export TEST_DIR
+export SOCK_DIR
export SAMPLE_IMG_DIR
if [ -s $tmp.list ]
@@ -716,6 +722,11 @@ END { if (NR > 0) {
rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
rm -f $tmp.*
+
+ if $tmp_sock_dir
+ then
+ rm -rf "$SOCK_DIR"
+ fi
}
trap "_wrapup; exit \$status" 0 1 2 3 15
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 9f418b4..f870e00 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -43,7 +43,8 @@ _filter_qom_path()
# replace occurrences of the actual TEST_DIR value with TEST_DIR
_filter_testdir()
{
- $SED -e "s#$TEST_DIR/#TEST_DIR/#g"
+ $SED -e "s#$TEST_DIR/#TEST_DIR/#g" \
+ -e "s#$SOCK_DIR/#SOCK_DIR/#g"
}
# replace occurrences of the actual IMGFMT value with IMGFMT
@@ -124,6 +125,7 @@ _filter_img_create()
$SED -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
-e "s#$TEST_DIR#TEST_DIR#g" \
+ -e "s#$SOCK_DIR#SOCK_DIR#g" \
-e "s#$IMGFMT#IMGFMT#g" \
-e 's#nbd:127.0.0.1:10810#TEST_DIR/t.IMGFMT#g' \
-e "s# encryption=off##g" \
@@ -160,6 +162,7 @@ _filter_img_info()
$SED -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
-e "s#$TEST_DIR#TEST_DIR#g" \
+ -e "s#$SOCK_DIR#SOCK_DIR#g" \
-e "s#$IMGFMT#IMGFMT#g" \
-e 's#nbd://127.0.0.1:10810$#TEST_DIR/t.IMGFMT#g' \
-e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \
@@ -218,7 +221,7 @@ _filter_nbd()
# Filter out the TCP port number since this changes between runs.
$SED -e '/nbd\/.*\.c:/d' \
-e 's#127\.0\.0\.1:[0-9]*#127.0.0.1:PORT#g' \
- -e "s#?socket=$TEST_DIR#?socket=TEST_DIR#g" \
+ -e "s#?socket=$SOCK_DIR#?socket=SOCK_DIR#g" \
-e 's#\(foo\|PORT/\?\|.sock\): Failed to .*$#\1#'
}
diff --git a/tests/qemu-iotests/common.nbd b/tests/qemu-iotests/common.nbd
index 24b01b6..a8cae8f 100644
--- a/tests/qemu-iotests/common.nbd
+++ b/tests/qemu-iotests/common.nbd
@@ -19,7 +19,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-nbd_unix_socket="${TEST_DIR}/qemu-nbd.sock"
+nbd_unix_socket="${SOCK_DIR}/qemu-nbd.sock"
nbd_tcp_addr="127.0.0.1"
nbd_pid_file="${TEST_DIR}/qemu-nbd.pid"
nbd_stderr_fifo="${TEST_DIR}/qemu-nbd.fifo"
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 12b4751..fa7bae2 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -53,6 +53,26 @@ poke_file()
printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
}
+# peek_file_le 'test.img' 512 2 => 65534
+peek_file_le()
+{
+ # Wrap in echo $() to strip spaces
+ echo $(od -j"$2" -N"$3" --endian=little -An -vtu"$3" "$1")
+}
+
+# peek_file_be 'test.img' 512 2 => 65279
+peek_file_be()
+{
+ # Wrap in echo $() to strip spaces
+ echo $(od -j"$2" -N"$3" --endian=big -An -vtu"$3" "$1")
+}
+
+# peek_file_raw 'test.img' 512 2 => '\xff\xfe'
+peek_file_raw()
+{
+ dd if="$1" bs=1 skip="$2" count="$3" status=none
+}
+
if ! . ./common.config
then
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index af322af..2887160 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -274,6 +274,7 @@
257 rw
258 rw quick
260 rw quick
+261 rw
262 rw quick migration
263 rw quick
264 rw
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 709def4..075f473 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -57,6 +57,7 @@ qemu_opts = os.environ.get('QEMU_OPTIONS', '').strip().split(' ')
imgfmt = os.environ.get('IMGFMT', 'raw')
imgproto = os.environ.get('IMGPROTO', 'file')
test_dir = os.environ.get('TEST_DIR')
+sock_dir = os.environ.get('SOCK_DIR')
output_dir = os.environ.get('OUTPUT_DIR', '.')
cachemode = os.environ.get('CACHEMODE')
qemu_default_machine = os.environ.get('QEMU_DEFAULT_MACHINE')
@@ -385,10 +386,10 @@ class FilePaths(object):
qemu_img('create', img_path, '1G')
# migration_sock_path is automatically deleted
"""
- def __init__(self, names):
+ def __init__(self, names, base_dir=test_dir):
self.paths = []
for name in names:
- self.paths.append(os.path.join(test_dir, file_pattern(name)))
+ self.paths.append(os.path.join(base_dir, file_pattern(name)))
def __enter__(self):
return self.paths
@@ -405,8 +406,8 @@ class FilePath(FilePaths):
"""
FilePath is a specialization of FilePaths that takes a single filename.
"""
- def __init__(self, name):
- super(FilePath, self).__init__([name])
+ def __init__(self, name, base_dir=test_dir):
+ super(FilePath, self).__init__([name], base_dir)
def __enter__(self):
return self.paths[0]
@@ -419,7 +420,7 @@ def file_path_remover():
pass
-def file_path(*names):
+def file_path(*names, base_dir=test_dir):
''' Another way to get auto-generated filename that cleans itself up.
Use is as simple as:
@@ -435,7 +436,7 @@ def file_path(*names):
paths = []
for name in names:
filename = file_pattern(name)
- path = os.path.join(test_dir, filename)
+ path = os.path.join(base_dir, filename)
file_path_remover.paths.append(path)
paths.append(path)
@@ -456,7 +457,8 @@ class VM(qtest.QEMUQtestMachine):
name = "qemu%s-%d" % (path_suffix, os.getpid())
super(VM, self).__init__(qemu_prog, qemu_opts, name=name,
test_dir=test_dir,
- socket_scm_helper=socket_scm_helper)
+ socket_scm_helper=socket_scm_helper,
+ sock_dir=sock_dir)
self._num_drives = 0
def add_object(self, opts):
@@ -838,6 +840,11 @@ class QMPTestCase(unittest.TestCase):
return self.pause_wait(job_id)
return result
+ def case_skip(self, reason):
+ '''Skip this test case'''
+ case_notrun(reason)
+ self.skipTest(reason)
+
def notrun(reason):
'''Skip this test suite'''
@@ -849,7 +856,11 @@ def notrun(reason):
sys.exit(0)
def case_notrun(reason):
- '''Skip this test case'''
+ '''Mark this test case as not having been run (without actually
+ skipping it, that is left to the caller). See
+ QMPTestCase.case_skip() for a variant that actually skips the
+ current test case.'''
+
# Each test in qemu-iotests has a number ("seq")
seq = os.path.basename(sys.argv[0])
@@ -912,22 +923,34 @@ def qemu_pipe(*args):
def supported_formats(read_only=False):
'''Set 'read_only' to True to check ro-whitelist
Otherwise, rw-whitelist is checked'''
- format_message = qemu_pipe("-drive", "format=help")
- line = 1 if read_only else 0
- return format_message.splitlines()[line].split(":")[1].split()
+
+ if not hasattr(supported_formats, "formats"):
+ supported_formats.formats = {}
+
+ if read_only not in supported_formats.formats:
+ format_message = qemu_pipe("-drive", "format=help")
+ line = 1 if read_only else 0
+ supported_formats.formats[read_only] = \
+ format_message.splitlines()[line].split(":")[1].split()
+
+ return supported_formats.formats[read_only]
def skip_if_unsupported(required_formats=[], read_only=False):
'''Skip Test Decorator
Runs the test if all the required formats are whitelisted'''
def skip_test_decorator(func):
- def func_wrapper(*args, **kwargs):
- usf_list = list(set(required_formats) -
- set(supported_formats(read_only)))
+ def func_wrapper(test_case: QMPTestCase, *args, **kwargs):
+ if callable(required_formats):
+ fmts = required_formats(test_case)
+ else:
+ fmts = required_formats
+
+ usf_list = list(set(fmts) - set(supported_formats(read_only)))
if usf_list:
- case_notrun('{}: formats {} are not whitelisted'.format(
- args[0], usf_list))
+ test_case.case_skip('{}: formats {} are not whitelisted'.format(
+ test_case, usf_list))
else:
- return func(*args, **kwargs)
+ return func(test_case, *args, **kwargs)
return func_wrapper
return skip_test_decorator
@@ -950,8 +973,15 @@ def execute_unittest(output, verbosity, debug):
unittest.main(testRunner=runner)
finally:
if not debug:
- sys.stderr.write(re.sub(r'Ran (\d+) tests? in [\d.]+s',
- r'Ran \1 tests', output.getvalue()))
+ out = output.getvalue()
+ out = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', out)
+
+ # Hide skipped tests from the reference output
+ out = re.sub(r'OK \(skipped=\d+\)', 'OK', out)
+ out_first_line, out_rest = out.split('\n', 1)
+ out = out_first_line.replace('s', '.') + '\n' + out_rest
+
+ sys.stderr.write(out)
def execute_test(test_function=None,
supported_fmts=[], supported_oses=['linux'],
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
index cfe30ba..0c86180 100644
--- a/tests/test-block-iothread.c
+++ b/tests/test-block-iothread.c
@@ -45,7 +45,7 @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
}
static int coroutine_fn
-bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset,
+bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
PreallocMode prealloc, Error **errp)
{
return 0;
@@ -185,18 +185,18 @@ static void test_sync_op_truncate(BdrvChild *c)
int ret;
/* Normal success path */
- ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
g_assert_cmpint(ret, ==, 0);
/* Early error: Negative offset */
- ret = bdrv_truncate(c, -2, PREALLOC_MODE_OFF, NULL);
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
g_assert_cmpint(ret, ==, -EINVAL);
/* Error: Read-only image */
c->bs->read_only = true;
c->bs->open_flags &= ~BDRV_O_RDWR;
- ret = bdrv_truncate(c, 65536, PREALLOC_MODE_OFF, NULL);
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
g_assert_cmpint(ret, ==, -EACCES);
c->bs->read_only = false;