1#!/bin/bash 2# 3# Test exiting qemu while jobs are still running 4# 5# Copyright (C) 2017 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=kwolf@redhat.com 23 24seq=`basename $0` 25echo "QA output created by $seq" 26 27here=`pwd` 28status=1 # failure is the default! 29 30MIG_SOCKET="${TEST_DIR}/migrate" 31 32_cleanup() 33{ 34 rm -f "${TEST_IMG}.mid" 35 rm -f "${TEST_IMG}.copy" 36 _cleanup_test_img 37 _cleanup_qemu 38} 39trap "_cleanup; exit \$status" 0 1 2 3 15 40 41# get standard environment, filters and checks 42. ./common.rc 43. ./common.filter 44. ./common.qemu 45 46_supported_fmt qcow2 47_supported_proto file 48_supported_os Linux 49 50size=64M 51TEST_IMG="${TEST_IMG}.base" _make_test_img $size 52 53echo 54echo === Starting VM === 55echo 56 57qemu_comm_method="qmp" 58 59_launch_qemu \ 60 -drive file="${TEST_IMG}.base",cache=$CACHEMODE,driver=$IMGFMT,id=disk 61h=$QEMU_HANDLE 62_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 63 64echo 65echo === Creating backing chain === 66echo 67 68_send_qemu_cmd $h \ 69 "{ 'execute': 'blockdev-snapshot-sync', 70 'arguments': { 'device': 'disk', 71 'snapshot-file': '$TEST_IMG.mid', 72 'format': '$IMGFMT', 73 'mode': 'absolute-paths' } }" \ 74 "return" 75 76_send_qemu_cmd $h \ 77 "{ 'execute': 'human-monitor-command', 78 'arguments': { 'command-line': 79 'qemu-io disk \"write 0 4M\"' } }" \ 80 "return" 81 82_send_qemu_cmd $h \ 83 "{ 'execute': 'blockdev-snapshot-sync', 84 'arguments': { 'device': 'disk', 85 'snapshot-file': '$TEST_IMG', 86 'format': '$IMGFMT', 87 'mode': 'absolute-paths' } }" \ 88 "return" 89 90echo 91echo === Start commit job and exit qemu === 92echo 93 94# Note that the reference output intentionally includes the 'offset' field in 95# BLOCK_JOB_CANCELLED events for all of the following block jobs. They are 96# predictable and any change in the offsets would hint at a bug in the job 97# throttling code. 98# 99# In order to achieve these predictable offsets, all of the following tests 100# use speed=65536. Each job will perform exactly one iteration before it has 101# to sleep at least for a second, which is plenty of time for the 'quit' QMP 102# command to be received (after receiving the command, the rest runs 103# synchronously, so jobs can arbitrarily continue or complete). 104# 105# The buffer size for commit and streaming is 512k (waiting for 8 seconds after 106# the first request), for active commit and mirror it's large enough to cover 107# the full 4M, and for backup it's the qcow2 cluster size, which we know is 108# 64k. As all of these are at least as large as the speed, we are sure that the 109# offset doesn't advance after the first iteration before qemu exits. 110 111_send_qemu_cmd $h \ 112 "{ 'execute': 'block-commit', 113 'arguments': { 'device': 'disk', 114 'base':'$TEST_IMG.base', 115 'top': '$TEST_IMG.mid', 116 'speed': 65536 } }" \ 117 "return" 118 119_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 120wait=1 _cleanup_qemu 121 122echo 123echo === Start active commit job and exit qemu === 124echo 125 126_launch_qemu \ 127 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 128h=$QEMU_HANDLE 129_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 130 131_send_qemu_cmd $h \ 132 "{ 'execute': 'block-commit', 133 'arguments': { 'device': 'disk', 134 'base':'$TEST_IMG.base', 135 'speed': 65536 } }" \ 136 "return" 137 138_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 139wait=1 _cleanup_qemu 140 141echo 142echo === Start mirror job and exit qemu === 143echo 144 145_launch_qemu \ 146 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 147h=$QEMU_HANDLE 148_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 149 150_send_qemu_cmd $h \ 151 "{ 'execute': 'drive-mirror', 152 'arguments': { 'device': 'disk', 153 'target': '$TEST_IMG.copy', 154 'format': '$IMGFMT', 155 'sync': 'full', 156 'speed': 65536 } }" \ 157 "return" 158 159# If we don't sleep here 'quit' command may be handled before 160# the first mirror iteration is done 161sleep 0.5 162 163_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 164wait=1 _cleanup_qemu 165 166echo 167echo === Start backup job and exit qemu === 168echo 169 170_launch_qemu \ 171 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 172h=$QEMU_HANDLE 173_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 174 175_send_qemu_cmd $h \ 176 "{ 'execute': 'drive-backup', 177 'arguments': { 'device': 'disk', 178 'target': '$TEST_IMG.copy', 179 'format': '$IMGFMT', 180 'sync': 'full', 181 'speed': 65536 } }" \ 182 "return" 183 184_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 185wait=1 _cleanup_qemu 186 187echo 188echo === Start streaming job and exit qemu === 189echo 190 191_launch_qemu \ 192 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 193h=$QEMU_HANDLE 194_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 195 196_send_qemu_cmd $h \ 197 "{ 'execute': 'block-stream', 198 'arguments': { 'device': 'disk', 199 'speed': 65536 } }" \ 200 "return" 201 202_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 203wait=1 _cleanup_qemu 204 205_check_test_img 206 207# success, all done 208echo "*** done" 209rm -f $seq.full 210status=0 211