1#!/usr/bin/env bash 2# 3# Test case for ejecting BDSs with block jobs still running on them 4# 5# Copyright (C) 2016 Red Hat, Inc. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20 21# creator 22owner=mreitz@redhat.com 23 24seq="$(basename $0)" 25echo "QA output created by $seq" 26 27status=1 # failure is the default! 28 29_cleanup() 30{ 31 _cleanup_qemu 32 _cleanup_test_img 33 rm -f "$TEST_DIR"/{b,m,o}.$IMGFMT 34} 35trap "_cleanup; exit \$status" 0 1 2 3 15 36 37# get standard environment, filters and checks 38. ./common.rc 39. ./common.filter 40. ./common.qemu 41 42# Needs backing file and backing format support 43_supported_fmt qcow2 qed 44_supported_proto file 45_supported_os Linux 46 47 48test_blockjob() 49{ 50 _send_qemu_cmd $QEMU_HANDLE \ 51 "{'execute': 'blockdev-add', 52 'arguments': { 53 'node-name': 'drv0', 54 'driver': '$IMGFMT', 55 'file': { 56 'driver': 'file', 57 'filename': '$TEST_IMG' 58 }}}" \ 59 'return' 60 61 # If "$2" is an event, we may or may not see it before the 62 # {"return": {}}. Therefore, filter the {"return": {}} out both 63 # here and in the next command. (Naturally, if we do not see it 64 # here, we will see it before the next command can be executed, 65 # so it will appear in the next _send_qemu_cmd's output.) 66 _send_qemu_cmd $QEMU_HANDLE \ 67 "$1" \ 68 "$2" \ 69 | _filter_img_create | _filter_qmp_empty_return 70 71 # We want this to return an error because the block job is still running 72 _send_qemu_cmd $QEMU_HANDLE \ 73 "{'execute': 'blockdev-del', 74 'arguments': {'node-name': 'drv0'}}" \ 75 'error' | _filter_generated_node_ids | _filter_qmp_empty_return 76 77 _send_qemu_cmd $QEMU_HANDLE \ 78 "{'execute': 'block-job-cancel', 79 'arguments': {'device': 'job0'}}" \ 80 "$3" 81 82 _send_qemu_cmd $QEMU_HANDLE \ 83 "{'execute': 'blockdev-del', 84 'arguments': {'node-name': 'drv0'}}" \ 85 'return' 86} 87 88 89TEST_IMG="$TEST_DIR/b.$IMGFMT" _make_test_img 1M 90TEST_IMG="$TEST_DIR/m.$IMGFMT" _make_test_img -b "$TEST_DIR/b.$IMGFMT" 1M 91_make_test_img -b "$TEST_DIR/m.$IMGFMT" 1M 92 93_launch_qemu -nodefaults 94 95_send_qemu_cmd $QEMU_HANDLE \ 96 "{'execute': 'qmp_capabilities'}" \ 97 'return' 98 99echo 100echo '=== Testing drive-backup ===' 101echo 102 103# drive-backup will not send BLOCK_JOB_READY by itself, and cancelling the job 104# will consequently result in BLOCK_JOB_CANCELLED being emitted. 105 106test_blockjob \ 107 "{'execute': 'drive-backup', 108 'arguments': {'job-id': 'job0', 109 'device': 'drv0', 110 'target': '$TEST_DIR/o.$IMGFMT', 111 'format': '$IMGFMT', 112 'sync': 'none'}}" \ 113 'return' \ 114 '"status": "null"' 115 116echo 117echo '=== Testing drive-mirror ===' 118echo 119 120# drive-mirror will send BLOCK_JOB_READY basically immediately, and cancelling 121# the job will consequently result in BLOCK_JOB_COMPLETED being emitted. 122 123test_blockjob \ 124 "{'execute': 'drive-mirror', 125 'arguments': {'job-id': 'job0', 126 'device': 'drv0', 127 'target': '$TEST_DIR/o.$IMGFMT', 128 'format': '$IMGFMT', 129 'sync': 'none'}}" \ 130 'BLOCK_JOB_READY' \ 131 '"status": "null"' 132 133echo 134echo '=== Testing active block-commit ===' 135echo 136 137# An active block-commit will send BLOCK_JOB_READY basically immediately, and 138# cancelling the job will consequently result in BLOCK_JOB_COMPLETED being 139# emitted. 140 141test_blockjob \ 142 "{'execute': 'block-commit', 143 'arguments': {'job-id': 'job0', 'device': 'drv0'}}" \ 144 'BLOCK_JOB_READY' \ 145 '"status": "null"' 146 147echo 148echo '=== Testing non-active block-commit ===' 149echo 150 151# Give block-commit something to work on, otherwise it would be done 152# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just 153# fine without the block job still running. 154 155$QEMU_IO -c 'write 0 1M' "$TEST_DIR/m.$IMGFMT" | _filter_qemu_io 156 157test_blockjob \ 158 "{'execute': 'block-commit', 159 'arguments': {'job-id': 'job0', 160 'device': 'drv0', 161 'top': '$TEST_DIR/m.$IMGFMT', 162 'speed': 1}}" \ 163 'return' \ 164 '"status": "null"' 165 166echo 167echo '=== Testing block-stream ===' 168echo 169 170# Give block-stream something to work on, otherwise it would be done 171# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just 172# fine without the block job still running. 173 174$QEMU_IO -c 'write 0 1M' "$TEST_DIR/b.$IMGFMT" | _filter_qemu_io 175 176# With some data to stream (and @speed set to 1), block-stream will not complete 177# until we send the block-job-cancel command. 178 179test_blockjob \ 180 "{'execute': 'block-stream', 181 'arguments': {'job-id': 'job0', 182 'device': 'drv0', 183 'speed': 1}}" \ 184 'return' \ 185 '"status": "null"' 186 187_cleanup_qemu 188 189# success, all done 190echo "*** done" 191rm -f $seq.full 192status=0 193