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