]>
Commit | Line | Data |
---|---|---|
bf03dede KW |
1 | #!/usr/bin/env python3 |
2 | # | |
3 | # Copyright (C) 2019 Red Hat, Inc. | |
4 | # | |
5 | # This program is free software; you can redistribute it and/or modify | |
6 | # it under the terms of the GNU General Public License as published by | |
7 | # the Free Software Foundation; either version 2 of the License, or | |
8 | # (at your option) any later version. | |
9 | # | |
10 | # This program is distributed in the hope that it will be useful, | |
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | # GNU General Public License for more details. | |
14 | # | |
15 | # You should have received a copy of the GNU General Public License | |
16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | # | |
18 | # Creator/Owner: Kevin Wolf <[email protected]> | |
19 | # | |
20 | # Some tests for short backing files and short overlays | |
21 | ||
22 | import iotests | |
23 | ||
24 | iotests.verify_image_format(supported_fmts=['qcow2']) | |
25 | iotests.verify_platform(['linux']) | |
26 | ||
27 | size_short = 1 * 1024 * 1024 | |
28 | size_long = 2 * 1024 * 1024 | |
29 | size_diff = size_long - size_short | |
30 | ||
31 | def create_chain() -> None: | |
32 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, | |
33 | str(size_long)) | |
34 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid, | |
35 | str(size_short)) | |
36 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top, | |
37 | str(size_long)) | |
38 | ||
39 | iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base) | |
40 | ||
41 | def create_vm() -> iotests.VM: | |
42 | vm = iotests.VM() | |
43 | vm.add_blockdev('file,filename=%s,node-name=base-file' % base) | |
44 | vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt) | |
45 | vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid) | |
46 | vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base' | |
47 | % iotests.imgfmt) | |
48 | vm.add_drive(top, 'backing=mid,node-name=top') | |
49 | return vm | |
50 | ||
51 | with iotests.FilePath('base') as base, \ | |
52 | iotests.FilePath('mid') as mid, \ | |
53 | iotests.FilePath('top') as top: | |
54 | ||
55 | iotests.log('== Commit tests ==') | |
56 | ||
57 | create_chain() | |
58 | ||
59 | iotests.log('=== Check visible data ===') | |
60 | ||
61 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top) | |
62 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top) | |
63 | ||
64 | iotests.log('=== Checking allocation status ===') | |
65 | ||
66 | iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, | |
67 | '-c', 'alloc %d %d' % (size_short, size_diff), | |
68 | base) | |
69 | ||
70 | iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, | |
71 | '-c', 'alloc %d %d' % (size_short, size_diff), | |
72 | mid) | |
73 | ||
74 | iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, | |
75 | '-c', 'alloc %d %d' % (size_short, size_diff), | |
76 | top) | |
77 | ||
78 | iotests.log('=== Checking map ===') | |
79 | ||
80 | iotests.qemu_img_log('map', '--output=json', base) | |
81 | iotests.qemu_img_log('map', '--output=human', base) | |
82 | iotests.qemu_img_log('map', '--output=json', mid) | |
83 | iotests.qemu_img_log('map', '--output=human', mid) | |
84 | iotests.qemu_img_log('map', '--output=json', top) | |
85 | iotests.qemu_img_log('map', '--output=human', top) | |
86 | ||
87 | iotests.log('=== Testing qemu-img commit (top -> mid) ===') | |
88 | ||
89 | iotests.qemu_img_log('commit', top) | |
90 | iotests.img_info_log(mid) | |
91 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) | |
92 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) | |
93 | ||
94 | iotests.log('=== Testing HMP commit (top -> mid) ===') | |
95 | ||
96 | create_chain() | |
97 | with create_vm() as vm: | |
98 | vm.launch() | |
99 | vm.qmp_log('human-monitor-command', command_line='commit drive0') | |
100 | ||
101 | iotests.img_info_log(mid) | |
102 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) | |
103 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) | |
104 | ||
105 | iotests.log('=== Testing QMP active commit (top -> mid) ===') | |
106 | ||
107 | create_chain() | |
108 | with create_vm() as vm: | |
109 | vm.launch() | |
110 | vm.qmp_log('block-commit', device='top', base_node='mid', | |
111 | job_id='job0', auto_dismiss=False) | |
112 | vm.run_job('job0', wait=5) | |
113 | ||
114 | iotests.img_info_log(mid) | |
115 | iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) | |
116 | iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) | |
117 | ||
118 | ||
119 | iotests.log('== Resize tests ==') | |
120 | ||
121 | # Use different sizes for different allocation modes: | |
122 | # | |
123 | # We want to have at least one test where 32 bit truncation in the size of | |
124 | # the overlapping area becomes visible. This is covered by the | |
125 | # prealloc='off' case (1G to 6G is an overlap of 5G). | |
126 | # | |
127 | # However, we can only do this for modes that don't preallocate data | |
128 | # because otherwise we might run out of space on the test host. | |
129 | # | |
130 | # We also want to test some unaligned combinations. | |
131 | for (prealloc, base_size, top_size_old, top_size_new, off) in [ | |
132 | ('off', '6G', '1G', '8G', '5G'), | |
133 | ('metadata', '32G', '30G', '33G', '31G'), | |
134 | ('falloc', '10M', '5M', '15M', '9M'), | |
135 | ('full', '16M', '8M', '12M', '11M'), | |
136 | ('off', '384k', '253k', '512k', '253k'), | |
137 | ('off', '400k', '256k', '512k', '336k'), | |
138 | ('off', '512k', '256k', '500k', '436k')]: | |
139 | ||
140 | iotests.log('=== preallocation=%s ===' % prealloc) | |
141 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size) | |
142 | iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top, | |
143 | top_size_old) | |
144 | iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base) | |
145 | ||
146 | # After this, top_size_old to base_size should be allocated/zeroed. | |
147 | # | |
148 | # In theory, leaving base_size to top_size_new unallocated would be | |
149 | # correct, but in practice, if we zero out anything, we zero out | |
150 | # everything up to top_size_new. | |
151 | iotests.qemu_img_log('resize', '-f', iotests.imgfmt, | |
152 | '--preallocation', prealloc, top, top_size_new) | |
153 | iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top) | |
154 | iotests.qemu_io_log('-c', 'map', top) | |
155 | iotests.qemu_img_log('map', '--output=json', top) |