]> git.proxmox.com Git - mirror_qemu.git/blame - tests/qemu-iotests/tests/copy-before-write
python/machine: remove unused sock_dir argument
[mirror_qemu.git] / tests / qemu-iotests / tests / copy-before-write
CommitLineData
dd3e97df
VSO
1#!/usr/bin/env python3
2# group: auto backup
3#
4# Copyright (c) 2022 Virtuozzo International GmbH
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19
20import os
21import re
22
23from qemu.machine import QEMUMachine
24
25import iotests
26from iotests import qemu_img_create, qemu_io
27
28
29temp_img = os.path.join(iotests.test_dir, 'temp')
30source_img = os.path.join(iotests.test_dir, 'source')
31size = '1M'
32
33
34class TestCbwError(iotests.QMPTestCase):
35 def tearDown(self):
36 self.vm.shutdown()
37 os.remove(temp_img)
38 os.remove(source_img)
39
40 def setUp(self):
41 qemu_img_create('-f', iotests.imgfmt, source_img, size)
42 qemu_img_create('-f', iotests.imgfmt, temp_img, size)
43 qemu_io('-c', 'write 0 1M', source_img)
44
45 opts = ['-nodefaults', '-display', 'none', '-machine', 'none']
46 self.vm = QEMUMachine(iotests.qemu_prog, opts,
46d4747a 47 base_temp_dir=iotests.test_dir)
dd3e97df
VSO
48 self.vm.launch()
49
50 def do_cbw_error(self, on_cbw_error):
51 result = self.vm.qmp('blockdev-add', {
52 'node-name': 'cbw',
53 'driver': 'copy-before-write',
54 'on-cbw-error': on_cbw_error,
55 'file': {
56 'driver': iotests.imgfmt,
57 'file': {
58 'driver': 'file',
59 'filename': source_img,
60 }
61 },
62 'target': {
63 'driver': iotests.imgfmt,
64 'file': {
65 'driver': 'blkdebug',
66 'image': {
67 'driver': 'file',
68 'filename': temp_img
69 },
70 'inject-error': [
71 {
72 'event': 'write_aio',
73 'errno': 5,
74 'immediately': False,
75 'once': True
76 }
77 ]
78 }
79 }
80 })
81 self.assert_qmp(result, 'return', {})
82
83 result = self.vm.qmp('blockdev-add', {
84 'node-name': 'access',
85 'driver': 'snapshot-access',
86 'file': 'cbw'
87 })
88 self.assert_qmp(result, 'return', {})
89
90 result = self.vm.qmp('human-monitor-command',
91 command_line='qemu-io cbw "write 0 1M"')
92 self.assert_qmp(result, 'return', '')
93
94 result = self.vm.qmp('human-monitor-command',
95 command_line='qemu-io access "read 0 1M"')
96 self.assert_qmp(result, 'return', '')
97
98 self.vm.shutdown()
99 log = self.vm.get_log()
100 log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
101 log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
102 log = iotests.filter_qemu_io(log)
103 return log
104
105 def test_break_snapshot_on_cbw_error(self):
106 """break-snapshot behavior:
107 Guest write succeed, but further snapshot-read fails, as snapshot is
108 broken.
109 """
110 log = self.do_cbw_error('break-snapshot')
111
112 self.assertEqual(log, """\
113wrote 1048576/1048576 bytes at offset 0
1141 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
115read failed: Permission denied
116""")
117
118 def test_break_guest_write_on_cbw_error(self):
119 """break-guest-write behavior:
120 Guest write fails, but snapshot-access continues working and further
121 snapshot-read succeeds.
122 """
123 log = self.do_cbw_error('break-guest-write')
124
125 self.assertEqual(log, """\
126write failed: Input/output error
127read 1048576/1048576 bytes at offset 0
1281 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
129""")
130
9d05a87b
VSO
131 def do_cbw_timeout(self, on_cbw_error):
132 result = self.vm.qmp('object-add', {
133 'qom-type': 'throttle-group',
134 'id': 'group0',
135 'limits': {'bps-write': 300 * 1024}
136 })
137 self.assert_qmp(result, 'return', {})
138
139 result = self.vm.qmp('blockdev-add', {
140 'node-name': 'cbw',
141 'driver': 'copy-before-write',
142 'on-cbw-error': on_cbw_error,
143 'cbw-timeout': 1,
144 'file': {
145 'driver': iotests.imgfmt,
146 'file': {
147 'driver': 'file',
148 'filename': source_img,
149 }
150 },
151 'target': {
152 'driver': 'throttle',
153 'throttle-group': 'group0',
154 'file': {
155 'driver': 'qcow2',
156 'file': {
157 'driver': 'file',
158 'filename': temp_img
159 }
160 }
161 }
162 })
163 self.assert_qmp(result, 'return', {})
164
165 result = self.vm.qmp('blockdev-add', {
166 'node-name': 'access',
167 'driver': 'snapshot-access',
168 'file': 'cbw'
169 })
170 self.assert_qmp(result, 'return', {})
171
172 result = self.vm.qmp('human-monitor-command',
173 command_line='qemu-io cbw "write 0 512K"')
174 self.assert_qmp(result, 'return', '')
175
176 # We need second write to trigger throttling
177 result = self.vm.qmp('human-monitor-command',
178 command_line='qemu-io cbw "write 512K 512K"')
179 self.assert_qmp(result, 'return', '')
180
181 result = self.vm.qmp('human-monitor-command',
182 command_line='qemu-io access "read 0 1M"')
183 self.assert_qmp(result, 'return', '')
184
185 self.vm.shutdown()
186 log = self.vm.get_log()
187 log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
188 log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
189 log = iotests.filter_qemu_io(log)
190 return log
191
192 def test_timeout_break_guest(self):
193 log = self.do_cbw_timeout('break-guest-write')
05b47eec
VSO
194 # macOS and FreeBSD tend to represent ETIMEDOUT as
195 # "Operation timed out", when Linux prefer
196 # "Connection timed out"
197 log = log.replace('Operation timed out',
198 'Connection timed out')
9d05a87b
VSO
199 self.assertEqual(log, """\
200wrote 524288/524288 bytes at offset 0
201512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
202write failed: Connection timed out
203read 1048576/1048576 bytes at offset 0
2041 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
205""")
206
207 def test_timeout_break_snapshot(self):
208 log = self.do_cbw_timeout('break-snapshot')
209 self.assertEqual(log, """\
210wrote 524288/524288 bytes at offset 0
211512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
212wrote 524288/524288 bytes at offset 524288
213512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
214read failed: Permission denied
215""")
216
dd3e97df
VSO
217
218if __name__ == '__main__':
219 iotests.main(supported_fmts=['qcow2'],
9548cbef
VSO
220 supported_protocols=['file'],
221 required_fmts=['copy-before-write'])