diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-10-24 18:26:59 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-10-24 18:26:59 +0100 |
commit | 45b567d645c22fb79f4698a13396718084f7cf72 (patch) | |
tree | ae90b95ea95890d41acd9b60518fc37471880dec /tests | |
parent | a3ae21ec3fe036f536dc94cad735931777143103 (diff) | |
parent | 25493dc012e7c10dba51ee893b634a1dbfeed126 (diff) | |
download | qemu-45b567d645c22fb79f4698a13396718084f7cf72.tar.gz |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches
# gpg: Signature made Mon 24 Oct 2016 17:02:47 BST
# gpg: using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream: (23 commits)
block/replication: Clarify 'top-id' parameter usage
block: More operations for meta dirty bitmap
tests: Add test code for hbitmap serialization
block: BdrvDirtyBitmap serialization interface
hbitmap: serialization
block: Assert that bdrv_release_dirty_bitmap succeeded
block: Add two dirty bitmap getters
block: Support meta dirty bitmap
tests: Add test code for meta bitmap
HBitmap: Introduce "meta" bitmap to track bit changes
block: Hide HBitmap in block dirty bitmap interface
quorum: do not allocate multiple iovecs for FIFO strategy
quorum: change child_iter to children_read
iotests: Do not rely on unavailable domains in 162
iotests: Remove raciness from 162
qemu-nbd: Add --fork option
qemu-iotests: Test I/O in a single drive from a throttling group
throttle: Correct access to wrong BlockBackendPublic structures
qapi: fix memory leak in bdrv_image_info_specific_dump
block: improve error handling in raw_open
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/qemu-iotests/041 | 11 | ||||
-rwxr-xr-x | tests/qemu-iotests/067 | 12 | ||||
-rwxr-xr-x | tests/qemu-iotests/071 | 118 | ||||
-rwxr-xr-x | tests/qemu-iotests/081 | 52 | ||||
-rwxr-xr-x | tests/qemu-iotests/085 | 9 | ||||
-rwxr-xr-x | tests/qemu-iotests/087 | 76 | ||||
-rwxr-xr-x | tests/qemu-iotests/093 | 33 | ||||
-rw-r--r-- | tests/qemu-iotests/093.out | 4 | ||||
-rwxr-xr-x | tests/qemu-iotests/117 | 12 | ||||
-rwxr-xr-x | tests/qemu-iotests/118 | 42 | ||||
-rw-r--r-- | tests/qemu-iotests/124 | 20 | ||||
-rw-r--r-- | tests/qemu-iotests/139 | 10 | ||||
-rwxr-xr-x | tests/qemu-iotests/141 | 13 | ||||
-rwxr-xr-x | tests/qemu-iotests/155 | 10 | ||||
-rwxr-xr-x | tests/qemu-iotests/162 | 22 | ||||
-rw-r--r-- | tests/qemu-iotests/162.out | 2 | ||||
-rw-r--r-- | tests/test-hbitmap.c | 272 |
17 files changed, 492 insertions, 226 deletions
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index d1e1ad8bd2..30e628f0f7 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -194,10 +194,9 @@ class TestSingleBlockdev(TestSingleDrive): def setUp(self): TestSingleDrive.setUp(self) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img) - args = {'options': - {'driver': iotests.imgfmt, - 'node-name': self.qmp_target, - 'file': { 'filename': target_img, 'driver': 'file' } } } + args = {'driver': iotests.imgfmt, + 'node-name': self.qmp_target, + 'file': { 'filename': target_img, 'driver': 'file' } } result = self.vm.qmp("blockdev-add", **args) self.assert_qmp(result, 'return', {}) @@ -782,8 +781,8 @@ class TestRepairQuorum(iotests.QMPTestCase): self.vm.launch() #assemble the quorum block device from the individual files - args = { "options" : { "driver": "quorum", "node-name": "quorum0", - "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] } } + args = { "driver": "quorum", "node-name": "quorum0", + "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] } if self.has_quorum(): result = self.vm.qmp("blockdev-add", **args) self.assert_qmp(result, 'return', {}) diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067 index a12125bd46..38d23fce6b 100755 --- a/tests/qemu-iotests/067 +++ b/tests/qemu-iotests/067 @@ -119,13 +119,11 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "disk", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "driver": "$IMGFMT", + "node-name": "disk", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071 index 6d0864cff6..48b495513f 100755 --- a/tests/qemu-iotests/071 +++ b/tests/qemu-iotests/071 @@ -107,25 +107,21 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "node-name": "drive0", - "driver": "file", - "filename": "$TEST_IMG" - } + "node-name": "drive0", + "driver": "file", + "filename": "$TEST_IMG" } } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "drive0-debug", - "file": { - "driver": "blkdebug", - "image": "drive0", - "inject-error": [{ - "event": "l2_load" - }] - } + "driver": "$IMGFMT", + "node-name": "drive0-debug", + "file": { + "driver": "blkdebug", + "image": "drive0", + "inject-error": [{ + "event": "l2_load" + }] } } } @@ -145,26 +141,22 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "node-name": "drive0", - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "node-name": "drive0", + "driver": "$IMGFMT", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "blkverify", - "node-name": "drive0-verify", - "test": "drive0", - "raw": { - "driver": "file", - "filename": "$TEST_IMG.base" - } + "driver": "blkverify", + "node-name": "drive0-verify", + "test": "drive0", + "raw": { + "driver": "file", + "filename": "$TEST_IMG.base" } } } @@ -184,27 +176,23 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "node-name": "drive0", - "driver": "file", - "filename": "$TEST_IMG.base" - } + "node-name": "drive0", + "driver": "file", + "filename": "$TEST_IMG.base" } } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "blkverify", - "node-name": "drive0-verify", - "test": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } - }, - "raw": "drive0" - } + "driver": "blkverify", + "node-name": "drive0-verify", + "test": { + "driver": "$IMGFMT", + "file": { + "driver": "file", + "filename": "$TEST_IMG" + } + }, + "raw": "drive0" } } { "execute": "human-monitor-command", @@ -223,30 +211,26 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "node-name": "drive0", - "driver": "file", - "filename": "$TEST_IMG" - } + "node-name": "drive0", + "driver": "file", + "filename": "$TEST_IMG" } } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "drive0-debug", - "file": { - "driver": "blkdebug", - "image": "drive0", - "inject-error": [{ - "event": "read_aio", - "state": 42 - }], - "set-state": [{ - "event": "write_aio", - "new_state": 42 - }] - } + "driver": "$IMGFMT", + "node-name": "drive0-debug", + "file": { + "driver": "blkdebug", + "image": "drive0", + "inject-error": [{ + "event": "read_aio", + "state": 42 + }], + "set-state": [{ + "event": "write_aio", + "new_state": 42 + }] } } } diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081 index 0a809f3499..da3fb0984b 100755 --- a/tests/qemu-iotests/081 +++ b/tests/qemu-iotests/081 @@ -105,40 +105,36 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "node-name": "drive2", - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_DIR/2.raw" - } + "node-name": "drive2", + "driver": "$IMGFMT", + "file": { + "driver": "file", + "filename": "$TEST_DIR/2.raw" } } } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "quorum", - "node-name": "drive0-quorum", - "vote-threshold": 2, - "children": [ - { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_DIR/1.raw" - } - }, - "drive2", - { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_DIR/3.raw" - } + "driver": "quorum", + "node-name": "drive0-quorum", + "vote-threshold": 2, + "children": [ + { + "driver": "$IMGFMT", + "file": { + "driver": "file", + "filename": "$TEST_DIR/1.raw" } - ] - } + }, + "drive2", + { + "driver": "$IMGFMT", + "file": { + "driver": "file", + "filename": "$TEST_DIR/3.raw" + } + } + ] } } { "execute": "human-monitor-command", diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085 index aa77eca77d..c53e97f067 100755 --- a/tests/qemu-iotests/085 +++ b/tests/qemu-iotests/085 @@ -100,11 +100,10 @@ function add_snapshot_image() _make_test_img -b "${base_image}" "$size" mv "${TEST_IMG}" "${snapshot_file}" cmd="{ 'execute': 'blockdev-add', 'arguments': - { 'options': - { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${extra_params} - 'file': - { 'driver': 'file', 'filename': '${snapshot_file}', - 'node-name': 'file_${1}' } } } }" + { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${extra_params} + 'file': + { 'driver': 'file', 'filename': '${snapshot_file}', + 'node-name': 'file_${1}' } } }" _send_qemu_cmd $h "${cmd}" "return" } diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 index b1ac71f2b8..9de57ddf6d 100755 --- a/tests/qemu-iotests/087 +++ b/tests/qemu-iotests/087 @@ -61,12 +61,10 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "driver": "$IMGFMT", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } @@ -81,25 +79,21 @@ run_qemu -drive driver=$IMGFMT,id=disk,node-name=test-node,file="$TEST_IMG" <<EO { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "disk", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "driver": "$IMGFMT", + "node-name": "disk", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "test-node", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "driver": "$IMGFMT", + "node-name": "test-node", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } @@ -114,14 +108,12 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "disk", - "file": { - "driver": "file", - "filename": "$TEST_IMG", - "aio": "native" - } + "driver": "$IMGFMT", + "node-name": "disk", + "file": { + "driver": "file", + "filename": "$TEST_IMG", + "aio": "native" } } } @@ -137,13 +129,11 @@ run_qemu -S <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "disk", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "driver": "$IMGFMT", + "node-name": "disk", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } @@ -154,13 +144,11 @@ run_qemu <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "driver": "$IMGFMT", - "node-name": "disk", - "file": { - "driver": "file", - "filename": "$TEST_IMG" - } + "driver": "$IMGFMT", + "node-name": "disk", + "file": { + "driver": "file", + "filename": "$TEST_IMG" } } } @@ -176,9 +164,7 @@ run_qemu -S <<EOF { "execute": "qmp_capabilities" } { "execute": "blockdev-add", "arguments": { - "options": { - "node-name": "disk" - } + "node-name": "disk" } } { "execute": "quit" } diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093 index ffcb271b36..2ed393a548 100755 --- a/tests/qemu-iotests/093 +++ b/tests/qemu-iotests/093 @@ -53,7 +53,7 @@ class ThrottleTestCase(iotests.QMPTestCase): result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params) self.assert_qmp(result, 'return', {}) - def do_test_throttle(self, ndrives, seconds, params): + def do_test_throttle(self, ndrives, seconds, params, first_drive = 0): def check_limit(limit, num): # IO throttling algorithm is discrete, allow 10% error so the test # is more robust @@ -85,12 +85,14 @@ class ThrottleTestCase(iotests.QMPTestCase): # Send I/O requests to all drives for i in range(rd_nr): for drive in range(0, ndrives): - self.vm.hmp_qemu_io("drive%d" % drive, "aio_read %d %d" % + idx = first_drive + drive + self.vm.hmp_qemu_io("drive%d" % idx, "aio_read %d %d" % (i * rq_size, rq_size)) for i in range(wr_nr): for drive in range(0, ndrives): - self.vm.hmp_qemu_io("drive%d" % drive, "aio_write %d %d" % + idx = first_drive + drive + self.vm.hmp_qemu_io("drive%d" % idx, "aio_write %d %d" % (i * rq_size, rq_size)) # We'll store the I/O stats for each drive in these arrays @@ -105,15 +107,17 @@ class ThrottleTestCase(iotests.QMPTestCase): # Read the stats before advancing the clock for i in range(0, ndrives): + idx = first_drive + i start_rd_bytes[i], start_rd_iops[i], start_wr_bytes[i], \ - start_wr_iops[i] = self.blockstats('drive%d' % i) + start_wr_iops[i] = self.blockstats('drive%d' % idx) self.vm.qtest("clock_step %d" % ns) # Read the stats after advancing the clock for i in range(0, ndrives): + idx = first_drive + i end_rd_bytes[i], end_rd_iops[i], end_wr_bytes[i], \ - end_wr_iops[i] = self.blockstats('drive%d' % i) + end_wr_iops[i] = self.blockstats('drive%d' % idx) # Check that the I/O is within the limits and evenly distributed for i in range(0, ndrives): @@ -129,6 +133,7 @@ class ThrottleTestCase(iotests.QMPTestCase): self.assertTrue(check_limit(params['iops_rd'], rd_iops)) self.assertTrue(check_limit(params['iops_wr'], wr_iops)) + # Connect N drives to a VM and test I/O in all of them def test_all(self): params = {"bps": 4096, "bps_rd": 4096, @@ -146,6 +151,24 @@ class ThrottleTestCase(iotests.QMPTestCase): self.configure_throttle(ndrives, limits) self.do_test_throttle(ndrives, 5, limits) + # Connect N drives to a VM and test I/O in just one of them a time + def test_one(self): + params = {"bps": 4096, + "bps_rd": 4096, + "bps_wr": 4096, + "iops": 10, + "iops_rd": 10, + "iops_wr": 10, + } + # Repeat the test for each one of the drives + for drive in range(0, self.max_drives): + # Pick each out of all possible params and test + for tk in params: + limits = dict([(k, 0) for k in params]) + limits[tk] = params[tk] * self.max_drives + self.configure_throttle(self.max_drives, limits) + self.do_test_throttle(1, 5, limits, drive) + def test_burst(self): params = {"bps": 4096, "bps_rd": 4096, diff --git a/tests/qemu-iotests/093.out b/tests/qemu-iotests/093.out index 914e3737bd..2f7d3902f2 100644 --- a/tests/qemu-iotests/093.out +++ b/tests/qemu-iotests/093.out @@ -1,5 +1,5 @@ -..... +....... ---------------------------------------------------------------------- -Ran 5 tests +Ran 7 tests OK diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117 index 5b28039e17..e955d52de3 100755 --- a/tests/qemu-iotests/117 +++ b/tests/qemu-iotests/117 @@ -52,16 +52,16 @@ _send_qemu_cmd $QEMU_HANDLE \ _send_qemu_cmd $QEMU_HANDLE \ "{ 'execute': 'blockdev-add', - 'arguments': { 'options': { 'node-name': 'protocol', - 'driver': 'file', - 'filename': '$TEST_IMG' } } }" \ + 'arguments': { 'node-name': 'protocol', + 'driver': 'file', + 'filename': '$TEST_IMG' } }" \ 'return' _send_qemu_cmd $QEMU_HANDLE \ "{ 'execute': 'blockdev-add', - 'arguments': { 'options': { 'node-name': 'format', - 'driver': '$IMGFMT', - 'file': 'protocol' } } }" \ + 'arguments': { 'node-name': 'format', + 'driver': '$IMGFMT', + 'file': 'protocol' } }" \ 'return' _send_qemu_cmd $QEMU_HANDLE \ diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118 index e63a40fa94..8a9e838c90 100755 --- a/tests/qemu-iotests/118 +++ b/tests/qemu-iotests/118 @@ -229,10 +229,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): def test_cycle(self): result = self.vm.qmp('blockdev-add', - options={'node-name': 'new', - 'driver': iotests.imgfmt, - 'file': {'filename': new_img, - 'driver': 'file'}}) + node_name='new', + driver=iotests.imgfmt, + file={'filename': new_img, + 'driver': 'file'}) self.assert_qmp(result, 'return', {}) if self.device_name is not None: @@ -309,10 +309,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass): return result = self.vm.qmp('blockdev-add', - options={'node-name': 'new', - 'driver': iotests.imgfmt, - 'file': {'filename': new_img, - 'driver': 'file'}}) + node_name='new', + driver=iotests.imgfmt, + file={'filename': new_img, + 'driver': 'file'}) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', @@ -341,10 +341,10 @@ class TestInitiallyFilled(GeneralChangeTestsBaseClass): def test_insert_on_filled(self): result = self.vm.qmp('blockdev-add', - options={'node-name': 'new', - 'driver': iotests.imgfmt, - 'file': {'filename': new_img, - 'driver': 'file'}}) + node_name='new', + driver=iotests.imgfmt, + file={'filename': new_img, + 'driver': 'file'}) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('blockdev-open-tray', device='drive0') @@ -609,11 +609,11 @@ class TestChangeReadOnly(ChangeBaseClass): self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) result = self.vm.qmp('blockdev-add', - options={'node-name': 'new', - 'driver': iotests.imgfmt, - 'read-only': True, - 'file': {'filename': new_img, - 'driver': 'file'}}) + node_name='new', + driver=iotests.imgfmt, + read_only=True, + file={'filename': new_img, + 'driver': 'file'}) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('query-block') @@ -663,10 +663,10 @@ class TestBlockJobsAfterCycle(ChangeBaseClass): self.assert_qmp_absent(result, 'return[0]/inserted') result = self.vm.qmp('blockdev-add', - options={'node-name': 'node0', - 'driver': iotests.imgfmt, - 'file': {'filename': old_img, - 'driver': 'file'}}) + node_name='node0', + driver=iotests.imgfmt, + file={'filename': old_img, + 'driver': 'file'}) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124 index 2f0bc24cd0..f06938eeb7 100644 --- a/tests/qemu-iotests/124 +++ b/tests/qemu-iotests/124 @@ -416,10 +416,10 @@ class TestIncrementalBackup(TestIncrementalBackupBase): ('0xcd', '32M', '124k'))) # Create a blkdebug interface to this img as 'drive1' - result = self.vm.qmp('blockdev-add', options={ - 'node-name': drive1['id'], - 'driver': drive1['fmt'], - 'file': { + result = self.vm.qmp('blockdev-add', + node_name=drive1['id'], + driver=drive1['fmt'], + file={ 'driver': 'blkdebug', 'image': { 'driver': 'file', @@ -438,7 +438,7 @@ class TestIncrementalBackup(TestIncrementalBackupBase): 'once': True }], } - }) + ) self.assert_qmp(result, 'return', {}) # Create bitmaps and full backups for both drives @@ -560,10 +560,10 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase): ''' drive0 = self.drives[0] - result = self.vm.qmp('blockdev-add', options={ - 'node-name': drive0['id'], - 'driver': drive0['fmt'], - 'file': { + result = self.vm.qmp('blockdev-add', + node_name=drive0['id'], + driver=drive0['fmt'], + file={ 'driver': 'blkdebug', 'image': { 'driver': 'file', @@ -582,7 +582,7 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase): 'once': True }], } - }) + ) self.assert_qmp(result, 'return', {}) self.create_anchor_backup(drive0) diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139 index 47a4c26e29..6a0f6ca569 100644 --- a/tests/qemu-iotests/139 +++ b/tests/qemu-iotests/139 @@ -57,7 +57,7 @@ class TestBlockdevDel(iotests.QMPTestCase): 'file': {'driver': 'file', 'node-name': file_node, 'filename': base_img}} - result = self.vm.qmp('blockdev-add', conv_keys = False, options = opts) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.assert_qmp(result, 'return', {}) self.checkBlockDriverState(node) self.checkBlockDriverState(file_node) @@ -72,7 +72,7 @@ class TestBlockdevDel(iotests.QMPTestCase): 'backing': '', 'file': {'driver': 'file', 'filename': new_img}} - result = self.vm.qmp('blockdev-add', conv_keys = False, options = opts) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.assert_qmp(result, 'return', {}) self.checkBlockDriverState(node) @@ -185,7 +185,7 @@ class TestBlockdevDel(iotests.QMPTestCase): opts = {'driver': 'blkdebug', 'node-name': debug, 'image': image} - result = self.vm.qmp('blockdev-add', conv_keys = False, options = opts) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.assert_qmp(result, 'return', {}) self.checkBlockDriverState(node) self.checkBlockDriverState(debug) @@ -210,7 +210,7 @@ class TestBlockdevDel(iotests.QMPTestCase): 'node-name': blkverify, 'test': node_0, 'raw': node_1} - result = self.vm.qmp('blockdev-add', conv_keys = False, options = opts) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.assert_qmp(result, 'return', {}) self.checkBlockDriverState(test) self.checkBlockDriverState(raw) @@ -234,7 +234,7 @@ class TestBlockdevDel(iotests.QMPTestCase): 'node-name': quorum, 'vote-threshold': 1, 'children': [ child_0, child_1 ]} - result = self.vm.qmp('blockdev-add', conv_keys = False, options = opts) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.assert_qmp(result, 'return', {}) self.checkBlockDriverState(child0) self.checkBlockDriverState(child1) diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141 index c092d872dc..3ba79f027a 100755 --- a/tests/qemu-iotests/141 +++ b/tests/qemu-iotests/141 @@ -50,13 +50,12 @@ test_blockjob() _send_qemu_cmd $QEMU_HANDLE \ "{'execute': 'blockdev-add', 'arguments': { - 'options': { - 'node-name': 'drv0', - 'driver': '$IMGFMT', - 'file': { - 'driver': 'file', - 'filename': '$TEST_IMG' - }}}}" \ + 'node-name': 'drv0', + 'driver': '$IMGFMT', + 'file': { + 'driver': 'file', + 'filename': '$TEST_IMG' + }}}" \ 'return' _send_qemu_cmd $QEMU_HANDLE \ diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155 index 4057b5e2aa..0b86ea4e5c 100755 --- a/tests/qemu-iotests/155 +++ b/tests/qemu-iotests/155 @@ -63,10 +63,10 @@ class BaseClass(iotests.QMPTestCase): # Add the BDS via blockdev-add so it stays around after the mirror block # job has been completed result = self.vm.qmp('blockdev-add', - options={'node-name': 'source', - 'driver': iotests.imgfmt, - 'file': {'driver': 'file', - 'filename': source_img}}) + node_name='source', + driver=iotests.imgfmt, + file={'driver': 'file', + 'filename': source_img}) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('x-blockdev-insert-medium', @@ -90,7 +90,7 @@ class BaseClass(iotests.QMPTestCase): if self.target_blockdev_backing: options['backing'] = self.target_blockdev_backing - result = self.vm.qmp('blockdev-add', options=options) + result = self.vm.qmp('blockdev-add', **options) self.assert_qmp(result, 'return', {}) def tearDown(self): diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162 index 0b43ea3395..f8eecb325b 100755 --- a/tests/qemu-iotests/162 +++ b/tests/qemu-iotests/162 @@ -43,16 +43,26 @@ echo '=== NBD ===' $QEMU_IMG info 'json:{"driver": "nbd", "host": 42}' # And this should not treat @port as if it had not been specified -# (We cannot use localhost with an invalid port here, but we need to use a -# non-existing domain, because otherwise the error message will not contain -# the port) -$QEMU_IMG info 'json:{"driver": "nbd", "host": "does.not.exist.example.com", "port": 42}' +# (We need to set up a server here, because the error message for "Connection +# refused" does not contain the destination port) + +# Launching qemu-nbd is done in a loop: We try to set up an NBD server on some +# random port and continue until success, i.e. until we have found a port that +# is not in use yet. +while true; do + port=$((RANDOM + 32768)) + if $QEMU_NBD -p $port -f raw --fork null-co:// 2> /dev/null; then + break + fi +done + +$QEMU_IMG info "json:{'driver': 'nbd', 'host': 'localhost', 'port': $port}" \ + | grep '^image' | sed -e "s/$port/PORT/" # This is a test for NBD's bdrv_refresh_filename() implementation: It expects # either host or path to be set, but it must not assume that they are set to # strings in the options QDict -$QEMU_NBD -k "$PWD/42" -f raw null-co:// & -sleep 0.5 +$QEMU_NBD -k "$PWD/42" -f raw --fork null-co:// $QEMU_IMG info 'json:{"driver": "nbd", "path": 42}' | grep '^image' rm -f 42 diff --git a/tests/qemu-iotests/162.out b/tests/qemu-iotests/162.out index 9bba72353a..3c5be2c569 100644 --- a/tests/qemu-iotests/162.out +++ b/tests/qemu-iotests/162.out @@ -2,7 +2,7 @@ QA output created by 162 === NBD === qemu-img: Could not open 'json:{"driver": "nbd", "host": 42}': Failed to connect socket: Invalid argument -qemu-img: Could not open 'json:{"driver": "nbd", "host": "does.not.exist.example.com", "port": 42}': address resolution failed for does.not.exist.example.com:42: Name or service not known +image: nbd://localhost:PORT image: nbd+unix://?socket=42 === SSH === diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c index c0e9895fb9..9b7495cc32 100644 --- a/tests/test-hbitmap.c +++ b/tests/test-hbitmap.c @@ -11,6 +11,8 @@ #include "qemu/osdep.h" #include "qemu/hbitmap.h" +#include "qemu/bitmap.h" +#include "block/block.h" #define LOG_BITS_PER_LONG (BITS_PER_LONG == 32 ? 5 : 6) @@ -20,6 +22,7 @@ typedef struct TestHBitmapData { HBitmap *hb; + HBitmap *meta; unsigned long *bits; size_t size; size_t old_size; @@ -91,6 +94,14 @@ static void hbitmap_test_init(TestHBitmapData *data, } } +static void hbitmap_test_init_meta(TestHBitmapData *data, + uint64_t size, int granularity, + int meta_chunk) +{ + hbitmap_test_init(data, size, granularity); + data->meta = hbitmap_create_meta(data->hb, meta_chunk); +} + static inline size_t hbitmap_test_array_size(size_t bits) { size_t n = DIV_ROUND_UP(bits, BITS_PER_LONG); @@ -133,6 +144,9 @@ static void hbitmap_test_teardown(TestHBitmapData *data, const void *unused) { if (data->hb) { + if (data->meta) { + hbitmap_free_meta(data->hb); + } hbitmap_free(data->hb); data->hb = NULL; } @@ -634,6 +648,249 @@ static void test_hbitmap_truncate_shrink_large(TestHBitmapData *data, hbitmap_test_truncate(data, size, -diff, 0); } +static void hbitmap_check_meta(TestHBitmapData *data, + int64_t start, int count) +{ + int64_t i; + + for (i = 0; i < data->size; i++) { + if (i >= start && i < start + count) { + g_assert(hbitmap_get(data->meta, i)); + } else { + g_assert(!hbitmap_get(data->meta, i)); + } + } +} + +static void hbitmap_test_meta(TestHBitmapData *data, + int64_t start, int count, + int64_t check_start, int check_count) +{ + hbitmap_reset_all(data->hb); + hbitmap_reset_all(data->meta); + + /* Test "unset" -> "unset" will not update meta. */ + hbitmap_reset(data->hb, start, count); + hbitmap_check_meta(data, 0, 0); + + /* Test "unset" -> "set" will update meta */ + hbitmap_set(data->hb, start, count); + hbitmap_check_meta(data, check_start, check_count); + + /* Test "set" -> "set" will not update meta */ + hbitmap_reset_all(data->meta); + hbitmap_set(data->hb, start, count); + hbitmap_check_meta(data, 0, 0); + + /* Test "set" -> "unset" will update meta */ + hbitmap_reset_all(data->meta); + hbitmap_reset(data->hb, start, count); + hbitmap_check_meta(data, check_start, check_count); +} + +static void hbitmap_test_meta_do(TestHBitmapData *data, int chunk_size) +{ + uint64_t size = chunk_size * 100; + hbitmap_test_init_meta(data, size, 0, chunk_size); + + hbitmap_test_meta(data, 0, 1, 0, chunk_size); + hbitmap_test_meta(data, 0, chunk_size, 0, chunk_size); + hbitmap_test_meta(data, chunk_size - 1, 1, 0, chunk_size); + hbitmap_test_meta(data, chunk_size - 1, 2, 0, chunk_size * 2); + hbitmap_test_meta(data, chunk_size - 1, chunk_size + 1, 0, chunk_size * 2); + hbitmap_test_meta(data, chunk_size - 1, chunk_size + 2, 0, chunk_size * 3); + hbitmap_test_meta(data, 7 * chunk_size - 1, chunk_size + 2, + 6 * chunk_size, chunk_size * 3); + hbitmap_test_meta(data, size - 1, 1, size - chunk_size, chunk_size); + hbitmap_test_meta(data, 0, size, 0, size); +} + +static void test_hbitmap_meta_byte(TestHBitmapData *data, const void *unused) +{ + hbitmap_test_meta_do(data, BITS_PER_BYTE); +} + +static void test_hbitmap_meta_word(TestHBitmapData *data, const void *unused) +{ + hbitmap_test_meta_do(data, BITS_PER_LONG); +} + +static void test_hbitmap_meta_sector(TestHBitmapData *data, const void *unused) +{ + hbitmap_test_meta_do(data, BDRV_SECTOR_SIZE * BITS_PER_BYTE); +} + +/** + * Create an HBitmap and test set/unset. + */ +static void test_hbitmap_meta_one(TestHBitmapData *data, const void *unused) +{ + int i; + int64_t offsets[] = { + 0, 1, L1 - 1, L1, L1 + 1, L2 - 1, L2, L2 + 1, L3 - 1, L3, L3 + 1 + }; + + hbitmap_test_init_meta(data, L3 * 2, 0, 1); + for (i = 0; i < ARRAY_SIZE(offsets); i++) { + hbitmap_test_meta(data, offsets[i], 1, offsets[i], 1); + hbitmap_test_meta(data, offsets[i], L1, offsets[i], L1); + hbitmap_test_meta(data, offsets[i], L2, offsets[i], L2); + } +} + +static void test_hbitmap_serialize_granularity(TestHBitmapData *data, + const void *unused) +{ + int r; + + hbitmap_test_init(data, L3 * 2, 3); + r = hbitmap_serialization_granularity(data->hb); + g_assert_cmpint(r, ==, 64 << 3); +} + +static void test_hbitmap_meta_zero(TestHBitmapData *data, const void *unused) +{ + hbitmap_test_init_meta(data, 0, 0, 1); + + hbitmap_check_meta(data, 0, 0); +} + +static void hbitmap_test_serialize_range(TestHBitmapData *data, + uint8_t *buf, size_t buf_size, + uint64_t pos, uint64_t count) +{ + size_t i; + unsigned long *el = (unsigned long *)buf; + + assert(hbitmap_granularity(data->hb) == 0); + hbitmap_reset_all(data->hb); + memset(buf, 0, buf_size); + if (count) { + hbitmap_set(data->hb, pos, count); + } + hbitmap_serialize_part(data->hb, buf, 0, data->size); + + /* Serialized buffer is inherently LE, convert it back manually to test */ + for (i = 0; i < buf_size / sizeof(unsigned long); i++) { + el[i] = (BITS_PER_LONG == 32 ? le32_to_cpu(el[i]) : le64_to_cpu(el[i])); + } + + for (i = 0; i < data->size; i++) { + int is_set = test_bit(i, (unsigned long *)buf); + if (i >= pos && i < pos + count) { + g_assert(is_set); + } else { + g_assert(!is_set); + } + } + + /* Re-serialize for deserialization testing */ + memset(buf, 0, buf_size); + hbitmap_serialize_part(data->hb, buf, 0, data->size); + hbitmap_reset_all(data->hb); + hbitmap_deserialize_part(data->hb, buf, 0, data->size, true); + + for (i = 0; i < data->size; i++) { + int is_set = hbitmap_get(data->hb, i); + if (i >= pos && i < pos + count) { + g_assert(is_set); + } else { + g_assert(!is_set); + } + } +} + +static void test_hbitmap_serialize_basic(TestHBitmapData *data, + const void *unused) +{ + int i, j; + size_t buf_size; + uint8_t *buf; + uint64_t positions[] = { 0, 1, L1 - 1, L1, L2 - 1, L2, L2 + 1, L3 - 1 }; + int num_positions = sizeof(positions) / sizeof(positions[0]); + + hbitmap_test_init(data, L3, 0); + buf_size = hbitmap_serialization_size(data->hb, 0, data->size); + buf = g_malloc0(buf_size); + + for (i = 0; i < num_positions; i++) { + for (j = 0; j < num_positions; j++) { + hbitmap_test_serialize_range(data, buf, buf_size, + positions[i], + MIN(positions[j], L3 - positions[i])); + } + } + + g_free(buf); +} + +static void test_hbitmap_serialize_part(TestHBitmapData *data, + const void *unused) +{ + int i, j, k; + size_t buf_size; + uint8_t *buf; + uint64_t positions[] = { 0, 1, L1 - 1, L1, L2 - 1, L2, L2 + 1, L3 - 1 }; + int num_positions = sizeof(positions) / sizeof(positions[0]); + + hbitmap_test_init(data, L3, 0); + buf_size = L2; + buf = g_malloc0(buf_size); + + for (i = 0; i < num_positions; i++) { + hbitmap_set(data->hb, positions[i], 1); + } + + for (i = 0; i < data->size; i += buf_size) { + unsigned long *el = (unsigned long *)buf; + hbitmap_serialize_part(data->hb, buf, i, buf_size); + for (j = 0; j < buf_size / sizeof(unsigned long); j++) { + el[j] = (BITS_PER_LONG == 32 ? le32_to_cpu(el[j]) : le64_to_cpu(el[j])); + } + + for (j = 0; j < buf_size; j++) { + bool should_set = false; + for (k = 0; k < num_positions; k++) { + if (positions[k] == j + i) { + should_set = true; + break; + } + } + g_assert_cmpint(should_set, ==, test_bit(j, (unsigned long *)buf)); + } + } + + g_free(buf); +} + +static void test_hbitmap_serialize_zeroes(TestHBitmapData *data, + const void *unused) +{ + int i; + HBitmapIter iter; + int64_t next; + uint64_t min_l1 = MAX(L1, 64); + uint64_t positions[] = { 0, min_l1, L2, L3 - min_l1}; + int num_positions = sizeof(positions) / sizeof(positions[0]); + + hbitmap_test_init(data, L3, 0); + + for (i = 0; i < num_positions; i++) { + hbitmap_set(data->hb, positions[i], L1); + } + + for (i = 0; i < num_positions; i++) { + hbitmap_deserialize_zeroes(data->hb, positions[i], min_l1, true); + hbitmap_iter_init(&iter, data->hb, 0); + next = hbitmap_iter_next(&iter); + if (i == num_positions - 1) { + g_assert_cmpint(next, ==, -1); + } else { + g_assert_cmpint(next, ==, positions[i + 1]); + } + } +} + static void hbitmap_test_add(const char *testpath, void (*test_func)(TestHBitmapData *data, const void *user_data)) { @@ -683,6 +940,21 @@ int main(int argc, char **argv) test_hbitmap_truncate_grow_large); hbitmap_test_add("/hbitmap/truncate/shrink/large", test_hbitmap_truncate_shrink_large); + + hbitmap_test_add("/hbitmap/meta/zero", test_hbitmap_meta_zero); + hbitmap_test_add("/hbitmap/meta/one", test_hbitmap_meta_one); + hbitmap_test_add("/hbitmap/meta/byte", test_hbitmap_meta_byte); + hbitmap_test_add("/hbitmap/meta/word", test_hbitmap_meta_word); + hbitmap_test_add("/hbitmap/meta/sector", test_hbitmap_meta_sector); + + hbitmap_test_add("/hbitmap/serialize/granularity", + test_hbitmap_serialize_granularity); + hbitmap_test_add("/hbitmap/serialize/basic", + test_hbitmap_serialize_basic); + hbitmap_test_add("/hbitmap/serialize/part", + test_hbitmap_serialize_part); + hbitmap_test_add("/hbitmap/serialize/zeroes", + test_hbitmap_serialize_zeroes); g_test_run(); return 0; |