Browse Source

iotests: Add coverage of recent NBD qio deadlock fix

Test that all images in a qcow2 chain using an NBD backing file can be
served by the same process.  Prior to the recent QIONetListener fixes,
this test would demonstrate deadlock.

The test borrows heavily from the original formula by "John Doe" in
the gitlab bug, but uses a Unix socket rather than TCP to avoid port
contention, and uses a full-blown QEMU rather than qemu-storage-daemon
since both programs were impacted.

The test starts out with the even simpler task of directly adding an
NBD client without qcow2 chain ('client'), which also provokes the
deadlock; but commenting out the 'Adding explicit NBD client' section
will still show deadlock when reaching the 'Adding wrapper image...'.

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/3169
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-ID: <20251113011625.878876-28-eblake@redhat.com>
pull/307/head
Eric Blake 5 months ago
parent
commit
24fd6d75b3
  1. 94
      tests/qemu-iotests/tests/nbd-in-qcow2-chain
  2. 75
      tests/qemu-iotests/tests/nbd-in-qcow2-chain.out

94
tests/qemu-iotests/tests/nbd-in-qcow2-chain

@ -0,0 +1,94 @@
#!/usr/bin/env bash
# group: rw quick
#
# Test of opening both server and client NBD in a qcow2 backing chain
#
# Copyright (C) Red Hat, Inc.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# creator
owner=eblake@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
status=1 # failure is the default!
_cleanup()
{
_cleanup_qemu
_cleanup_test_img
rm -f "$SOCK_DIR/nbd"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
cd ..
. ./common.rc
. ./common.filter
. ./common.qemu
. ./common.nbd
_supported_fmt qcow2 # Hardcoded to qcow2 command line and QMP below
_supported_proto file
size=100M
echo
echo "=== Preparing base image ==="
TEST_IMG="$TEST_IMG.base" _make_test_img $size
echo
echo "=== Starting QEMU and exposing base image ==="
_launch_qemu -machine q35
h1=$QEMU_HANDLE
_send_qemu_cmd $QEMU_HANDLE '{"execute": "qmp_capabilities"}' 'return'
_send_qemu_cmd $QEMU_HANDLE '{"execute": "blockdev-add",
"arguments": {"node-name":"base", "driver":"qcow2",
"file":{"driver":"file", "filename":"'"$TEST_IMG.base"'"}}}' 'return'
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start",
"arguments": {"addr":{"type":"unix",
"data":{"path":"'"$SOCK_DIR/nbd"'"}}}}' 'return'
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments": {"device":"base","name":"base"}}' 'return'
echo
echo "=== Adding explicit NBD client ==="
_send_qemu_cmd $QEMU_HANDLE '{"execute": "blockdev-add",
"arguments": {"node-name":"client", "driver":"nbd",
"read-only":true, "export":"base",
"server":{"type":"unix", "path":"'"$SOCK_DIR/nbd"'"}}}' 'return'
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments": {"device":"client","name":"client"}}' 'return'
echo
echo "=== Creating wrapper image ==="
_make_test_img -F raw -b "nbd+unix:///base?socket=$SOCK_DIR/nbd" $size
echo
echo "=== Adding wrapper image with implicit client from qcow2 file ==="
_send_qemu_cmd $QEMU_HANDLE '{"execute": "blockdev-add",
"arguments": {"node-name":"wrap", "driver":"qcow2",
"file":{"driver":"file", "filename":"'"$TEST_IMG"'"}}}' 'return'
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments": {"device":"wrap","name":"wrap"}}' 'return'
echo
echo "=== Checking NBD server ==="
$QEMU_NBD --list -k $SOCK_DIR/nbd
echo
echo "=== Cleaning up ==="
_send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' ''
echo "*** done"
rm -f $seq.full
status=0

75
tests/qemu-iotests/tests/nbd-in-qcow2-chain.out

@ -0,0 +1,75 @@
QA output created by nbd-in-qcow2-chain
=== Preparing base image ===
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=104857600
=== Starting QEMU and exposing base image ===
{"execute": "qmp_capabilities"}
{"return": {}}
{"execute": "blockdev-add",
"arguments": {"node-name":"base", "driver":"IMGFMT",
"file":{"driver":"file", "filename":"TEST_DIR/t.IMGFMT.base"}}}
{"return": {}}
{"execute":"nbd-server-start",
"arguments": {"addr":{"type":"unix",
"data":{"path":"SOCK_DIR/nbd"}}}}
{"return": {}}
{"execute":"nbd-server-add",
"arguments": {"device":"base","name":"base"}}
{"return": {}}
=== Adding explicit NBD client ===
{"execute": "blockdev-add",
"arguments": {"node-name":"client", "driver":"nbd",
"read-only":true, "export":"base",
"server":{"type":"unix", "path":"SOCK_DIR/nbd"}}}
{"return": {}}
{"execute":"nbd-server-add",
"arguments": {"device":"client","name":"client"}}
{"return": {}}
=== Creating wrapper image ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file=nbd+unix:///base?socket=SOCK_DIR/nbd backing_fmt=raw
=== Adding wrapper image with implicit client from qcow2 file ===
{"execute": "blockdev-add",
"arguments": {"node-name":"wrap", "driver":"IMGFMT",
"file":{"driver":"file", "filename":"TEST_DIR/t.IMGFMT"}}}
{"return": {}}
{"execute":"nbd-server-add",
"arguments": {"device":"wrap","name":"wrap"}}
{"return": {}}
=== Checking NBD server ===
exports available: 3
export: 'base'
size: 104857600
flags: 0x158f ( readonly flush fua df multi cache block-status-payload )
min block: 1
opt block: 4096
max block: 33554432
transaction size: 64-bit
available meta contexts: 1
base:allocation
export: 'client'
size: 104857600
flags: 0x158f ( readonly flush fua df multi cache block-status-payload )
min block: 1
opt block: 4096
max block: 33554432
transaction size: 64-bit
available meta contexts: 1
base:allocation
export: 'wrap'
size: 104857600
flags: 0x158f ( readonly flush fua df multi cache block-status-payload )
min block: 1
opt block: 4096
max block: 33554432
transaction size: 64-bit
available meta contexts: 1
base:allocation
=== Cleaning up ===
{"execute":"quit"}
*** done
Loading…
Cancel
Save