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