]>
Commit | Line | Data |
---|---|---|
8f7acbe6 KW |
1 | #!/bin/bash |
2 | # | |
3 | # Test for configuring cache modes of arbitrary nodes (requires O_DIRECT) | |
4 | # | |
5 | # Copyright (C) 2015 Red Hat, Inc. | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2 of the License, or | |
10 | # (at your option) any later version. | |
11 | # | |
12 | # This program is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | # | |
20 | ||
21 | # creator | |
22 | owner=kwolf@redhat.com | |
23 | ||
24 | seq=`basename $0` | |
25 | echo "QA output created by $seq" | |
26 | ||
27 | here=`pwd` | |
28 | tmp=/tmp/$$ | |
29 | status=1 # failure is the default! | |
30 | ||
31 | _cleanup() | |
32 | { | |
33 | _cleanup_test_img | |
34 | rm -f $TEST_IMG.snap | |
35 | } | |
36 | trap "_cleanup; exit \$status" 0 1 2 3 15 | |
37 | ||
38 | # get standard environment, filters and checks | |
39 | . ./common.rc | |
40 | . ./common.filter | |
41 | ||
42 | _supported_fmt qcow2 | |
43 | _supported_proto file | |
44 | _supported_os Linux | |
45 | ||
46 | # We test all cache modes anyway, but O_DIRECT needs to be supported | |
47 | _default_cache_mode none | |
48 | _supported_cache_modes none directsync | |
49 | ||
50 | function do_run_qemu() | |
51 | { | |
52 | echo Testing: "$@" | |
53 | ( | |
54 | if ! test -t 0; then | |
55 | while read cmd; do | |
56 | echo $cmd | |
57 | done | |
58 | fi | |
59 | echo quit | |
60 | ) | $QEMU -nographic -monitor stdio -nodefaults "$@" | |
61 | echo | |
62 | } | |
63 | ||
64 | function run_qemu() | |
65 | { | |
66 | do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | |
67 | } | |
68 | ||
69 | size=128M | |
70 | ||
71 | TEST_IMG="$TEST_IMG.base" _make_test_img $size | |
72 | TEST_IMG="$TEST_IMG.snap" _make_test_img $size | |
73 | _make_test_img -b "$TEST_IMG.base" $size | |
74 | ||
75 | echo | |
76 | echo === Simple test for all cache modes === | |
77 | echo | |
78 | ||
79 | run_qemu -drive file="$TEST_IMG",cache=none | |
80 | run_qemu -drive file="$TEST_IMG",cache=directsync | |
81 | run_qemu -drive file="$TEST_IMG",cache=writeback | |
82 | run_qemu -drive file="$TEST_IMG",cache=writethrough | |
83 | run_qemu -drive file="$TEST_IMG",cache=unsafe | |
84 | run_qemu -drive file="$TEST_IMG",cache=invalid_value | |
85 | ||
86 | echo | |
87 | echo === Check inheritance of cache modes === | |
88 | echo | |
89 | ||
90 | files="if=none,file=$TEST_IMG,backing.file.filename=$TEST_IMG.base" | |
91 | ids="node-name=image,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file" | |
92 | ||
93 | function check_cache_all() | |
94 | { | |
95 | # cache.direct is supposed to be inherited by both bs->file and | |
96 | # bs->backing | |
97 | ||
98 | echo -e "cache.direct=on on none0" | |
73ac451f | 99 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" |
8f7acbe6 | 100 | echo -e "\ncache.direct=on on file" |
73ac451f | 101 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" |
8f7acbe6 | 102 | echo -e "\ncache.direct=on on backing" |
73ac451f | 103 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" |
8f7acbe6 | 104 | echo -e "\ncache.direct=on on backing-file" |
73ac451f | 105 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" |
8f7acbe6 KW |
106 | |
107 | # cache.writeback is supposed to be inherited by bs->backing; bs->file | |
108 | # always gets cache.writeback=on | |
109 | ||
110 | echo -e "\n\ncache.writeback=off on none0" | |
73ac451f | 111 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 112 | echo -e "\ncache.writeback=off on file" |
73ac451f | 113 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 114 | echo -e "\ncache.writeback=off on backing" |
73ac451f | 115 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 116 | echo -e "\ncache.writeback=off on backing-file" |
73ac451f | 117 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 KW |
118 | |
119 | # cache.no-flush is supposed to be inherited by both bs->file and bs->backing | |
120 | ||
121 | echo -e "\n\ncache.no-flush=on on none0" | |
73ac451f | 122 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 123 | echo -e "\ncache.no-flush=on on file" |
73ac451f | 124 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 125 | echo -e "\ncache.no-flush=on on backing" |
73ac451f | 126 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 127 | echo -e "\ncache.no-flush=on on backing-file" |
73ac451f | 128 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 KW |
129 | } |
130 | ||
131 | echo | |
132 | echo "--- Configure cache modes on the command line ---" | |
133 | echo | |
134 | ||
135 | # First check the inherited cache mode after opening the image. | |
136 | ||
137 | hmp_cmds="info block image | |
138 | info block file | |
139 | info block backing | |
140 | info block backing-file" | |
141 | ||
142 | check_cache_all | |
143 | ||
144 | echo | |
145 | echo "--- Cache modes after reopen (live snapshot) ---" | |
146 | echo | |
147 | ||
148 | # Then trigger a reopen and check that the cache modes are still the same. | |
149 | ||
150 | hmp_cmds="snapshot_blkdev -n none0 $TEST_IMG.snap $IMGFMT | |
151 | info block | |
152 | info block image | |
153 | info block file | |
154 | info block backing | |
155 | info block backing-file" | |
156 | ||
157 | check_cache_all | |
158 | ||
159 | echo | |
160 | echo "--- Change cache modes with reopen (qemu-io command, flags) ---" | |
161 | echo | |
162 | ||
163 | # This one actually changes the cache mode with the reopen. For this test, the | |
164 | # new cache mode is specified in the flags, not as an option. | |
165 | ||
166 | hmp_cmds='qemu-io none0 "reopen -c none" | |
167 | info block image | |
168 | info block file | |
169 | info block backing | |
170 | info block backing-file' | |
171 | ||
172 | check_cache_all | |
173 | ||
174 | echo | |
175 | echo "--- Change cache modes with reopen (qemu-io command, options) ---" | |
176 | echo | |
177 | ||
178 | # This one actually changes the cache mode with the reopen. For this test, the | |
179 | # new cache mode is specified as an option, not in the flags. | |
180 | ||
181 | hmp_cmds='qemu-io none0 "reopen -o cache.direct=on" | |
182 | info block image | |
183 | info block file | |
184 | info block backing | |
185 | info block backing-file' | |
186 | ||
187 | check_cache_all | |
188 | ||
189 | echo | |
190 | echo "--- Change cache modes after snapshot ---" | |
191 | echo | |
192 | ||
193 | # This checks that the original image doesn't inherit from the snapshot | |
194 | ||
195 | hmp_cmds="snapshot_blkdev -n none0 $TEST_IMG.snap $IMGFMT | |
196 | qemu-io none0 \"reopen -c none\" | |
197 | info block none0 | |
198 | info block image | |
199 | info block file | |
200 | info block backing | |
201 | info block backing-file" | |
202 | ||
203 | check_cache_all | |
204 | ||
205 | echo | |
206 | echo "--- Change cache mode in parent, child has explicit option in JSON ---" | |
207 | echo | |
208 | ||
209 | # This checks that children with options explicitly set by the json: | |
210 | # pseudo-protocol don't inherit these options from their parents. | |
211 | # | |
212 | # Yes, blkdebug::json:... is criminal, but I can't see another way to have a | |
213 | # BDS initialised with the json: pseudo-protocol, but still have it inherit | |
214 | # options from its parent node. | |
215 | ||
216 | hmp_cmds="qemu-io none0 \"reopen -o cache.writeback=off,cache.direct=on,cache.no-flush=on\" | |
217 | info block image | |
218 | info block blkdebug | |
219 | info block file" | |
220 | ||
73ac451f | 221 | echo "$hmp_cmds" | run_qemu -drive if=none,file="blkdebug::json:{\"filename\":\"$TEST_IMG\",,\"cache\":{\"direct\":false}}",node-name=image,file.node-name=blkdebug,file.image.node-name=file | grep "Cache" |
8f7acbe6 KW |
222 | |
223 | echo | |
224 | echo "=== Check that referenced BDSes don't inherit ===" | |
225 | echo | |
226 | ||
227 | drv_bkfile="if=none,driver=file,filename=$TEST_IMG.base,node-name=backing-file" | |
228 | drv_bk="if=none,file=json:{'driver':'$IMGFMT',,'file':'backing-file',,'node-name':'backing'}" | |
229 | drv_file="if=none,driver=file,filename=$TEST_IMG,node-name=file" | |
230 | drv_img="if=none,id=blk,file=json:{'driver':'$IMGFMT',,'file':'file',,'backing':'backing',,'node-name':'image'}" | |
231 | ||
232 | function check_cache_all_separate() | |
233 | { | |
234 | # Check cache.direct | |
235 | ||
236 | echo -e "cache.direct=on on blk" | |
73ac451f | 237 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img",cache.direct=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 238 | echo -e "\ncache.direct=on on file" |
73ac451f | 239 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file",cache.direct=on -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 240 | echo -e "\ncache.direct=on on backing" |
73ac451f | 241 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk",cache.direct=on -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 242 | echo -e "\ncache.direct=on on backing-file" |
73ac451f | 243 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile",cache.direct=on -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 KW |
244 | |
245 | # Check cache.writeback | |
246 | ||
247 | echo -e "\n\ncache.writeback=off on blk" | |
73ac451f | 248 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img",cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 249 | echo -e "\ncache.writeback=off on file" |
73ac451f | 250 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file",cache.writeback=off -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 251 | echo -e "\ncache.writeback=off on backing" |
73ac451f | 252 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk",cache.writeback=off -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 253 | echo -e "\ncache.writeback=off on backing-file" |
73ac451f | 254 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile",cache.writeback=off -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 KW |
255 | |
256 | # Check cache.no-flush | |
257 | ||
258 | echo -e "\n\ncache.no-flush=on on blk" | |
73ac451f | 259 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img",cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 260 | echo -e "\ncache.no-flush=on on file" |
73ac451f | 261 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file",cache.no-flush=on -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 262 | echo -e "\ncache.no-flush=on on backing" |
73ac451f | 263 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk",cache.no-flush=on -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 | 264 | echo -e "\ncache.no-flush=on on backing-file" |
73ac451f | 265 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile",cache.no-flush=on -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" |
8f7acbe6 KW |
266 | } |
267 | ||
268 | echo | |
269 | echo "--- Configure cache modes on the command line ---" | |
270 | echo | |
271 | ||
272 | # First check the inherited cache mode after opening the image. | |
273 | ||
274 | hmp_cmds="info block image | |
275 | info block file | |
276 | info block backing | |
277 | info block backing-file" | |
278 | ||
279 | check_cache_all_separate | |
280 | ||
281 | echo | |
282 | echo "--- Cache modes after reopen (live snapshot) ---" | |
283 | echo | |
284 | ||
285 | # Then trigger a reopen and check that the cache modes are still the same. | |
286 | ||
287 | hmp_cmds="snapshot_blkdev -n blk $TEST_IMG.snap $IMGFMT | |
288 | info block blk | |
289 | info block image | |
290 | info block file | |
291 | info block backing | |
292 | info block backing-file" | |
293 | ||
294 | check_cache_all_separate | |
295 | ||
296 | echo | |
297 | echo "--- Change cache modes with reopen (qemu-io command, flags) ---" | |
298 | echo | |
299 | ||
300 | # This one actually changes the cache mode with the reopen. For this test, the | |
301 | # new cache mode is specified as flags, not as option. | |
302 | ||
303 | hmp_cmds='qemu-io blk "reopen -c none" | |
304 | info block image | |
305 | info block file | |
306 | info block backing | |
307 | info block backing-file' | |
308 | ||
309 | check_cache_all_separate | |
310 | ||
311 | ||
312 | echo | |
313 | echo "=== Reopening children instead of the root ===" | |
314 | echo | |
315 | ||
316 | files="if=none,file=$TEST_IMG,backing.file.filename=$TEST_IMG.base" | |
317 | ids="node-name=image,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file" | |
318 | ||
319 | echo | |
320 | echo "--- Basic reopen ---" | |
321 | echo | |
322 | ||
323 | hmp_cmds='qemu-io none0 "reopen -o backing.cache.direct=on" | |
324 | info block image | |
325 | info block file | |
326 | info block backing | |
327 | info block backing-file' | |
328 | ||
329 | check_cache_all | |
330 | ||
331 | echo | |
332 | echo "--- Change cache mode after reopening child ---" | |
333 | echo | |
334 | ||
335 | # This checks that children with options explicitly set with reopen don't | |
336 | # inherit these options from their parents any more | |
337 | ||
338 | # TODO Implement node-name support for 'qemu-io' HMP command for -c | |
339 | # Can use only -o to access child node options for now | |
340 | ||
341 | hmp_cmds="qemu-io none0 \"reopen -o file.cache.writeback=off,file.cache.direct=off,file.cache.no-flush=off\" | |
342 | qemu-io none0 \"reopen -o backing.file.cache.writeback=on,backing.file.cache.direct=off,backing.file.cache.no-flush=on\" | |
343 | qemu-io none0 \"reopen -c none\" | |
344 | info block image | |
345 | info block file | |
346 | info block backing | |
347 | info block backing-file" | |
348 | ||
349 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids" | grep "Cache" | |
350 | ||
351 | # success, all done | |
352 | echo "*** done" | |
353 | rm -f $seq.full | |
354 | status=0 |