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