1#!/usr/bin/env python3 2# 3# Copyright (C) 2017 Red Hat, Inc. 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17# 18# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com> 19# 20# Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a 21# single IOThread completes successfully. This particular command triggered a 22# hang due to recursive AioContext locking and BDRV_POLL_WHILE(). Protect 23# against regressions. 24 25import iotests 26 27iotests.script_initialize(supported_fmts=['qcow2'], 28 supported_platforms=['linux']) 29 30with iotests.FilePath('disk0.img') as disk0_img_path, \ 31 iotests.FilePath('disk1.img') as disk1_img_path, \ 32 iotests.FilePath('disk0-snap.img') as disk0_snap_img_path, \ 33 iotests.FilePath('disk1-snap.img') as disk1_snap_img_path, \ 34 iotests.VM() as vm: 35 36 img_size = '10M' 37 iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size) 38 iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size) 39 40 iotests.log('Launching VM...') 41 vm.launch() 42 43 iotests.log('Adding IOThread...') 44 iotests.log(vm.qmp('object-add', 45 qom_type='iothread', 46 id='iothread0')) 47 48 iotests.log('Adding blockdevs...') 49 iotests.log(vm.qmp('blockdev-add', 50 driver=iotests.imgfmt, 51 node_name='disk0', 52 file={ 53 'driver': 'file', 54 'filename': disk0_img_path, 55 })) 56 iotests.log(vm.qmp('blockdev-add', 57 driver=iotests.imgfmt, 58 node_name='disk1', 59 file={ 60 'driver': 'file', 61 'filename': disk1_img_path, 62 })) 63 64 iotests.log('Setting iothread...') 65 iotests.log(vm.qmp('x-blockdev-set-iothread', 66 node_name='disk0', 67 iothread='iothread0')) 68 iotests.log(vm.qmp('x-blockdev-set-iothread', 69 node_name='disk1', 70 iothread='iothread0')) 71 72 iotests.log('Creating external snapshots...') 73 iotests.log(vm.qmp( 74 'transaction', 75 actions=[ 76 { 77 'data': { 78 'node-name': 'disk0', 79 'snapshot-file': disk0_snap_img_path, 80 'snapshot-node-name': 'disk0-snap', 81 'mode': 'absolute-paths', 82 'format': iotests.imgfmt, 83 }, 84 'type': 'blockdev-snapshot-sync' 85 }, { 86 'data': { 87 'node-name': 'disk1', 88 'snapshot-file': disk1_snap_img_path, 89 'snapshot-node-name': 'disk1-snap', 90 'mode': 'absolute-paths', 91 'format': iotests.imgfmt 92 }, 93 'type': 'blockdev-snapshot-sync' 94 } 95 ])) 96