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_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 122wait=1 _cleanup_qemu 123 124echo 125echo === Start active commit job and exit qemu === 126echo 127 128_launch_qemu \ 129 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 130h=$QEMU_HANDLE 131_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 132 133_send_qemu_cmd $h \ 134 "{ 'execute': 'block-commit', 135 'arguments': { 'device': 'disk', 136 'base':'$TEST_IMG.base', 137 'speed': 65536 } }" \ 138 "return" 139 140_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 141wait=1 _cleanup_qemu 142 143echo 144echo === Start mirror job and exit qemu === 145echo 146 147_launch_qemu \ 148 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 149h=$QEMU_HANDLE 150_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 151 152_send_qemu_cmd $h \ 153 "{ 'execute': 'drive-mirror', 154 'arguments': { 'device': 'disk', 155 'target': '$TEST_IMG.copy', 156 'format': '$IMGFMT', 157 'sync': 'full', 158 'speed': 65536 } }" \ 159 "return" 160 161# If we don't sleep here 'quit' command may be handled before 162# the first mirror iteration is done 163sleep 0.5 164 165_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 166wait=1 _cleanup_qemu 167 168echo 169echo === Start backup job and exit qemu === 170echo 171 172_launch_qemu \ 173 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 174h=$QEMU_HANDLE 175_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 176 177_send_qemu_cmd $h \ 178 "{ 'execute': 'drive-backup', 179 'arguments': { 'device': 'disk', 180 'target': '$TEST_IMG.copy', 181 'format': '$IMGFMT', 182 'sync': 'full', 183 'speed': 65536 } }" \ 184 "return" 185 186_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 187wait=1 _cleanup_qemu 188 189echo 190echo === Start streaming job and exit qemu === 191echo 192 193_launch_qemu \ 194 -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk 195h=$QEMU_HANDLE 196_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 197 198_send_qemu_cmd $h \ 199 "{ 'execute': 'block-stream', 200 'arguments': { 'device': 'disk', 201 'speed': 65536 } }" \ 202 "return" 203 204_send_qemu_cmd $h "{ 'execute': 'quit' }" "return" 205wait=1 _cleanup_qemu 206 207_check_test_img 208 209# success, all done 210echo "*** done" 211rm -f $seq.full 212status=0 213