Right now, _filter_img_create just filters out everything that looks format-dependent, and applies some filename filters. That means that we have to add another filter line every time some format gets a new creation option. This can be avoided by instead discarding everything and just keeping what we know is format-independent (format, size, backing file, encryption information[1], preallocation) or just interesting to have in the reference output (external data file path). Furthermore, we probably want to sort these options. Format drivers are not required to define them in any specific order, so the output is effectively random (although this has never bothered us until now). We need a specific order for our reference outputs, though. Unfortunately, just using a plain "sort" would change a lot of existing reference outputs, so we have to pre-filter the option keys to keep our existing order (fmt, size, backing*, data, encryption info, preallocation). Finally, this makes it difficult for _filter_img_create to automagically work for QMP output. Thus, this patch adds a separate _filter_img_create_for_qmp function that echos every line verbatim that does not start with "Formatting", and pipes those "Formatting" lines to _filter_img_create. [1] Actually, the only thing that is really important is whether encryption is enabled or not. A patch by Maxim thus removes all other "encrypt.*" options from the output: https://lists.nongnu.org/archive/html/qemu-block/2020-06/msg00339.html But that patch needs to come later so we can get away with changing as few reference outputs in this patch here as possible. Signed-off-by: Max Reitz <mreitz@redhat.com> Message-Id: <20200625125548.870061-2-mreitz@redhat.com> Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
195 lines
5.4 KiB
Bash
Executable file
195 lines
5.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# Test case for ejecting BDSs with block jobs still running on them
|
|
#
|
|
# Copyright (C) 2016 Red Hat, Inc.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
# creator
|
|
owner=mreitz@redhat.com
|
|
|
|
seq="$(basename $0)"
|
|
echo "QA output created by $seq"
|
|
|
|
status=1 # failure is the default!
|
|
|
|
_cleanup()
|
|
{
|
|
_cleanup_qemu
|
|
_cleanup_test_img
|
|
for img in "$TEST_DIR"/{b,m,o}.$IMGFMT; do
|
|
_rm_test_img "$img"
|
|
done
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common.rc
|
|
. ./common.filter
|
|
. ./common.qemu
|
|
|
|
# Needs backing file and backing format support
|
|
_supported_fmt qcow2 qed
|
|
_supported_proto file
|
|
_supported_os Linux
|
|
|
|
|
|
test_blockjob()
|
|
{
|
|
_send_qemu_cmd $QEMU_HANDLE \
|
|
"{'execute': 'blockdev-add',
|
|
'arguments': {
|
|
'node-name': 'drv0',
|
|
'driver': '$IMGFMT',
|
|
'file': {
|
|
'driver': 'file',
|
|
'filename': '$TEST_IMG'
|
|
}}}" \
|
|
'return'
|
|
|
|
# If "$2" is an event, we may or may not see it before the
|
|
# {"return": {}}. Therefore, filter the {"return": {}} out both
|
|
# here and in the next command. (Naturally, if we do not see it
|
|
# here, we will see it before the next command can be executed,
|
|
# so it will appear in the next _send_qemu_cmd's output.)
|
|
_send_qemu_cmd $QEMU_HANDLE \
|
|
"$1" \
|
|
"$2" \
|
|
| _filter_img_create_in_qmp | _filter_qmp_empty_return
|
|
|
|
# We want this to return an error because the block job is still running
|
|
_send_qemu_cmd $QEMU_HANDLE \
|
|
"{'execute': 'blockdev-del',
|
|
'arguments': {'node-name': 'drv0'}}" \
|
|
'error' | _filter_generated_node_ids | _filter_qmp_empty_return
|
|
|
|
_send_qemu_cmd $QEMU_HANDLE \
|
|
"{'execute': 'block-job-cancel',
|
|
'arguments': {'device': 'job0'}}" \
|
|
"$3"
|
|
|
|
_send_qemu_cmd $QEMU_HANDLE \
|
|
"{'execute': 'blockdev-del',
|
|
'arguments': {'node-name': 'drv0'}}" \
|
|
'return'
|
|
}
|
|
|
|
|
|
TEST_IMG="$TEST_DIR/b.$IMGFMT" _make_test_img 1M
|
|
TEST_IMG="$TEST_DIR/m.$IMGFMT" _make_test_img -b "$TEST_DIR/b.$IMGFMT" 1M
|
|
_make_test_img -b "$TEST_DIR/m.$IMGFMT" 1M
|
|
|
|
_launch_qemu -nodefaults
|
|
|
|
_send_qemu_cmd $QEMU_HANDLE \
|
|
"{'execute': 'qmp_capabilities'}" \
|
|
'return'
|
|
|
|
echo
|
|
echo '=== Testing drive-backup ==='
|
|
echo
|
|
|
|
# drive-backup will not send BLOCK_JOB_READY by itself, and cancelling the job
|
|
# will consequently result in BLOCK_JOB_CANCELLED being emitted.
|
|
|
|
test_blockjob \
|
|
"{'execute': 'drive-backup',
|
|
'arguments': {'job-id': 'job0',
|
|
'device': 'drv0',
|
|
'target': '$TEST_DIR/o.$IMGFMT',
|
|
'format': '$IMGFMT',
|
|
'sync': 'none'}}" \
|
|
'return' \
|
|
'"status": "null"'
|
|
|
|
echo
|
|
echo '=== Testing drive-mirror ==='
|
|
echo
|
|
|
|
# drive-mirror will send BLOCK_JOB_READY basically immediately, and cancelling
|
|
# the job will consequently result in BLOCK_JOB_COMPLETED being emitted.
|
|
|
|
test_blockjob \
|
|
"{'execute': 'drive-mirror',
|
|
'arguments': {'job-id': 'job0',
|
|
'device': 'drv0',
|
|
'target': '$TEST_DIR/o.$IMGFMT',
|
|
'format': '$IMGFMT',
|
|
'sync': 'none'}}" \
|
|
'BLOCK_JOB_READY' \
|
|
'"status": "null"'
|
|
|
|
echo
|
|
echo '=== Testing active block-commit ==='
|
|
echo
|
|
|
|
# An active block-commit will send BLOCK_JOB_READY basically immediately, and
|
|
# cancelling the job will consequently result in BLOCK_JOB_COMPLETED being
|
|
# emitted.
|
|
|
|
test_blockjob \
|
|
"{'execute': 'block-commit',
|
|
'arguments': {'job-id': 'job0', 'device': 'drv0'}}" \
|
|
'BLOCK_JOB_READY' \
|
|
'"status": "null"'
|
|
|
|
echo
|
|
echo '=== Testing non-active block-commit ==='
|
|
echo
|
|
|
|
# Give block-commit something to work on, otherwise it would be done
|
|
# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just
|
|
# fine without the block job still running.
|
|
|
|
$QEMU_IO -c 'write 0 1M' "$TEST_DIR/m.$IMGFMT" | _filter_qemu_io
|
|
|
|
test_blockjob \
|
|
"{'execute': 'block-commit',
|
|
'arguments': {'job-id': 'job0',
|
|
'device': 'drv0',
|
|
'top': '$TEST_DIR/m.$IMGFMT',
|
|
'speed': 1}}" \
|
|
'return' \
|
|
'"status": "null"'
|
|
|
|
echo
|
|
echo '=== Testing block-stream ==='
|
|
echo
|
|
|
|
# Give block-stream something to work on, otherwise it would be done
|
|
# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just
|
|
# fine without the block job still running.
|
|
|
|
$QEMU_IO -c 'write 0 1M' "$TEST_DIR/b.$IMGFMT" | _filter_qemu_io
|
|
|
|
# With some data to stream (and @speed set to 1), block-stream will not complete
|
|
# until we send the block-job-cancel command.
|
|
|
|
test_blockjob \
|
|
"{'execute': 'block-stream',
|
|
'arguments': {'job-id': 'job0',
|
|
'device': 'drv0',
|
|
'speed': 1}}" \
|
|
'return' \
|
|
'"status": "null"'
|
|
|
|
_cleanup_qemu
|
|
|
|
# success, all done
|
|
echo "*** done"
|
|
rm -f $seq.full
|
|
status=0
|