1#!/usr/bin/env python3 2# group: rw auto quick 3# 4# Test incremental/backup across iothread contexts 5# 6# Copyright (c) 2019 John Snow for Red Hat, Inc. 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program. If not, see <http://www.gnu.org/licenses/>. 20# 21# owner=jsnow@redhat.com 22 23import os 24import iotests 25from iotests import log 26 27iotests._verify_virtio_scsi_pci_or_ccw() 28 29iotests.script_initialize(supported_fmts=['qcow2']) 30size = 64 * 1024 * 1024 31 32with iotests.FilePath('img0') as img0_path, \ 33 iotests.FilePath('img1') as img1_path, \ 34 iotests.FilePath('img0-full') as img0_full_path, \ 35 iotests.FilePath('img1-full') as img1_full_path, \ 36 iotests.FilePath('img0-incr') as img0_incr_path, \ 37 iotests.FilePath('img1-incr') as img1_incr_path, \ 38 iotests.VM() as vm: 39 40 def create_target(filepath, name, size): 41 basename = os.path.basename(filepath) 42 nodename = "file_{}".format(basename) 43 log(vm.command('blockdev-create', job_id='job1', 44 options={ 45 'driver': 'file', 46 'filename': filepath, 47 'size': 0, 48 })) 49 vm.run_job('job1') 50 log(vm.command('blockdev-add', driver='file', 51 node_name=nodename, filename=filepath)) 52 log(vm.command('blockdev-create', job_id='job2', 53 options={ 54 'driver': iotests.imgfmt, 55 'file': nodename, 56 'size': size, 57 })) 58 vm.run_job('job2') 59 log(vm.command('blockdev-add', driver=iotests.imgfmt, 60 node_name=name, 61 file=nodename)) 62 63 log('--- Preparing images & VM ---\n') 64 vm.add_object('iothread,id=iothread0') 65 vm.add_object('iothread,id=iothread1') 66 vm.add_device('virtio-scsi,id=scsi0,iothread=iothread0') 67 vm.add_device('virtio-scsi,id=scsi1,iothread=iothread1') 68 iotests.qemu_img_create('-f', iotests.imgfmt, img0_path, str(size)) 69 iotests.qemu_img_create('-f', iotests.imgfmt, img1_path, str(size)) 70 vm.add_drive(img0_path, interface='none') 71 vm.add_device('scsi-hd,id=device0,drive=drive0,bus=scsi0.0') 72 vm.add_drive(img1_path, interface='none') 73 vm.add_device('scsi-hd,id=device1,drive=drive1,bus=scsi1.0') 74 75 log('--- Starting VM ---\n') 76 vm.launch() 77 78 log('--- Create Targets & Full Backups ---\n') 79 create_target(img0_full_path, 'img0-full', size) 80 create_target(img1_full_path, 'img1-full', size) 81 ret = vm.qmp_log('transaction', indent=2, actions=[ 82 { 'type': 'block-dirty-bitmap-add', 83 'data': { 'node': 'drive0', 'name': 'bitmap0' }}, 84 { 'type': 'block-dirty-bitmap-add', 85 'data': { 'node': 'drive1', 'name': 'bitmap1' }}, 86 { 'type': 'blockdev-backup', 87 'data': { 'device': 'drive0', 88 'target': 'img0-full', 89 'sync': 'full', 90 'job-id': 'j0' }}, 91 { 'type': 'blockdev-backup', 92 'data': { 'device': 'drive1', 93 'target': 'img1-full', 94 'sync': 'full', 95 'job-id': 'j1' }} 96 ]) 97 if "error" in ret: 98 raise Exception(ret['error']['desc']) 99 vm.run_job('j0', auto_dismiss=True) 100 vm.run_job('j1', auto_dismiss=True) 101 102 log('\n--- Create Targets & Incremental Backups ---\n') 103 create_target(img0_incr_path, 'img0-incr', size) 104 create_target(img1_incr_path, 'img1-incr', size) 105 ret = vm.qmp_log('transaction', indent=2, actions=[ 106 { 'type': 'blockdev-backup', 107 'data': { 'device': 'drive0', 108 'target': 'img0-incr', 109 'sync': 'incremental', 110 'bitmap': 'bitmap0', 111 'job-id': 'j2' }}, 112 { 'type': 'blockdev-backup', 113 'data': { 'device': 'drive1', 114 'target': 'img1-incr', 115 'sync': 'incremental', 116 'bitmap': 'bitmap1', 117 'job-id': 'j3' }} 118 ]) 119 if "error" in ret: 120 raise Exception(ret['error']['desc']) 121 vm.run_job('j2', auto_dismiss=True) 122 vm.run_job('j3', auto_dismiss=True) 123 124 log('\n--- Done ---') 125 vm.shutdown() 126