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