xref: /openbmc/qemu/tests/qemu-iotests/218 (revision 7d8140595f1e131935ba1c98a55af7d066660707)
17c477526SPhilippe Mathieu-Daudé#!/usr/bin/env python3
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
3049278ec0SMax Reitzfrom iotests import log, qemu_img, qemu_io_silent
31dc885fffSMax Reitz
32*7d814059SJohn Snowiotests.script_initialize(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])
13949278ec0SMax Reitz
14049278ec0SMax Reitzlog('')
14149278ec0SMax Reitzlog('=== Cancel mirror job from throttled node by quitting ===')
14249278ec0SMax Reitzlog('')
14349278ec0SMax Reitz
14449278ec0SMax Reitzwith iotests.VM() as vm, \
14549278ec0SMax Reitz     iotests.FilePath('src.img') as src_img_path:
14649278ec0SMax Reitz
14749278ec0SMax Reitz    assert qemu_img('create', '-f', iotests.imgfmt, src_img_path, '64M') == 0
14849278ec0SMax Reitz    assert qemu_io_silent('-f', iotests.imgfmt, src_img_path,
14949278ec0SMax Reitz                          '-c', 'write -P 42 0M 64M') == 0
15049278ec0SMax Reitz
15149278ec0SMax Reitz    vm.launch()
15249278ec0SMax Reitz
15349278ec0SMax Reitz    ret = vm.qmp('object-add', qom_type='throttle-group', id='tg',
15449278ec0SMax Reitz                 props={'x-bps-read': 4096})
15549278ec0SMax Reitz    assert ret['return'] == {}
15649278ec0SMax Reitz
15749278ec0SMax Reitz    ret = vm.qmp('blockdev-add',
15849278ec0SMax Reitz                 node_name='source',
15949278ec0SMax Reitz                 driver=iotests.imgfmt,
16049278ec0SMax Reitz                 file={
16149278ec0SMax Reitz                     'driver': 'file',
16249278ec0SMax Reitz                     'filename': src_img_path
16349278ec0SMax Reitz                 })
16449278ec0SMax Reitz    assert ret['return'] == {}
16549278ec0SMax Reitz
16649278ec0SMax Reitz    ret = vm.qmp('blockdev-add',
16749278ec0SMax Reitz                 node_name='throttled-source',
16849278ec0SMax Reitz                 driver='throttle',
16949278ec0SMax Reitz                 throttle_group='tg',
17049278ec0SMax Reitz                 file='source')
17149278ec0SMax Reitz    assert ret['return'] == {}
17249278ec0SMax Reitz
17349278ec0SMax Reitz    ret = vm.qmp('blockdev-add',
17449278ec0SMax Reitz                 node_name='target',
17549278ec0SMax Reitz                 driver='null-co',
17649278ec0SMax Reitz                 size=(64 * 1048576))
17749278ec0SMax Reitz    assert ret['return'] == {}
17849278ec0SMax Reitz
17949278ec0SMax Reitz    ret = vm.qmp('blockdev-mirror',
18049278ec0SMax Reitz                 job_id='mirror',
18149278ec0SMax Reitz                 device='throttled-source',
18249278ec0SMax Reitz                 target='target',
18349278ec0SMax Reitz                 sync='full')
18449278ec0SMax Reitz    assert ret['return'] == {}
18549278ec0SMax Reitz
18649278ec0SMax Reitz    log(vm.qmp('quit'))
18749278ec0SMax Reitz
18849278ec0SMax Reitz    with iotests.Timeout(5, 'Timeout waiting for VM to quit'):
18949278ec0SMax Reitz        vm.shutdown(has_quit=True)
190