e92f0e1910
BDRV_POLL_WHILE waits for the started I/O by releasing bs's ctx then polling the main context, which relies on the yielded coroutine continuing on bs->ctx before notifying qemu_aio_context with bdrv_wakeup(). Thus, using qemu_coroutine_enter to start I/O is wrong because if the coroutine is entered from main loop, co->ctx will be qemu_aio_context, as a result of the "release, poll, acquire" loop of BDRV_POLL_WHILE, race conditions happen when both main thread and the iothread access the same BDS: main loop iothread ----------------------------------------------------------------------- blockdev_snapshot aio_context_acquire(bs->ctx) virtio_scsi_data_plane_handle_cmd bdrv_drained_begin(bs->ctx) bdrv_flush(bs) bdrv_co_flush(bs) aio_context_acquire(bs->ctx).enter ... qemu_coroutine_yield(co) BDRV_POLL_WHILE() aio_context_release(bs->ctx) aio_context_acquire(bs->ctx).return ... aio_co_wake(co) aio_poll(qemu_aio_context) ... co_schedule_bh_cb() ... qemu_coroutine_enter(co) ... /* (A) bdrv_co_flush(bs) /* (B) I/O on bs */ continues... */ aio_context_release(bs->ctx) aio_context_acquire(bs->ctx) Note that in above case, bdrv_drained_begin() doesn't do the "release, poll, acquire" in BDRV_POLL_WHILE, because bs->in_flight == 0. Fix this by using bdrv_coroutine_enter and enter coroutine in the right context. iotests 109 output is updated because the coroutine reenter flow during mirror job complete is different (now through co_queue_wakeup, instead of the unconditional qemu_coroutine_switch before), making the end job len different. Signed-off-by: Fam Zheng <famz@redhat.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
228 lines
14 KiB
Plaintext
228 lines
14 KiB
Plaintext
QA output created by 109
|
|
|
|
=== Writing a qcow header into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Writing a qcow2 header into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Writing a qed header into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Writing a vdi header into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Writing a vmdk header into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Writing a vpc header into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Copying sample image empty.bochs into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Copying sample image iotest-dirtylog-10G-4M.vhdx into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Copying sample image parallels-v1 into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Copying sample image simple-pattern.cloop into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
|
|
{"return": []}
|
|
read 65536/65536 bytes at offset 0
|
|
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
|
|
=== Write legitimate MBR into raw ===
|
|
|
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
|
{"return": {}}
|
|
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
|
|
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
|
|
Specify the 'raw' format explicitly to remove the restrictions.
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
{"return": {}}
|
|
{"return": {}}
|
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
|
|
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
|
|
Warning: Image size mismatch!
|
|
Images are identical.
|
|
*** done
|