1#!/usr/bin/env python3 2# group: rw quick 3# 4# This test covers what happens when a mirror block job is cancelled 5# in various phases of its existence. 6# 7# Note that this test only checks the emitted events (i.e. 8# BLOCK_JOB_COMPLETED vs. BLOCK_JOB_CANCELLED), it does not compare 9# whether the target is in sync with the source when the 10# BLOCK_JOB_COMPLETED event occurs. This is covered by other tests 11# (such as 041). 12# 13# Copyright (C) 2018 Red Hat, Inc. 14# 15# This program is free software; you can redistribute it and/or modify 16# it under the terms of the GNU General Public License as published by 17# the Free Software Foundation; either version 2 of the License, or 18# (at your option) any later version. 19# 20# This program is distributed in the hope that it will be useful, 21# but WITHOUT ANY WARRANTY; without even the implied warranty of 22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23# GNU General Public License for more details. 24# 25# You should have received a copy of the GNU General Public License 26# along with this program. If not, see <http://www.gnu.org/licenses/>. 27# 28# Creator/Owner: Hanna Reitz <hreitz@redhat.com> 29 30import iotests 31from iotests import log, qemu_img, qemu_io 32 33iotests.script_initialize(supported_fmts=['qcow2', 'raw']) 34 35 36# Launches the VM, adds two null-co nodes (source and target), and 37# starts a blockdev-mirror job on them. 38# 39# Either both or none of speed and buf_size must be given. 40 41def start_mirror(vm, speed=None, buf_size=None): 42 vm.launch() 43 44 vm.cmd('blockdev-add', 45 node_name='source', 46 driver='null-co', 47 size=1048576) 48 49 vm.cmd('blockdev-add', 50 node_name='target', 51 driver='null-co', 52 size=1048576) 53 54 if speed is not None: 55 vm.cmd('blockdev-mirror', 56 job_id='mirror', 57 device='source', 58 target='target', 59 sync='full', 60 speed=speed, 61 buf_size=buf_size) 62 else: 63 vm.cmd('blockdev-mirror', 64 job_id='mirror', 65 device='source', 66 target='target', 67 sync='full') 68 69 70log('') 71log('=== Cancel mirror job before convergence ===') 72log('') 73 74log('--- force=false ---') 75log('') 76 77with iotests.VM() as vm: 78 # Low speed so it does not converge 79 start_mirror(vm, 65536, 65536) 80 81 log('Cancelling job') 82 log(vm.qmp('block-job-cancel', device='mirror', force=False)) 83 84 log(vm.event_wait('BLOCK_JOB_CANCELLED'), 85 filters=[iotests.filter_qmp_event]) 86 87log('') 88log('--- force=true ---') 89log('') 90 91with iotests.VM() as vm: 92 # Low speed so it does not converge 93 start_mirror(vm, 65536, 65536) 94 95 log('Cancelling job') 96 log(vm.qmp('block-job-cancel', device='mirror', force=True)) 97 98 log(vm.event_wait('BLOCK_JOB_CANCELLED'), 99 filters=[iotests.filter_qmp_event]) 100 101 102log('') 103log('=== Cancel mirror job after convergence ===') 104log('') 105 106log('--- force=false ---') 107log('') 108 109with iotests.VM() as vm: 110 start_mirror(vm) 111 112 log(vm.event_wait('BLOCK_JOB_READY'), 113 filters=[iotests.filter_qmp_event]) 114 115 log('Cancelling job') 116 log(vm.qmp('block-job-cancel', device='mirror', force=False)) 117 118 log(vm.event_wait('BLOCK_JOB_COMPLETED'), 119 filters=[iotests.filter_qmp_event]) 120 121log('') 122log('--- force=true ---') 123log('') 124 125with iotests.VM() as vm: 126 start_mirror(vm) 127 128 log(vm.event_wait('BLOCK_JOB_READY'), 129 filters=[iotests.filter_qmp_event]) 130 131 log('Cancelling job') 132 log(vm.qmp('block-job-cancel', device='mirror', force=True)) 133 134 log(vm.event_wait('BLOCK_JOB_CANCELLED'), 135 filters=[iotests.filter_qmp_event]) 136 137log('') 138log('=== Cancel mirror job from throttled node by quitting ===') 139log('') 140 141with iotests.VM() as vm, \ 142 iotests.FilePath('src.img') as src_img_path: 143 144 qemu_img('create', '-f', iotests.imgfmt, src_img_path, '64M') 145 qemu_io('-f', iotests.imgfmt, src_img_path, '-c', 'write -P 42 0M 64M') 146 147 vm.launch() 148 149 vm.cmd('object-add', qom_type='throttle-group', id='tg', 150 limits={'bps-read': 4096}) 151 152 vm.cmd('blockdev-add', 153 node_name='source', 154 driver=iotests.imgfmt, 155 file={ 156 'driver': 'file', 157 'filename': src_img_path 158 }) 159 160 vm.cmd('blockdev-add', 161 node_name='throttled-source', 162 driver='throttle', 163 throttle_group='tg', 164 file='source') 165 166 vm.cmd('blockdev-add', 167 node_name='target', 168 driver='null-co', 169 size=(64 * 1048576)) 170 171 vm.cmd('blockdev-mirror', 172 job_id='mirror', 173 device='throttled-source', 174 target='target', 175 sync='full') 176 177 log(vm.qmp('quit')) 178 179 with iotests.Timeout(5, 'Timeout waiting for VM to quit'): 180 vm.shutdown() 181