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