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