]>
Commit | Line | Data |
---|---|---|
bf03dede | 1 | #!/usr/bin/env python3 |
9dd003a9 | 2 | # group: rw backing |
bf03dede KW |
3 | # |
4 | # Copyright (C) 2019 Red Hat, Inc. | |
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 | # Creator/Owner: Kevin Wolf <kwolf@redhat.com> | |
20 | # | |
21 | # Some tests for short backing files and short overlays | |
22 | ||
23 | import iotests | |
24 | ||
7d814059 | 25 | iotests.script_initialize(supported_fmts=['qcow2'], |
b30b8077 VSO |
26 | supported_platforms=['linux'], |
27 | unsupported_imgopts=['refcount_bits', 'compat']) | |
bf03dede KW |
28 | |
29 | size_short = 1 * 1024 * 1024 | |
30 | size_long = 2 * 1024 * 1024 | |
31 | size_diff = size_long - size_short | |
32 | ||
33 | def create_chain() -> None: | |
34 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, | |
35 | str(size_long)) | |
b66ff2c2 EB |
36 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, |
37 | '-F', iotests.imgfmt, mid, str(size_short)) | |
38 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, | |
39 | '-F', iotests.imgfmt, top, str(size_long)) | |
bf03dede KW |
40 | |
41 | iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base) | |
42 | ||
43 | def create_vm() -> iotests.VM: | |
44 | vm = iotests.VM() | |
45 | vm.add_blockdev('file,filename=%s,node-name=base-file' % base) | |
46 | vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt) | |
47 | vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid) | |
48 | vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base' | |
49 | % iotests.imgfmt) | |
50 | vm.add_drive(top, 'backing=mid,node-name=top') | |
51 | return vm | |
52 | ||
53 | with iotests.FilePath('base') as base, \ | |
54 | iotests.FilePath('mid') as mid, \ | |
55 | iotests.FilePath('top') as top: | |
56 | ||
57 | iotests.log('== Commit tests ==') | |
58 | ||
59 | create_chain() | |
60 | ||
61 | iotests.log('=== Check visible data ===') | |
62 | ||
63 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top) | |
64 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top) | |
65 | ||
66 | iotests.log('=== Checking allocation status ===') | |
67 | ||
68 | iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, | |
69 | '-c', 'alloc %d %d' % (size_short, size_diff), | |
70 | base) | |
71 | ||
72 | iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, | |
73 | '-c', 'alloc %d %d' % (size_short, size_diff), | |
74 | mid) | |
75 | ||
76 | iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, | |
77 | '-c', 'alloc %d %d' % (size_short, size_diff), | |
78 | top) | |
79 | ||
80 | iotests.log('=== Checking map ===') | |
81 | ||
82 | iotests.qemu_img_log('map', '--output=json', base) | |
83 | iotests.qemu_img_log('map', '--output=human', base) | |
84 | iotests.qemu_img_log('map', '--output=json', mid) | |
85 | iotests.qemu_img_log('map', '--output=human', mid) | |
86 | iotests.qemu_img_log('map', '--output=json', top) | |
87 | iotests.qemu_img_log('map', '--output=human', top) | |
88 | ||
89 | iotests.log('=== Testing qemu-img commit (top -> mid) ===') | |
90 | ||
91 | iotests.qemu_img_log('commit', top) | |
92 | iotests.img_info_log(mid) | |
93 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) | |
94 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) | |
95 | ||
96 | iotests.log('=== Testing HMP commit (top -> mid) ===') | |
97 | ||
98 | create_chain() | |
99 | with create_vm() as vm: | |
100 | vm.launch() | |
101 | vm.qmp_log('human-monitor-command', command_line='commit drive0') | |
102 | ||
103 | iotests.img_info_log(mid) | |
104 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) | |
105 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) | |
106 | ||
107 | iotests.log('=== Testing QMP active commit (top -> mid) ===') | |
108 | ||
109 | create_chain() | |
110 | with create_vm() as vm: | |
111 | vm.launch() | |
112 | vm.qmp_log('block-commit', device='top', base_node='mid', | |
113 | job_id='job0', auto_dismiss=False) | |
114 | vm.run_job('job0', wait=5) | |
115 | ||
116 | iotests.img_info_log(mid) | |
117 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) | |
118 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) | |
119 | ||
4f193168 VSO |
120 | iotests.log('=== Testing qemu-img commit (top -> base) ===') |
121 | ||
122 | create_chain() | |
123 | iotests.qemu_img_log('commit', '-b', base, top) | |
124 | iotests.img_info_log(base) | |
125 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, base) | |
126 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), base) | |
127 | ||
128 | iotests.log('=== Testing QMP active commit (top -> base) ===') | |
129 | ||
130 | create_chain() | |
131 | with create_vm() as vm: | |
132 | vm.launch() | |
133 | vm.qmp_log('block-commit', device='top', base_node='base', | |
134 | job_id='job0', auto_dismiss=False) | |
135 | vm.run_job('job0', wait=5) | |
136 | ||
137 | iotests.img_info_log(mid) | |
138 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, base) | |
139 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), base) | |
bf03dede KW |
140 | |
141 | iotests.log('== Resize tests ==') | |
142 | ||
143 | # Use different sizes for different allocation modes: | |
144 | # | |
145 | # We want to have at least one test where 32 bit truncation in the size of | |
146 | # the overlapping area becomes visible. This is covered by the | |
147 | # prealloc='off' case (1G to 6G is an overlap of 5G). | |
148 | # | |
149 | # However, we can only do this for modes that don't preallocate data | |
150 | # because otherwise we might run out of space on the test host. | |
151 | # | |
152 | # We also want to test some unaligned combinations. | |
153 | for (prealloc, base_size, top_size_old, top_size_new, off) in [ | |
154 | ('off', '6G', '1G', '8G', '5G'), | |
155 | ('metadata', '32G', '30G', '33G', '31G'), | |
156 | ('falloc', '10M', '5M', '15M', '9M'), | |
157 | ('full', '16M', '8M', '12M', '11M'), | |
158 | ('off', '384k', '253k', '512k', '253k'), | |
159 | ('off', '400k', '256k', '512k', '336k'), | |
160 | ('off', '512k', '256k', '500k', '436k')]: | |
161 | ||
162 | iotests.log('=== preallocation=%s ===' % prealloc) | |
163 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size) | |
b66ff2c2 EB |
164 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, |
165 | '-F', iotests.imgfmt, top, top_size_old) | |
bf03dede KW |
166 | iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base) |
167 | ||
168 | # After this, top_size_old to base_size should be allocated/zeroed. | |
169 | # | |
170 | # In theory, leaving base_size to top_size_new unallocated would be | |
171 | # correct, but in practice, if we zero out anything, we zero out | |
172 | # everything up to top_size_new. | |
173 | iotests.qemu_img_log('resize', '-f', iotests.imgfmt, | |
174 | '--preallocation', prealloc, top, top_size_new) | |
175 | iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top) | |
176 | iotests.qemu_io_log('-c', 'map', top) | |
177 | iotests.qemu_img_log('map', '--output=json', top) |