]>
Commit | Line | Data |
---|---|---|
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 | ||
20 | import os | |
21 | import re | |
22 | ||
23 | from qemu.machine import QEMUMachine | |
24 | ||
25 | import iotests | |
26 | from iotests import qemu_img_create, qemu_io | |
27 | ||
28 | ||
29 | temp_img = os.path.join(iotests.test_dir, 'temp') | |
30 | source_img = os.path.join(iotests.test_dir, 'source') | |
31 | size = '1M' | |
32 | ||
33 | ||
34 | class 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, | |
47 | base_temp_dir=iotests.test_dir, | |
48 | sock_dir=iotests.sock_dir) | |
49 | self.vm.launch() | |
50 | ||
51 | def do_cbw_error(self, on_cbw_error): | |
52 | result = self.vm.qmp('blockdev-add', { | |
53 | 'node-name': 'cbw', | |
54 | 'driver': 'copy-before-write', | |
55 | 'on-cbw-error': on_cbw_error, | |
56 | 'file': { | |
57 | 'driver': iotests.imgfmt, | |
58 | 'file': { | |
59 | 'driver': 'file', | |
60 | 'filename': source_img, | |
61 | } | |
62 | }, | |
63 | 'target': { | |
64 | 'driver': iotests.imgfmt, | |
65 | 'file': { | |
66 | 'driver': 'blkdebug', | |
67 | 'image': { | |
68 | 'driver': 'file', | |
69 | 'filename': temp_img | |
70 | }, | |
71 | 'inject-error': [ | |
72 | { | |
73 | 'event': 'write_aio', | |
74 | 'errno': 5, | |
75 | 'immediately': False, | |
76 | 'once': True | |
77 | } | |
78 | ] | |
79 | } | |
80 | } | |
81 | }) | |
82 | self.assert_qmp(result, 'return', {}) | |
83 | ||
84 | result = self.vm.qmp('blockdev-add', { | |
85 | 'node-name': 'access', | |
86 | 'driver': 'snapshot-access', | |
87 | 'file': 'cbw' | |
88 | }) | |
89 | self.assert_qmp(result, 'return', {}) | |
90 | ||
91 | result = self.vm.qmp('human-monitor-command', | |
92 | command_line='qemu-io cbw "write 0 1M"') | |
93 | self.assert_qmp(result, 'return', '') | |
94 | ||
95 | result = self.vm.qmp('human-monitor-command', | |
96 | command_line='qemu-io access "read 0 1M"') | |
97 | self.assert_qmp(result, 'return', '') | |
98 | ||
99 | self.vm.shutdown() | |
100 | log = self.vm.get_log() | |
101 | log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) | |
102 | log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) | |
103 | log = iotests.filter_qemu_io(log) | |
104 | return log | |
105 | ||
106 | def test_break_snapshot_on_cbw_error(self): | |
107 | """break-snapshot behavior: | |
108 | Guest write succeed, but further snapshot-read fails, as snapshot is | |
109 | broken. | |
110 | """ | |
111 | log = self.do_cbw_error('break-snapshot') | |
112 | ||
113 | self.assertEqual(log, """\ | |
114 | wrote 1048576/1048576 bytes at offset 0 | |
115 | 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | |
116 | read failed: Permission denied | |
117 | """) | |
118 | ||
119 | def test_break_guest_write_on_cbw_error(self): | |
120 | """break-guest-write behavior: | |
121 | Guest write fails, but snapshot-access continues working and further | |
122 | snapshot-read succeeds. | |
123 | """ | |
124 | log = self.do_cbw_error('break-guest-write') | |
125 | ||
126 | self.assertEqual(log, """\ | |
127 | write failed: Input/output error | |
128 | read 1048576/1048576 bytes at offset 0 | |
129 | 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | |
130 | """) | |
131 | ||
132 | ||
133 | if __name__ == '__main__': | |
134 | iotests.main(supported_fmts=['qcow2'], | |
135 | supported_protocols=['file']) |