]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/env python | |
2 | # | |
3 | # Test for when a backing file is considered overridden (thus, a | |
4 | # json:{} filename is generated for the overlay) and when it is not | |
5 | # | |
6 | # Copyright (C) 2018 Red Hat, Inc. | |
7 | # | |
8 | # This program is free software; you can redistribute it and/or modify | |
9 | # it under the terms of the GNU General Public License as published by | |
10 | # the Free Software Foundation; either version 2 of the License, or | |
11 | # (at your option) any later version. | |
12 | # | |
13 | # This program is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 | # | |
21 | # Creator/Owner: Max Reitz <[email protected]> | |
22 | ||
23 | import iotests | |
24 | from iotests import log, qemu_img, filter_testfiles, filter_imgfmt, \ | |
25 | filter_qmp_testfiles, filter_qmp_imgfmt | |
26 | ||
27 | # Need backing file and change-backing-file support | |
28 | iotests.verify_image_format(supported_fmts=['qcow2', 'qed']) | |
29 | iotests.verify_platform(['linux']) | |
30 | ||
31 | ||
32 | def log_node_info(node): | |
33 | log('') | |
34 | ||
35 | log('bs->filename: ' + node['image']['filename'], | |
36 | filters=[filter_testfiles, filter_imgfmt]) | |
37 | log('bs->backing_file: ' + node['backing_file'], | |
38 | filters=[filter_testfiles, filter_imgfmt]) | |
39 | ||
40 | if 'backing-image' in node['image']: | |
41 | log('bs->backing->bs->filename: ' + | |
42 | node['image']['backing-image']['filename'], | |
43 | filters=[filter_testfiles, filter_imgfmt]) | |
44 | else: | |
45 | log('bs->backing: (none)') | |
46 | ||
47 | log('') | |
48 | ||
49 | ||
50 | with iotests.FilePath('base.img') as base_img_path, \ | |
51 | iotests.FilePath('top.img') as top_img_path, \ | |
52 | iotests.VM() as vm: | |
53 | ||
54 | assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0 | |
55 | # Choose a funny way to describe the backing filename | |
56 | assert qemu_img('create', '-f', iotests.imgfmt, '-b', | |
57 | 'file:' + base_img_path, top_img_path) == 0 | |
58 | ||
59 | vm.launch() | |
60 | ||
61 | log('--- Implicit backing file ---') | |
62 | log('') | |
63 | ||
64 | vm.qmp_log('blockdev-add', | |
65 | node_name='node0', | |
66 | driver=iotests.imgfmt, | |
67 | file={ | |
68 | 'driver': 'file', | |
69 | 'filename': top_img_path | |
70 | }, | |
71 | filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) | |
72 | ||
73 | # Filename should be plain, and the backing filename should not | |
74 | # contain the "file:" prefix | |
75 | log_node_info(vm.node_info('node0')) | |
76 | ||
77 | vm.qmp_log('blockdev-del', node_name='node0') | |
78 | ||
79 | log('') | |
80 | log('--- change-backing-file ---') | |
81 | log('') | |
82 | ||
83 | vm.qmp_log('blockdev-add', | |
84 | node_name='node0', | |
85 | driver=iotests.imgfmt, | |
86 | file={ | |
87 | 'driver': 'file', | |
88 | 'filename': top_img_path | |
89 | }, | |
90 | filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) | |
91 | ||
92 | # Changing the backing file to a qemu-reported filename should | |
93 | # result in qemu accepting the corresponding BDS as the implicit | |
94 | # backing BDS (and thus not generate a json:{} filename). | |
95 | # So, first, query the backing filename. | |
96 | ||
97 | backing_filename = \ | |
98 | vm.node_info('node0')['image']['backing-image']['filename'] | |
99 | ||
100 | # Next, change the backing file to something different | |
101 | ||
102 | vm.qmp_log('change-backing-file', | |
103 | image_node_name='node0', | |
104 | device='node0', | |
105 | backing_file='null-co://', | |
106 | filters=[filter_qmp_testfiles]) | |
107 | ||
108 | # Now, verify that we get a json:{} filename | |
109 | # (Image header says "null-co://", actual backing file still is | |
110 | # base_img_path) | |
111 | ||
112 | log_node_info(vm.node_info('node0')) | |
113 | ||
114 | # Change it back | |
115 | # (To get header and backing file in sync) | |
116 | ||
117 | vm.qmp_log('change-backing-file', | |
118 | image_node_name='node0', | |
119 | device='node0', | |
120 | backing_file=backing_filename, | |
121 | filters=[filter_qmp_testfiles]) | |
122 | ||
123 | # And verify that we get our original results | |
124 | ||
125 | log_node_info(vm.node_info('node0')) | |
126 | ||
127 | # Finally, try a "file:" prefix. While this is actually what we | |
128 | # originally had in the image header, qemu will not reopen the | |
129 | # backing file here, so it cannot verify that this filename | |
130 | # "resolves" to the actual backing BDS's filename and will thus | |
131 | # consider both to be different. | |
132 | # (This may be fixed in the future.) | |
133 | ||
134 | vm.qmp_log('change-backing-file', | |
135 | image_node_name='node0', | |
136 | device='node0', | |
137 | backing_file=('file:' + backing_filename), | |
138 | filters=[filter_qmp_testfiles]) | |
139 | ||
140 | # So now we should get a json:{} filename | |
141 | ||
142 | log_node_info(vm.node_info('node0')) | |
143 | ||
144 | # Remove and re-attach so we can see that (as in our first try), | |
145 | # opening the image anew helps qemu resolve the header backing | |
146 | # filename. | |
147 | ||
148 | vm.qmp_log('blockdev-del', node_name='node0') | |
149 | ||
150 | vm.qmp_log('blockdev-add', | |
151 | node_name='node0', | |
152 | driver=iotests.imgfmt, | |
153 | file={ | |
154 | 'driver': 'file', | |
155 | 'filename': top_img_path | |
156 | }, | |
157 | filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) | |
158 | ||
159 | log_node_info(vm.node_info('node0')) | |
160 | ||
161 | vm.qmp_log('blockdev-del', node_name='node0') | |
162 | ||
163 | log('') | |
164 | log('--- Override backing file ---') | |
165 | log('') | |
166 | ||
167 | # For this test, we need the plain filename in the image header | |
168 | # (because qemu cannot "canonicalize"/"resolve" the backing | |
169 | # filename unless the backing file is opened implicitly with the | |
170 | # overlay) | |
171 | assert qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path, | |
172 | top_img_path) == 0 | |
173 | ||
174 | # You can only reliably override backing options by using a node | |
175 | # reference (or by specifying file.filename, but, well...) | |
176 | vm.qmp_log('blockdev-add', node_name='null', driver='null-co') | |
177 | ||
178 | vm.qmp_log('blockdev-add', | |
179 | node_name='node0', | |
180 | driver=iotests.imgfmt, | |
181 | file={ | |
182 | 'driver': 'file', | |
183 | 'filename': top_img_path | |
184 | }, | |
185 | backing='null', | |
186 | filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) | |
187 | ||
188 | # Should get a json:{} filename (and bs->backing_file is | |
189 | # null-co://, because that field actually has not much to do | |
190 | # with the header backing filename (except that it is changed by | |
191 | # change-backing-file)) | |
192 | ||
193 | log_node_info(vm.node_info('node0')) | |
194 | ||
195 | # Detach the backing file by reopening the whole thing | |
196 | ||
197 | vm.qmp_log('blockdev-del', node_name='node0') | |
198 | vm.qmp_log('blockdev-del', node_name='null') | |
199 | ||
200 | vm.qmp_log('blockdev-add', | |
201 | node_name='node0', | |
202 | driver=iotests.imgfmt, | |
203 | file={ | |
204 | 'driver': 'file', | |
205 | 'filename': top_img_path | |
206 | }, | |
207 | backing=None, | |
208 | filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) | |
209 | ||
210 | # Should get a json:{} filename (because we overrode the backing | |
211 | # file to not be there) | |
212 | ||
213 | log_node_info(vm.node_info('node0')) | |
214 | ||
215 | # Open the original backing file | |
216 | ||
217 | vm.qmp_log('blockdev-add', | |
218 | node_name='original-backing', | |
219 | driver=iotests.imgfmt, | |
220 | file={ | |
221 | 'driver': 'file', | |
222 | 'filename': base_img_path | |
223 | }, | |
224 | filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) | |
225 | ||
226 | # Attach the original backing file to its overlay | |
227 | ||
228 | vm.qmp_log('blockdev-snapshot', | |
229 | node='original-backing', | |
230 | overlay='node0') | |
231 | ||
232 | # This should give us the original plain result | |
233 | ||
234 | log_node_info(vm.node_info('node0')) | |
235 | ||
236 | vm.qmp_log('blockdev-del', node_name='node0') | |
237 | vm.qmp_log('blockdev-del', node_name='original-backing') | |
238 | ||
239 | vm.shutdown() |