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