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