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_* events for all of the following block jobs. They are predictable 96# and any change in the offsets would hint at a bug in the job throttling code. 97# 98# In order to achieve these predictable offsets, all of the following tests 99# use speed=65536. Each job will perform exactly one iteration before it has 100# to sleep at least for a second, which is plenty of time for the 'quit' QMP 101# command to be received (after receiving the command, the rest runs 102# synchronously, so jobs can arbitrarily continue or complete). 103# 104# Jobs present while QEMU is terminating iterate once more due to 105# bdrv_drain_all(). 106# 107# The buffer size for commit and streaming is 512k (waiting for 8 seconds after 108# the first request), for active commit and mirror it's large enough to cover 109# the full 4M, and for backup it's the qcow2 cluster size, which we know is 110# 64k. As all of these are at least as large as the speed, we are sure that the 111# offset advances exactly twice before qemu exits. 112 113_send_qemu_cmd $h \ 114 "{ 'execute': 'block-commit', 115 'arguments': { 'device': 'disk', 116 'base':'$TEST_IMG.base', 117 'top': '$TEST_IMG.mid', 118 'speed': 65536 } }" \ 119 "return" 120 121# If we don't sleep here 'quit' command races with disk I/O 122sleep 0.5 123 124_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 125wait=1 _cleanup_qemu 126 127echo 128echo === Start active commit job and exit qemu === 129echo 130 131_launch_qemu \ 132 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 133h=$QEMU_HANDLE 134_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 135 136_send_qemu_cmd $h \ 137 "{ 'execute': 'block-commit', 138 'arguments': { 'device': 'disk', 139 'base':'$TEST_IMG.base', 140 'speed': 65536 } }" \ 141 "return" 142 143# If we don't sleep here 'quit' command races with disk I/O 144sleep 0.5 145 146_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 147wait=1 _cleanup_qemu 148 149echo 150echo === Start mirror job and exit qemu === 151echo 152 153_launch_qemu \ 154 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 155h=$QEMU_HANDLE 156_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 157 158_send_qemu_cmd $h \ 159 "{ 'execute': 'drive-mirror', 160 'arguments': { 'device': 'disk', 161 'target': '$TEST_IMG.copy', 162 'format': '$IMGFMT', 163 'sync': 'full', 164 'speed': 65536 } }" \ 165 "return" 166 167# If we don't sleep here 'quit' command may be handled before 168# the first mirror iteration is done 169sleep 0.5 170 171_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 172wait=1 _cleanup_qemu 173 174echo 175echo === Start backup job and exit qemu === 176echo 177 178_launch_qemu \ 179 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 180h=$QEMU_HANDLE 181_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 182 183_send_qemu_cmd $h \ 184 "{ 'execute': 'drive-backup', 185 'arguments': { 'device': 'disk', 186 'target': '$TEST_IMG.copy', 187 'format': '$IMGFMT', 188 'sync': 'full', 189 'speed': 65536 } }" \ 190 "return" 191 192# If we don't sleep here 'quit' command races with disk I/O 193sleep 0.5 194 195_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 196wait=1 _cleanup_qemu 197 198echo 199echo === Start streaming job and exit qemu === 200echo 201 202_launch_qemu \ 203 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 204h=$QEMU_HANDLE 205_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 206 207_send_qemu_cmd $h \ 208 "{ 'execute': 'block-stream', 209 'arguments': { 'device': 'disk', 210 'speed': 65536 } }" \ 211 "return" 212 213# If we don't sleep here 'quit' command races with disk I/O 214sleep 0.5 215 216_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 217wait=1 _cleanup_qemu 218 219_check_test_img 220 221# success, all done 222echo "*** done" 223rm -f $seq.full 224status=0 225