1#!/usr/bin/env 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 48do_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 62run_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 91check_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 234check_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