xref: /openbmc/qemu/tests/qemu-iotests/256 (revision b91a0fa7)
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