summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell2021-07-20 17:59:33 +0200
committerPeter Maydell2021-07-20 17:59:33 +0200
commitc04b4d9e6b596ead3cf6046a9243fbfee068ef33 (patch)
tree7976e9b1f05115812cb63efb646c32ac5a7ab6cf /tests
parentMerge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2021-07-19' in... (diff)
parentiotests/307: Test iothread conflict for exports (diff)
downloadqemu-c04b4d9e6b596ead3cf6046a9243fbfee068ef33.tar.gz
qemu-c04b4d9e6b596ead3cf6046a9243fbfee068ef33.tar.xz
qemu-c04b4d9e6b596ead3cf6046a9243fbfee068ef33.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches - mirror: Fix active mirror deadlock - replication: Fix crashes due to operations on wrong BdrvChild - configure: Add option to use driver whitelist even in tools - vvfat: Fix crash when opening image read-write - export: Fix crash in error path with fixed-iothread=false # gpg: Signature made Tue 20 Jul 2021 16:09:23 BST # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: iotests/307: Test iothread conflict for exports block/export: Conditionally ignore set-context error block/vvfat: fix: drop backing replication: Remove workaround replication: Properly attach children replication: Reduce usage of s->hidden_disk and s->secondary_disk replication: Remove s->active_disk block: Add option to use driver whitelist even in tools block/mirror: fix active mirror dead-lock in mirror_wait_on_conflicts iotest 151: add test-case that shows active mirror dead-lock block/mirror: set .co for active-write MirrorOp objects Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rwxr-xr-xtests/qemu-iotests/15154
-rw-r--r--tests/qemu-iotests/151.out4
-rwxr-xr-xtests/qemu-iotests/30715
-rw-r--r--tests/qemu-iotests/307.out8
4 files changed, 77 insertions, 4 deletions
diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
index 182f6b5321..93d14193d0 100755
--- a/tests/qemu-iotests/151
+++ b/tests/qemu-iotests/151
@@ -38,8 +38,9 @@ class TestActiveMirror(iotests.QMPTestCase):
'if': 'none',
'node-name': 'source-node',
'driver': iotests.imgfmt,
- 'file': {'driver': 'file',
- 'filename': source_img}}
+ 'file': {'driver': 'blkdebug',
+ 'image': {'driver': 'file',
+ 'filename': source_img}}}
blk_target = {'node-name': 'target-node',
'driver': iotests.imgfmt,
@@ -141,6 +142,55 @@ class TestActiveMirror(iotests.QMPTestCase):
self.potential_writes_in_flight = False
+ def testIntersectingActiveIO(self):
+ # Fill the source image
+ result = self.vm.hmp_qemu_io('source', 'write -P 1 0 2M')
+
+ # Start the block job (very slowly)
+ result = self.vm.qmp('blockdev-mirror',
+ job_id='mirror',
+ filter_node_name='mirror-node',
+ device='source-node',
+ target='target-node',
+ sync='full',
+ copy_mode='write-blocking',
+ speed=1)
+
+ self.vm.hmp_qemu_io('source', 'break write_aio A')
+ self.vm.hmp_qemu_io('source', 'aio_write 0 1M') # 1
+ self.vm.hmp_qemu_io('source', 'wait_break A')
+ self.vm.hmp_qemu_io('source', 'aio_write 0 2M') # 2
+ self.vm.hmp_qemu_io('source', 'aio_write 0 2M') # 3
+
+ # Now 2 and 3 are in mirror_wait_on_conflicts, waiting for 1
+
+ self.vm.hmp_qemu_io('source', 'break write_aio B')
+ self.vm.hmp_qemu_io('source', 'aio_write 1M 2M') # 4
+ self.vm.hmp_qemu_io('source', 'wait_break B')
+
+ # 4 doesn't wait for 2 and 3, because they didn't yet set
+ # in_flight_bitmap. So, nothing prevents 4 to go except for our
+ # break-point B.
+
+ self.vm.hmp_qemu_io('source', 'resume A')
+
+ # Now we resumed 1, so 2 and 3 goes to the next iteration of while loop
+ # in mirror_wait_on_conflicts(). They don't exit, as bitmap is dirty
+ # due to request 4.
+ # In the past at that point 2 and 3 would wait for each other producing
+ # a dead-lock. Now this is fixed and they will wait for request 4.
+
+ self.vm.hmp_qemu_io('source', 'resume B')
+
+ # After resuming 4, one of 2 and 3 goes first and set in_flight_bitmap,
+ # so the other will wait for it.
+
+ result = self.vm.qmp('block-job-set-speed', device='mirror', speed=0)
+ self.assert_qmp(result, 'return', {})
+ self.complete_and_wait(drive='mirror')
+
+ self.potential_writes_in_flight = False
+
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'raw'],
diff --git a/tests/qemu-iotests/151.out b/tests/qemu-iotests/151.out
index 8d7e996700..89968f35d7 100644
--- a/tests/qemu-iotests/151.out
+++ b/tests/qemu-iotests/151.out
@@ -1,5 +1,5 @@
-...
+....
----------------------------------------------------------------------
-Ran 3 tests
+Ran 4 tests
OK
diff --git a/tests/qemu-iotests/307 b/tests/qemu-iotests/307
index c7685347bc..b429b5aa50 100755
--- a/tests/qemu-iotests/307
+++ b/tests/qemu-iotests/307
@@ -41,9 +41,11 @@ with iotests.FilePath('image') as img, \
iotests.log('=== Launch VM ===')
vm.add_object('iothread,id=iothread0')
+ vm.add_object('iothread,id=iothread1')
vm.add_blockdev(f'file,filename={img},node-name=file')
vm.add_blockdev(f'{iotests.imgfmt},file=file,node-name=fmt')
vm.add_blockdev('raw,file=file,node-name=ro,read-only=on')
+ vm.add_blockdev('null-co,node-name=null')
vm.add_device(f'id=scsi0,driver=virtio-scsi,iothread=iothread0')
vm.launch()
@@ -74,6 +76,19 @@ with iotests.FilePath('image') as img, \
vm.qmp_log('query-block-exports')
iotests.qemu_nbd_list_log('-k', socket)
+ iotests.log('\n=== Add export with conflicting iothread ===')
+
+ vm.qmp_log('device_add', id='sdb', driver='scsi-hd', drive='null')
+
+ # Should fail because of fixed-iothread
+ vm.qmp_log('block-export-add', id='export1', type='nbd', node_name='null',
+ iothread='iothread1', fixed_iothread=True, writable=True)
+
+ # Should ignore the iothread conflict, but then fail because of the
+ # permission conflict (and not crash)
+ vm.qmp_log('block-export-add', id='export1', type='nbd', node_name='null',
+ iothread='iothread1', fixed_iothread=False, writable=True)
+
iotests.log('\n=== Add a writable export ===')
# This fails because share-rw=off
diff --git a/tests/qemu-iotests/307.out b/tests/qemu-iotests/307.out
index 4b0c7e155a..ec8d2be0e0 100644
--- a/tests/qemu-iotests/307.out
+++ b/tests/qemu-iotests/307.out
@@ -51,6 +51,14 @@ exports available: 1
base:allocation
+=== Add export with conflicting iothread ===
+{"execute": "device_add", "arguments": {"drive": "null", "driver": "scsi-hd", "id": "sdb"}}
+{"return": {}}
+{"execute": "block-export-add", "arguments": {"fixed-iothread": true, "id": "export1", "iothread": "iothread1", "node-name": "null", "type": "nbd", "writable": true}}
+{"error": {"class": "GenericError", "desc": "Cannot change iothread of active block backend"}}
+{"execute": "block-export-add", "arguments": {"fixed-iothread": false, "id": "export1", "iothread": "iothread1", "node-name": "null", "type": "nbd", "writable": true}}
+{"error": {"class": "GenericError", "desc": "Permission conflict on node 'null': permissions 'write' are both required by an unnamed block device (uses node 'null' as 'root' child) and unshared by block device 'sdb' (uses node 'null' as 'root' child)."}}
+
=== Add a writable export ===
{"execute": "block-export-add", "arguments": {"description": "This is the writable second export", "id": "export1", "name": "export1", "node-name": "fmt", "type": "nbd", "writable": true, "writethrough": true}}
{"error": {"class": "GenericError", "desc": "Permission conflict on node 'fmt': permissions 'write' are both required by an unnamed block device (uses node 'fmt' as 'root' child) and unshared by block device 'sda' (uses node 'fmt' as 'root' child)."}}