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