xref: /openbmc/qemu/tests/qemu-iotests/218 (revision 49278ec065da3fbf90f7effcde3b39ac606b2e9e)
1dc885fffSMax Reitz#!/usr/bin/env python
2dc885fffSMax Reitz#
3dc885fffSMax Reitz# This test covers what happens when a mirror block job is cancelled
4dc885fffSMax Reitz# in various phases of its existence.
5dc885fffSMax Reitz#
6dc885fffSMax Reitz# Note that this test only checks the emitted events (i.e.
7dc885fffSMax Reitz# BLOCK_JOB_COMPLETED vs. BLOCK_JOB_CANCELLED), it does not compare
8dc885fffSMax Reitz# whether the target is in sync with the source when the
9dc885fffSMax Reitz# BLOCK_JOB_COMPLETED event occurs.  This is covered by other tests
10dc885fffSMax Reitz# (such as 041).
11dc885fffSMax Reitz#
12dc885fffSMax Reitz# Copyright (C) 2018 Red Hat, Inc.
13dc885fffSMax Reitz#
14dc885fffSMax Reitz# This program is free software; you can redistribute it and/or modify
15dc885fffSMax Reitz# it under the terms of the GNU General Public License as published by
16dc885fffSMax Reitz# the Free Software Foundation; either version 2 of the License, or
17dc885fffSMax Reitz# (at your option) any later version.
18dc885fffSMax Reitz#
19dc885fffSMax Reitz# This program is distributed in the hope that it will be useful,
20dc885fffSMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of
21dc885fffSMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22dc885fffSMax Reitz# GNU General Public License for more details.
23dc885fffSMax Reitz#
24dc885fffSMax Reitz# You should have received a copy of the GNU General Public License
25dc885fffSMax Reitz# along with this program.  If not, see <http://www.gnu.org/licenses/>.
26dc885fffSMax Reitz#
27dc885fffSMax Reitz# Creator/Owner: Max Reitz <mreitz@redhat.com>
28dc885fffSMax Reitz
29dc885fffSMax Reitzimport iotests
30*49278ec0SMax Reitzfrom iotests import log, qemu_img, qemu_io_silent
31dc885fffSMax Reitz
32*49278ec0SMax Reitziotests.verify_image_format(supported_fmts=['qcow2', 'raw'])
33dc885fffSMax Reitz
34dc885fffSMax Reitz
35dc885fffSMax Reitz# Launches the VM, adds two null-co nodes (source and target), and
36dc885fffSMax Reitz# starts a blockdev-mirror job on them.
37dc885fffSMax Reitz#
38dc885fffSMax Reitz# Either both or none of speed and buf_size must be given.
39dc885fffSMax Reitz
40dc885fffSMax Reitzdef start_mirror(vm, speed=None, buf_size=None):
41dc885fffSMax Reitz    vm.launch()
42dc885fffSMax Reitz
43dc885fffSMax Reitz    ret = vm.qmp('blockdev-add',
44dc885fffSMax Reitz                     node_name='source',
45dc885fffSMax Reitz                     driver='null-co',
46dc885fffSMax Reitz                     size=1048576)
47dc885fffSMax Reitz    assert ret['return'] == {}
48dc885fffSMax Reitz
49dc885fffSMax Reitz    ret = vm.qmp('blockdev-add',
50dc885fffSMax Reitz                     node_name='target',
51dc885fffSMax Reitz                     driver='null-co',
52dc885fffSMax Reitz                     size=1048576)
53dc885fffSMax Reitz    assert ret['return'] == {}
54dc885fffSMax Reitz
55dc885fffSMax Reitz    if speed is not None:
56dc885fffSMax Reitz        ret = vm.qmp('blockdev-mirror',
57dc885fffSMax Reitz                         job_id='mirror',
58dc885fffSMax Reitz                         device='source',
59dc885fffSMax Reitz                         target='target',
60dc885fffSMax Reitz                         sync='full',
61dc885fffSMax Reitz                         speed=speed,
62dc885fffSMax Reitz                         buf_size=buf_size)
63dc885fffSMax Reitz    else:
64dc885fffSMax Reitz        ret = vm.qmp('blockdev-mirror',
65dc885fffSMax Reitz                         job_id='mirror',
66dc885fffSMax Reitz                         device='source',
67dc885fffSMax Reitz                         target='target',
68dc885fffSMax Reitz                         sync='full')
69dc885fffSMax Reitz
70dc885fffSMax Reitz    assert ret['return'] == {}
71dc885fffSMax Reitz
72dc885fffSMax Reitz
73dc885fffSMax Reitzlog('')
74dc885fffSMax Reitzlog('=== Cancel mirror job before convergence ===')
75dc885fffSMax Reitzlog('')
76dc885fffSMax Reitz
77dc885fffSMax Reitzlog('--- force=false ---')
78dc885fffSMax Reitzlog('')
79dc885fffSMax Reitz
80dc885fffSMax Reitzwith iotests.VM() as vm:
81dc885fffSMax Reitz    # Low speed so it does not converge
82dc885fffSMax Reitz    start_mirror(vm, 65536, 65536)
83dc885fffSMax Reitz
84dc885fffSMax Reitz    log('Cancelling job')
85dc885fffSMax Reitz    log(vm.qmp('block-job-cancel', device='mirror', force=False))
86dc885fffSMax Reitz
87dc885fffSMax Reitz    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
88dc885fffSMax Reitz        filters=[iotests.filter_qmp_event])
89dc885fffSMax Reitz
90dc885fffSMax Reitzlog('')
91dc885fffSMax Reitzlog('--- force=true ---')
92dc885fffSMax Reitzlog('')
93dc885fffSMax Reitz
94dc885fffSMax Reitzwith iotests.VM() as vm:
95dc885fffSMax Reitz    # Low speed so it does not converge
96dc885fffSMax Reitz    start_mirror(vm, 65536, 65536)
97dc885fffSMax Reitz
98dc885fffSMax Reitz    log('Cancelling job')
99dc885fffSMax Reitz    log(vm.qmp('block-job-cancel', device='mirror', force=True))
100dc885fffSMax Reitz
101dc885fffSMax Reitz    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
102dc885fffSMax Reitz        filters=[iotests.filter_qmp_event])
103dc885fffSMax Reitz
104dc885fffSMax Reitz
105dc885fffSMax Reitzlog('')
106dc885fffSMax Reitzlog('=== Cancel mirror job after convergence ===')
107dc885fffSMax Reitzlog('')
108dc885fffSMax Reitz
109dc885fffSMax Reitzlog('--- force=false ---')
110dc885fffSMax Reitzlog('')
111dc885fffSMax Reitz
112dc885fffSMax Reitzwith iotests.VM() as vm:
113dc885fffSMax Reitz    start_mirror(vm)
114dc885fffSMax Reitz
115dc885fffSMax Reitz    log(vm.event_wait('BLOCK_JOB_READY'),
116dc885fffSMax Reitz        filters=[iotests.filter_qmp_event])
117dc885fffSMax Reitz
118dc885fffSMax Reitz    log('Cancelling job')
119dc885fffSMax Reitz    log(vm.qmp('block-job-cancel', device='mirror', force=False))
120dc885fffSMax Reitz
121dc885fffSMax Reitz    log(vm.event_wait('BLOCK_JOB_COMPLETED'),
122dc885fffSMax Reitz        filters=[iotests.filter_qmp_event])
123dc885fffSMax Reitz
124dc885fffSMax Reitzlog('')
125dc885fffSMax Reitzlog('--- force=true ---')
126dc885fffSMax Reitzlog('')
127dc885fffSMax Reitz
128dc885fffSMax Reitzwith iotests.VM() as vm:
129dc885fffSMax Reitz    start_mirror(vm)
130dc885fffSMax Reitz
131dc885fffSMax Reitz    log(vm.event_wait('BLOCK_JOB_READY'),
132dc885fffSMax Reitz        filters=[iotests.filter_qmp_event])
133dc885fffSMax Reitz
134dc885fffSMax Reitz    log('Cancelling job')
135dc885fffSMax Reitz    log(vm.qmp('block-job-cancel', device='mirror', force=True))
136dc885fffSMax Reitz
137dc885fffSMax Reitz    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
138dc885fffSMax Reitz        filters=[iotests.filter_qmp_event])
139*49278ec0SMax Reitz
140*49278ec0SMax Reitzlog('')
141*49278ec0SMax Reitzlog('=== Cancel mirror job from throttled node by quitting ===')
142*49278ec0SMax Reitzlog('')
143*49278ec0SMax Reitz
144*49278ec0SMax Reitzwith iotests.VM() as vm, \
145*49278ec0SMax Reitz     iotests.FilePath('src.img') as src_img_path:
146*49278ec0SMax Reitz
147*49278ec0SMax Reitz    assert qemu_img('create', '-f', iotests.imgfmt, src_img_path, '64M') == 0
148*49278ec0SMax Reitz    assert qemu_io_silent('-f', iotests.imgfmt, src_img_path,
149*49278ec0SMax Reitz                          '-c', 'write -P 42 0M 64M') == 0
150*49278ec0SMax Reitz
151*49278ec0SMax Reitz    vm.launch()
152*49278ec0SMax Reitz
153*49278ec0SMax Reitz    ret = vm.qmp('object-add', qom_type='throttle-group', id='tg',
154*49278ec0SMax Reitz                 props={'x-bps-read': 4096})
155*49278ec0SMax Reitz    assert ret['return'] == {}
156*49278ec0SMax Reitz
157*49278ec0SMax Reitz    ret = vm.qmp('blockdev-add',
158*49278ec0SMax Reitz                 node_name='source',
159*49278ec0SMax Reitz                 driver=iotests.imgfmt,
160*49278ec0SMax Reitz                 file={
161*49278ec0SMax Reitz                     'driver': 'file',
162*49278ec0SMax Reitz                     'filename': src_img_path
163*49278ec0SMax Reitz                 })
164*49278ec0SMax Reitz    assert ret['return'] == {}
165*49278ec0SMax Reitz
166*49278ec0SMax Reitz    ret = vm.qmp('blockdev-add',
167*49278ec0SMax Reitz                 node_name='throttled-source',
168*49278ec0SMax Reitz                 driver='throttle',
169*49278ec0SMax Reitz                 throttle_group='tg',
170*49278ec0SMax Reitz                 file='source')
171*49278ec0SMax Reitz    assert ret['return'] == {}
172*49278ec0SMax Reitz
173*49278ec0SMax Reitz    ret = vm.qmp('blockdev-add',
174*49278ec0SMax Reitz                 node_name='target',
175*49278ec0SMax Reitz                 driver='null-co',
176*49278ec0SMax Reitz                 size=(64 * 1048576))
177*49278ec0SMax Reitz    assert ret['return'] == {}
178*49278ec0SMax Reitz
179*49278ec0SMax Reitz    ret = vm.qmp('blockdev-mirror',
180*49278ec0SMax Reitz                 job_id='mirror',
181*49278ec0SMax Reitz                 device='throttled-source',
182*49278ec0SMax Reitz                 target='target',
183*49278ec0SMax Reitz                 sync='full')
184*49278ec0SMax Reitz    assert ret['return'] == {}
185*49278ec0SMax Reitz
186*49278ec0SMax Reitz    log(vm.qmp('quit'))
187*49278ec0SMax Reitz
188*49278ec0SMax Reitz    with iotests.Timeout(5, 'Timeout waiting for VM to quit'):
189*49278ec0SMax Reitz        vm.shutdown(has_quit=True)
190