@samitouri / QOSamiQemu / commits / 2224bff1ba

iotests/308: Add multi-threading sanity test

Run qemu-img bench on a simple multi-threaded FUSE export to test that it works. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Hanna Czenczek <hreitz@redhat.com> Message-ID: <20260309150856.26800-26-hreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Hanna Czenczek committed Mar 9, 2026 at 16:08 UTC 2224bff1ba90f3061a3f240be9994d755ba2770e
2 files changed +107
tests/qemu-iotests/308
+51
@@ -441,6 +441,57 @@ $QEMU_IO -c 'read -P 0 0 64M' "$TEST_IMG" | _filter_qemu_io
441
442 _cleanup_test_img
443
444 +echo
445 +echo '=== Multi-threading ==='
446 +
447 +# Just set up a null block device, export it (with multi-threading), and run
448 +# qemu-img bench on it (to get parallel requests)
449 +
450 +_launch_qemu
451 +_send_qemu_cmd $QEMU_HANDLE \
452 + "{'execute': 'qmp_capabilities'}" \
453 + 'return'
454 +
455 +_send_qemu_cmd $QEMU_HANDLE \
456 + "{'execute': 'blockdev-add',
457 + 'arguments': {
458 + 'driver': 'null-co',
459 + 'node-name': 'null'
460 + } }" \
461 + 'return'
462 +
463 +for id in iothread{0,1,2,3}; do
464 + _send_qemu_cmd $QEMU_HANDLE \
465 + "{'execute': 'object-add',
466 + 'arguments': {
467 + 'qom-type': 'iothread',
468 + 'id': '$id'
469 + } }" \
470 + 'return'
471 +done
472 +
473 +echo
474 +
475 +iothreads="['iothread0', 'iothread1', 'iothread2', 'iothread3']"
476 +fuse_export_add \
477 + 'export' \
478 + "'mountpoint': '$EXT_MP', 'iothread': $iothreads" \
479 + 'return' \
480 + 'null'
481 +
482 +echo
483 +$QEMU_IMG bench -f raw "$EXT_MP" |
484 + sed -e 's/[0-9.]\+ seconds/X.XXX seconds/'
485 +echo
486 +
487 +fuse_export_del 'export'
488 +
489 +_send_qemu_cmd $QEMU_HANDLE \
490 + "{'execute': 'quit'}" \
491 + 'return'
492 +
493 +wait=yes _cleanup_qemu
494 +
495 # success, all done
496 echo "*** done"
497 rm -f $seq.full
tests/qemu-iotests/308.out
+56
@@ -217,4 +217,60 @@ read 67108864/67108864 bytes at offset 0
217 {"return": {}}
218 read 67108864/67108864 bytes at offset 0
219 64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
220 +
221 +=== Multi-threading ===
222 +{'execute': 'qmp_capabilities'}
223 +{"return": {}}
224 +{'execute': 'blockdev-add',
225 + 'arguments': {
226 + 'driver': 'null-co',
227 + 'node-name': 'null'
228 + } }
229 +{"return": {}}
230 +{'execute': 'object-add',
231 + 'arguments': {
232 + 'qom-type': 'iothread',
233 + 'id': 'iothread0'
234 + } }
235 +{"return": {}}
236 +{'execute': 'object-add',
237 + 'arguments': {
238 + 'qom-type': 'iothread',
239 + 'id': 'iothread1'
240 + } }
241 +{"return": {}}
242 +{'execute': 'object-add',
243 + 'arguments': {
244 + 'qom-type': 'iothread',
245 + 'id': 'iothread2'
246 + } }
247 +{"return": {}}
248 +{'execute': 'object-add',
249 + 'arguments': {
250 + 'qom-type': 'iothread',
251 + 'id': 'iothread3'
252 + } }
253 +{"return": {}}
254 +
255 +{'execute': 'block-export-add',
256 + 'arguments': {
257 + 'type': 'fuse',
258 + 'id': 'export',
259 + 'node-name': 'null',
260 + 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'iothread': ['iothread0', 'iothread1', 'iothread2', 'iothread3']
261 + } }
262 +{"return": {}}
263 +
264 +Sending 75000 read requests, 4096 bytes each, 64 in parallel (starting at offset 0, step size 4096)
265 +Run completed in X.XXX seconds.
266 +
267 +{'execute': 'block-export-del',
268 + 'arguments': {
269 + 'id': 'export'
270 + } }
271 +{"return": {}}
272 +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export"}}
273 +{'execute': 'quit'}
274 +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
275 +{"return": {}}
276 *** done