1#!/usr/bin/env bash 2# 3# Copyright Red Hat 4# Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <http://www.gnu.org/licenses/>. 18# 19 20export LANG=C 21 22PATH=".:$PATH" 23 24HOSTOS=$(uname -s) 25arch=$(uname -m) 26[[ "$arch" =~ "ppc64" ]] && qemu_arch=ppc64 || qemu_arch="$arch" 27 28# make sure we have a standard umask 29umask 022 30 31# bail out, setting up .notrun file 32_notrun() 33{ 34 echo "$*" >"$TEST_DIR/$seq.notrun" 35 echo "$seq not run: $*" 36 status=0 37 exit 38} 39 40if ! command -v gsed >/dev/null 2>&1; then 41 if sed --version 2>&1 | grep -v 'not GNU sed' | grep 'GNU sed' > /dev/null; 42 then 43 gsed() 44 { 45 sed "$@" 46 } 47 else 48 gsed() 49 { 50 _notrun "GNU sed not available" 51 } 52 fi 53fi 54 55dd() 56{ 57 if [ "$HOSTOS" == "Linux" ] 58 then 59 command dd --help | grep noxfer > /dev/null 2>&1 60 61 if [ "$?" -eq 0 ] 62 then 63 command dd status=noxfer $@ 64 else 65 command dd $@ 66 fi 67 else 68 command dd $@ 69 fi 70} 71 72# poke_file 'test.img' 512 '\xff\xfe' 73poke_file() 74{ 75 printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null 76} 77 78# poke_file_le $img_filename $offset $byte_width $value 79# Example: poke_file_le "$TEST_IMG" 512 2 65534 80poke_file_le() 81{ 82 local img=$1 ofs=$2 len=$3 val=$4 str='' 83 84 while ((len--)); do 85 str+=$(printf '\\x%02x' $((val & 0xff))) 86 val=$((val >> 8)) 87 done 88 89 poke_file "$img" "$ofs" "$str" 90} 91 92# poke_file_be $img_filename $offset $byte_width $value 93# Example: poke_file_be "$TEST_IMG" 512 2 65279 94poke_file_be() 95{ 96 local img=$1 ofs=$2 len=$3 val=$4 97 local str=$(printf "%0$((len * 2))x\n" $val | sed 's/\(..\)/\\x\1/g') 98 99 poke_file "$img" "$ofs" "$str" 100} 101 102# peek_file_le 'test.img' 512 2 => 65534 103peek_file_le() 104{ 105 local val=0 shift=0 byte 106 107 # coreutils' od --endian is not portable, so manually assemble bytes. 108 for byte in $(od -j"$2" -N"$3" -An -v -tu1 "$1"); do 109 val=$(( val | (byte << shift) )) 110 shift=$((shift + 8)) 111 done 112 printf %llu $val 113} 114 115# peek_file_be 'test.img' 512 2 => 65279 116peek_file_be() 117{ 118 local val=0 byte 119 120 # coreutils' od --endian is not portable, so manually assemble bytes. 121 for byte in $(od -j"$2" -N"$3" -An -v -tu1 "$1"); do 122 val=$(( (val << 8) | byte )) 123 done 124 printf %llu $val 125} 126 127# peek_file_raw 'test.img' 512 2 => '\xff\xfe'. Do not use if the raw data 128# is likely to contain \0 or trailing \n. 129peek_file_raw() 130{ 131 dd if="$1" bs=1 skip="$2" count="$3" status=none 132} 133 134_optstr_add() 135{ 136 if [ -n "$1" ]; then 137 echo "$1,$2" 138 else 139 echo "$2" 140 fi 141} 142 143# report real disk usage for sparse files 144disk_usage() 145{ 146 du --block-size=1 "$1" | awk '{print $1}' 147} 148 149# Set the variables to the empty string to turn Valgrind off 150# for specific processes, e.g. 151# $ VALGRIND_QEMU_IO= ./check -qcow2 -valgrind 015 152 153: ${VALGRIND_QEMU_VM=$VALGRIND_QEMU} 154: ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU} 155: ${VALGRIND_QEMU_IO=$VALGRIND_QEMU} 156: ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU} 157: ${VALGRIND_QSD=$VALGRIND_QEMU} 158 159# The Valgrind own parameters may be set with 160# its environment variable VALGRIND_OPTS, e.g. 161# $ VALGRIND_OPTS="--leak-check=yes" ./check -qcow2 -valgrind 015 162 163_qemu_proc_exec() 164{ 165 local VALGRIND_LOGFILE="$1" 166 shift 167 if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then 168 exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$@" 169 else 170 exec "$@" 171 fi 172} 173 174_qemu_proc_valgrind_log() 175{ 176 local VALGRIND_LOGFILE="$1" 177 local RETVAL="$2" 178 if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then 179 if [ $RETVAL == 99 ]; then 180 cat "${VALGRIND_LOGFILE}" 181 fi 182 rm -f "${VALGRIND_LOGFILE}" 183 fi 184} 185 186_qemu_wrapper() 187{ 188 local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind 189 ( 190 if [ -n "${QEMU_NEED_PID}" ]; then 191 echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid" 192 fi 193 194 GDB="" 195 if [ -n "${GDB_OPTIONS}" ]; then 196 GDB="gdbserver ${GDB_OPTIONS}" 197 fi 198 199 VALGRIND_QEMU="${VALGRIND_QEMU_VM}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ 200 $GDB "$QEMU_PROG" $QEMU_OPTIONS "$@" 201 ) 202 RETVAL=$? 203 _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL 204 return $RETVAL 205} 206 207_qemu_img_wrapper() 208{ 209 local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind 210 ( 211 VALGRIND_QEMU="${VALGRIND_QEMU_IMG}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ 212 "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@" 213 ) 214 RETVAL=$? 215 _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL 216 return $RETVAL 217} 218 219_qemu_io_wrapper() 220{ 221 local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind 222 local QEMU_IO_ARGS="$QEMU_IO_OPTIONS" 223 if [ "$IMGOPTSSYNTAX" = "true" ]; then 224 QEMU_IO_ARGS="--image-opts $QEMU_IO_ARGS" 225 if [ -n "$IMGKEYSECRET" ]; then 226 QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS" 227 fi 228 fi 229 ( 230 VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ 231 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" 232 ) 233 RETVAL=$? 234 _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL 235 return $RETVAL 236} 237 238_qemu_nbd_wrapper() 239{ 240 local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind 241 ( 242 VALGRIND_QEMU="${VALGRIND_QEMU_NBD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ 243 "$QEMU_NBD_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \ 244 $QEMU_NBD_OPTIONS "$@" 245 ) 246 RETVAL=$? 247 _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL 248 return $RETVAL 249} 250 251_qemu_storage_daemon_wrapper() 252{ 253 local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind 254 ( 255 if [ -n "${QSD_NEED_PID}" ]; then 256 echo $BASHPID > "${QEMU_TEST_DIR}/qemu-storage-daemon.pid" 257 fi 258 VALGRIND_QEMU="${VALGRIND_QSD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ 259 "$QSD_PROG" $QSD_OPTIONS "$@" 260 ) 261 RETVAL=$? 262 _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL 263 return $RETVAL 264} 265 266# Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141 267# Until valgrind 3.16+ is ubiquitous, we must work around a hang in 268# valgrind when issuing sigkill. Disable valgrind for this invocation. 269_NO_VALGRIND() 270{ 271 NO_VALGRIND="y" "$@" 272} 273 274export QEMU=_qemu_wrapper 275export QEMU_IMG=_qemu_img_wrapper 276export QEMU_IO=_qemu_io_wrapper 277export QEMU_NBD=_qemu_nbd_wrapper 278export QSD=_qemu_storage_daemon_wrapper 279 280if [ "$IMGOPTSSYNTAX" = "true" ]; then 281 DRIVER="driver=$IMGFMT" 282 QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS" 283 if [ -n "$IMGKEYSECRET" ]; then 284 QEMU_IMG_EXTRA_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IMG_EXTRA_ARGS" 285 fi 286 if [ "$IMGFMT" = "luks" ]; then 287 DRIVER="$DRIVER,key-secret=keysec0" 288 fi 289 if [ "$IMGPROTO" = "file" ]; then 290 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 291 TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT" 292 elif [ "$IMGPROTO" = "nbd" ]; then 293 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 294 TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix" 295 TEST_IMG="$TEST_IMG,file.path=$SOCK_DIR/nbd" 296 elif [ "$IMGPROTO" = "fuse" ]; then 297 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 298 TEST_IMG="$DRIVER,file.filename=$SOCK_DIR/fuse-t.$IMGFMT" 299 elif [ "$IMGPROTO" = "ssh" ]; then 300 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 301 TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE" 302 elif [ "$IMGPROTO" = "nfs" ]; then 303 TEST_DIR="$DRIVER,file.driver=nfs,file.filename=nfs://127.0.0.1/$TEST_DIR" 304 TEST_IMG=$TEST_DIR/t.$IMGFMT 305 else 306 TEST_IMG="$DRIVER,file.driver=$IMGPROTO,file.filename=$TEST_DIR/t.$IMGFMT" 307 fi 308else 309 QEMU_IMG_EXTRA_ARGS= 310 if [ "$IMGPROTO" = "file" ]; then 311 TEST_IMG=$TEST_DIR/t.$IMGFMT 312 elif [ "$IMGPROTO" = "nbd" ]; then 313 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 314 TEST_IMG="nbd+unix:///?socket=$SOCK_DIR/nbd" 315 elif [ "$IMGPROTO" = "fuse" ]; then 316 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 317 TEST_IMG="$SOCK_DIR/fuse-t.$IMGFMT" 318 elif [ "$IMGPROTO" = "ssh" ]; then 319 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 320 REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR" 321 TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE" 322 elif [ "$IMGPROTO" = "nfs" ]; then 323 TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT 324 REMOTE_TEST_DIR="nfs://127.0.0.1$TEST_DIR" 325 TEST_IMG="nfs://127.0.0.1$TEST_IMG_FILE" 326 else 327 TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT 328 fi 329fi 330ORIG_TEST_IMG_FILE=$TEST_IMG_FILE 331ORIG_TEST_IMG="$TEST_IMG" 332 333FUSE_PIDS=() 334FUSE_EXPORTS=() 335 336if [ -z "$TEST_DIR" ]; then 337 TEST_DIR=$PWD/scratch 338fi 339 340QEMU_TEST_DIR="${TEST_DIR}" 341 342if [ ! -e "$TEST_DIR" ]; then 343 mkdir "$TEST_DIR" 344fi 345 346if [ ! -d "$TEST_DIR" ]; then 347 echo "common.rc: Error: \$TEST_DIR ($TEST_DIR) is not a directory" 348 exit 1 349fi 350 351if [ -z "$REMOTE_TEST_DIR" ]; then 352 REMOTE_TEST_DIR="$TEST_DIR" 353fi 354 355if [ ! -d "$SAMPLE_IMG_DIR" ]; then 356 echo "common.rc: Error: \$SAMPLE_IMG_DIR ($SAMPLE_IMG_DIR) is not a directory" 357 exit 1 358fi 359 360_use_sample_img() 361{ 362 SAMPLE_IMG_FILE="${1%\.bz2}" 363 TEST_IMG="$TEST_DIR/$SAMPLE_IMG_FILE" 364 bzcat "$SAMPLE_IMG_DIR/$1" > "$TEST_IMG" 365 if [ $? -ne 0 ] 366 then 367 echo "_use_sample_img error, cannot extract '$SAMPLE_IMG_DIR/$1'" 368 exit 1 369 fi 370} 371 372_stop_nbd_server() 373{ 374 if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then 375 local QEMU_NBD_PID 376 read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid" 377 kill ${QEMU_NBD_PID} 378 rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid" "$SOCK_DIR/nbd" 379 fi 380} 381 382# Gets the data_file value from IMGOPTS and replaces the '$TEST_IMG' 383# pattern by '$1' 384# Caution: The replacement is done with sed, so $1 must be escaped 385# properly. (The delimiter is '#'.) 386_get_data_file() 387{ 388 if ! echo "$IMGOPTS" | grep -q 'data_file='; then 389 return 1 390 fi 391 392 echo "$IMGOPTS" | sed -e 's/.*data_file=\([^,]*\).*/\1/' \ 393 | sed -e "s#\\\$TEST_IMG#$1#" 394} 395 396# Translate a $TEST_IMG to its corresponding $TEST_IMG_FILE for 397# different protocols 398_test_img_to_test_img_file() 399{ 400 case "$IMGPROTO" in 401 file) 402 echo "$1" 403 ;; 404 405 fuse) 406 echo "$1" | sed -e "s#$SOCK_DIR/fuse-#$TEST_DIR/#" 407 ;; 408 409 nfs) 410 echo "$1" | sed -e "s#nfs://127.0.0.1##" 411 ;; 412 413 ssh) 414 echo "$1" | \ 415 sed -e "s#ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?##" 416 ;; 417 418 *) 419 return 1 420 ;; 421 esac 422} 423 424_make_test_img() 425{ 426 # extra qemu-img options can be added by tests 427 # at least one argument (the image size) needs to be added 428 local extra_img_options="" 429 local optstr="" 430 local img_name="" 431 local use_backing=0 432 local backing_file="" 433 local object_options="" 434 local opts_param=false 435 local misc_params=() 436 437 if [[ $IMGPROTO == fuse && $TEST_IMG == $SOCK_DIR/fuse-* ]]; then 438 # The caller may be trying to overwrite an existing image 439 _rm_test_img "$TEST_IMG" 440 fi 441 442 if [ -z "$TEST_IMG_FILE" ]; then 443 img_name=$TEST_IMG 444 elif [ "$IMGOPTSSYNTAX" != "true" -a \ 445 "$TEST_IMG_FILE" = "$ORIG_TEST_IMG_FILE" ]; then 446 # Handle cases of tests only updating TEST_IMG, but not TEST_IMG_FILE 447 img_name=$(_test_img_to_test_img_file "$TEST_IMG") 448 if [ "$?" != 0 ]; then 449 img_name=$TEST_IMG_FILE 450 fi 451 else 452 # $TEST_IMG_FILE is not the default value, so it definitely has been 453 # modified by the test 454 img_name=$TEST_IMG_FILE 455 fi 456 457 if [ -n "$IMGOPTS" ]; then 458 imgopts_expanded=$(echo "$IMGOPTS" | sed -e "s#\\\$TEST_IMG#$img_name#") 459 optstr=$(_optstr_add "$optstr" "$imgopts_expanded") 460 fi 461 if [ -n "$IMGKEYSECRET" ]; then 462 object_options="--object secret,id=keysec0,data=$IMGKEYSECRET" 463 optstr=$(_optstr_add "$optstr" "key-secret=keysec0") 464 fi 465 466 for param; do 467 if [ "$use_backing" = "1" -a -z "$backing_file" ]; then 468 backing_file=$param 469 continue 470 elif $opts_param; then 471 optstr=$(_optstr_add "$optstr" "$param") 472 opts_param=false 473 continue 474 fi 475 476 case "$param" in 477 -b) 478 use_backing=1 479 ;; 480 481 -o) 482 opts_param=true 483 ;; 484 485 --no-opts) 486 optstr="" 487 ;; 488 489 *) 490 misc_params=("${misc_params[@]}" "$param") 491 ;; 492 esac 493 done 494 495 if [ \( "$IMGFMT" = "qcow2" -o "$IMGFMT" = "qed" \) -a -n "$CLUSTER_SIZE" ]; then 496 optstr=$(_optstr_add "$optstr" "cluster_size=$CLUSTER_SIZE") 497 fi 498 499 if [ -n "$optstr" ]; then 500 extra_img_options="-o $optstr $extra_img_options" 501 fi 502 503 if [ $IMGPROTO = "nbd" ]; then 504 _stop_nbd_server 505 fi 506 507 # XXX(hch): have global image options? 508 ( 509 if [ $use_backing = 1 ]; then 510 $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" "${misc_params[@]}" 2>&1 511 else 512 $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" "${misc_params[@]}" 2>&1 513 fi 514 ) | _filter_img_create 515 516 # Start an NBD server on the image file, which is what we'll be talking to. 517 # Once NBD gains resize support, we may also want to use -f raw at the 518 # server and interpret format over NBD, but for now, the format is 519 # interpreted at the server and raw data sent over NBD. 520 if [ $IMGPROTO = "nbd" ]; then 521 # Pass a sufficiently high number to -e that should be enough for all 522 # tests 523 eval "$QEMU_NBD -v -t -k '$SOCK_DIR/nbd' -f $IMGFMT -e 42 -x '' $TEST_IMG_FILE >/dev/null &" 524 sleep 1 # FIXME: qemu-nbd needs to be listening before we continue 525 fi 526 527 if [ $IMGPROTO = "fuse" -a -f "$img_name" ]; then 528 local export_mp 529 local pid 530 local pidfile 531 local timeout 532 533 export_mp=$(echo "$img_name" | sed -e "s#$TEST_DIR/#$SOCK_DIR/fuse-#") 534 if ! echo "$export_mp" | grep -q "^$SOCK_DIR"; then 535 echo 'Cannot use FUSE exports with images outside of TEST_DIR' >&2 536 return 1 537 fi 538 539 touch "$export_mp" 540 rm -f "$SOCK_DIR/fuse-output" 541 542 # Usually, users would export formatted nodes. But we present fuse as a 543 # protocol-level driver here, so we have to leave the format to the 544 # client. 545 # Switch off allow-other, because in general we do not need it for 546 # iotests. The default allow-other=auto has the downside of printing a 547 # fusermount error on its first attempt if allow_other is not 548 # permissible, which we would need to filter. 549 QSD_NEED_PID=y $QSD \ 550 --blockdev file,node-name=export-node,filename=$img_name,discard=unmap \ 551 --export fuse,id=fuse-export,node-name=export-node,mountpoint="$export_mp",writable=on,growable=on,allow-other=off \ 552 & 553 554 pidfile="$QEMU_TEST_DIR/qemu-storage-daemon.pid" 555 556 # Wait for the PID file 557 while [ ! -f "$pidfile" ]; do 558 sleep 0.5 559 done 560 561 pid=$(cat "$pidfile") 562 rm -f "$pidfile" 563 564 FUSE_PIDS+=($pid) 565 FUSE_EXPORTS+=("$export_mp") 566 fi 567} 568 569_rm_test_img() 570{ 571 local img=$1 572 573 if [[ $IMGPROTO == fuse && $img == $SOCK_DIR/fuse-* ]]; then 574 # Drop a FUSE export 575 local df_output 576 local i 577 local image_file 578 local index='' 579 local timeout 580 581 for i in "${!FUSE_EXPORTS[@]}"; do 582 if [ "${FUSE_EXPORTS[i]}" = "$img" ]; then 583 index=$i 584 break 585 fi 586 done 587 588 if [ -z "$index" ]; then 589 # Probably gone already 590 return 0 591 fi 592 593 kill "${FUSE_PIDS[index]}" 594 595 # Wait until the mount is gone 596 timeout=10 # *0.5 s 597 while true; do 598 # Will show the mount point; if the mount is still there, 599 # it will be $img. 600 df_output=$(df "$img" 2>/dev/null) 601 602 # But df may also show an error ("Transpoint endpoint not 603 # connected"), so retry in such cases 604 if [ -n "$df_output" ]; then 605 if ! echo "$df_output" | grep -q "$img"; then 606 break 607 fi 608 fi 609 610 sleep 0.5 611 612 timeout=$((timeout - 1)) 613 if [ "$timeout" = 0 ]; then 614 echo 'Failed to take down FUSE export' >&2 615 return 1 616 fi 617 done 618 619 rm -f "$img" 620 621 unset "FUSE_PIDS[$index]" 622 unset "FUSE_EXPORTS[$index]" 623 624 image_file=$(echo "$img" | sed -e "s#$SOCK_DIR/fuse-#$TEST_DIR/#") 625 _rm_test_img "$image_file" 626 return 627 fi 628 629 if [ "$IMGFMT" = "vmdk" ]; then 630 # Remove all the extents for vmdk 631 "$QEMU_IMG" info "$img" 2>/dev/null | grep 'filename:' | cut -f 2 -d: \ 632 | xargs -I {} rm -f "{}" 633 elif [ "$IMGFMT" = "qcow2" ]; then 634 # Remove external data file 635 if data_file=$(_get_data_file "$img"); then 636 rm -f "$data_file" 637 fi 638 fi 639 rm -f "$img" 640} 641 642_cleanup_test_img() 643{ 644 case "$IMGPROTO" in 645 646 nbd) 647 _stop_nbd_server 648 rm -f "$TEST_IMG_FILE" 649 ;; 650 651 fuse) 652 local mp 653 654 for mp in "${FUSE_EXPORTS[@]}"; do 655 _rm_test_img "$mp" 656 done 657 658 FUSE_PIDS=() 659 FUSE_EXPORTS=() 660 ;; 661 662 file) 663 _rm_test_img "$TEST_DIR/t.$IMGFMT" 664 _rm_test_img "$TEST_DIR/t.$IMGFMT.orig" 665 _rm_test_img "$TEST_DIR/t.$IMGFMT.base" 666 if [ -n "$SAMPLE_IMG_FILE" ] 667 then 668 rm -f "$TEST_DIR/$SAMPLE_IMG_FILE" 669 SAMPLE_IMG_FILE= 670 TEST_IMG="$ORIG_TEST_IMG" 671 fi 672 ;; 673 674 rbd) 675 rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null 676 ;; 677 678 esac 679} 680 681_check_test_img() 682{ 683 ( 684 if [ "$IMGOPTSSYNTAX" = "true" ]; then 685 $QEMU_IMG check $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1 686 else 687 $QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1 688 fi 689 ) | _filter_testdir | _filter_qemu_img_check 690 691 # return real qemu_img check status, to analyze in 692 # _check_test_img_ignore_leaks 693 return ${PIPESTATUS[0]} 694} 695 696_check_test_img_ignore_leaks() 697{ 698 out=$(_check_test_img "$@") 699 status=$? 700 if [ $status = 3 ]; then 701 # This must correspond to success output in dump_human_image_check() 702 echo "No errors were found on the image." 703 return 0 704 fi 705 echo "$out" 706 return $status 707} 708 709_img_info() 710{ 711 if [[ "$1" == "--format-specific" ]]; then 712 local format_specific=1 713 shift 714 else 715 local format_specific=0 716 fi 717 718 discard=0 719 regex_json_spec_start='^ *"format-specific": \{' 720 regex_json_child_start='^ *"children": \[' 721 $QEMU_IMG info $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1 | \ 722 sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \ 723 -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \ 724 -e "s#$TEST_DIR#TEST_DIR#g" \ 725 -e "s#$SOCK_DIR/fuse-#TEST_DIR/#g" \ 726 -e "s#$SOCK_DIR/#SOCK_DIR/#g" \ 727 -e "s#$IMGFMT#IMGFMT#g" \ 728 -e 's/\(compression type: \)\(zlib\|zstd\)/\1COMPRESSION_TYPE/' \ 729 -e "/^disk size:/ D" \ 730 -e "/actual-size/ D" | \ 731 while IFS='' read -r line; do 732 if [[ $discard == 0 ]]; then 733 if [[ $format_specific == 0 && $line == "Format specific information:" ]]; then 734 discard=1 735 elif [[ $line =~ "Child node '/" ]]; then 736 discard=1 737 elif [[ $format_specific == 0 && $line =~ $regex_json_spec_start ]]; then 738 discard=2 739 regex_json_end="^${line%%[^ ]*}\\},? *$" 740 elif [[ $line =~ $regex_json_child_start ]]; then 741 discard=2 742 regex_json_end="^${line%%[^ ]*}\\],? *$" 743 fi 744 fi 745 if [[ $discard == 0 ]]; then 746 echo "$line" 747 elif [[ $discard == 1 && ! $line ]]; then 748 echo 749 discard=0 750 elif [[ $discard == 2 && $line =~ $regex_json_end ]]; then 751 discard=0 752 fi 753 done 754} 755 756# bail out, setting up .casenotrun file 757# The function _casenotrun() is used as a notifier. It is the 758# caller's responsibility to make skipped a particular test. 759# 760_casenotrun() 761{ 762 echo " [case not run] $*" >>"$TEST_DIR/$seq.casenotrun" 763} 764 765# just plain bail out 766# 767_fail() 768{ 769 echo "$*" | tee -a "$TEST_DIR/$seq.full" 770 echo "(see $seq.full for details)" 771 status=1 772 exit 1 773} 774 775# tests whether $IMGFMT is one of the supported image formats for a test 776# 777_supported_fmt() 778{ 779 # "generic" is suitable for most image formats. For some formats it doesn't 780 # work, however (most notably read-only formats), so they can opt out by 781 # setting IMGFMT_GENERIC to false. 782 for f; do 783 if [ "$f" = "$IMGFMT" -o "$f" = "generic" -a "$IMGFMT_GENERIC" = "true" ]; then 784 if [ "$IMGFMT" = "luks" ]; then 785 _require_working_luks 786 fi 787 return 788 fi 789 done 790 791 _notrun "not suitable for this image format: $IMGFMT" 792} 793 794# tests whether $IMGFMT is one of the unsupported image format for a test 795# 796_unsupported_fmt() 797{ 798 for f; do 799 if [ "$f" = "$IMGFMT" ]; then 800 _notrun "not suitable for this image format: $IMGFMT" 801 fi 802 done 803} 804 805# tests whether $IMGPROTO is one of the supported image protocols for a test 806# 807_supported_proto() 808{ 809 for f; do 810 if [ "$f" = "$IMGPROTO" -o "$f" = "generic" ]; then 811 return 812 fi 813 done 814 815 _notrun "not suitable for this image protocol: $IMGPROTO" 816} 817 818# tests whether $IMGPROTO is specified as an unsupported image protocol for a test 819# 820_unsupported_proto() 821{ 822 for f; do 823 if [ "$f" = "$IMGPROTO" ]; then 824 _notrun "not suitable for this image protocol: $IMGPROTO" 825 return 826 fi 827 done 828} 829 830# tests whether the host OS is one of the supported OSes for a test 831# 832_supported_os() 833{ 834 for h 835 do 836 if [ "$h" = "$HOSTOS" ] 837 then 838 return 839 fi 840 done 841 842 _notrun "not suitable for this OS: $HOSTOS" 843} 844 845_supported_cache_modes() 846{ 847 for mode; do 848 if [ "$mode" = "$CACHEMODE" ]; then 849 return 850 fi 851 done 852 _notrun "not suitable for cache mode: $CACHEMODE" 853} 854 855# Check whether the filesystem supports O_DIRECT 856_check_o_direct() 857{ 858 testfile="$TEST_DIR"/_check_o_direct 859 $QEMU_IMG create -f raw "$testfile" 1M > /dev/null 860 out=$($QEMU_IO -f raw -t none -c quit "$testfile" 2>&1) 861 rm -f "$testfile" 862 863 [[ "$out" != *"O_DIRECT"* ]] 864} 865 866_require_o_direct() 867{ 868 if ! _check_o_direct; then 869 _notrun "file system on $TEST_DIR does not support O_DIRECT" 870 fi 871} 872 873_check_cache_mode() 874{ 875 if [ $CACHEMODE == "none" ] || [ $CACHEMODE == "directsync" ]; then 876 _require_o_direct 877 fi 878} 879 880_check_cache_mode 881 882# $1 - cache mode to use by default 883# $2 - (optional) cache mode to use by default if O_DIRECT is not supported 884_default_cache_mode() 885{ 886 if $CACHEMODE_IS_DEFAULT; then 887 if [ -z "$2" ] || _check_o_direct; then 888 CACHEMODE="$1" 889 else 890 CACHEMODE="$2" 891 fi 892 QEMU_IO="$QEMU_IO --cache $CACHEMODE" 893 _check_cache_mode 894 return 895 fi 896} 897_supported_aio_modes() 898{ 899 for mode; do 900 if [ "$mode" = "$AIOMODE" ]; then 901 return 902 fi 903 done 904 _notrun "not suitable for aio mode: $AIOMODE" 905} 906_default_aio_mode() 907{ 908 AIOMODE="$1" 909 QEMU_IO="$QEMU_IO --aio $1" 910} 911 912_unsupported_imgopts() 913{ 914 for bad_opt 915 do 916 # Add a space so tests can match for whitespace that marks the 917 # end of an option (\b or \> are not portable) 918 if echo "$IMGOPTS " | grep -q 2>/dev/null "$bad_opt" 919 then 920 _notrun "not suitable for image option: $bad_opt" 921 fi 922 done 923} 924 925# Caution: Overwrites $TEST_DIR/t.luks 926_require_working_luks() 927{ 928 file="$TEST_DIR/t.luks" 929 930 output=$( 931 $QEMU_IMG create -f luks \ 932 --object secret,id=sec0,data=hunter0 \ 933 -o key-secret=sec0 \ 934 -o iter-time=10 \ 935 "$file" \ 936 1M \ 937 2>&1 938 ) 939 status=$? 940 941 IMGFMT='luks' _rm_test_img "$file" 942 943 if [ $status != 0 ]; then 944 reason=$(echo "$output" | grep "$file:" | sed -e "s#.*$file: *##") 945 if [ -z "$reason" ]; then 946 reason="Failed to create a LUKS image" 947 fi 948 _notrun "$reason" 949 fi 950} 951 952# this test requires that a specified command (executable) exists 953# 954_require_command() 955{ 956 if [ "$1" = "QEMU" ]; then 957 c=$QEMU_PROG 958 elif [ "$1" = "QEMU_IMG" ]; then 959 c=$QEMU_IMG_PROG 960 elif [ "$1" = "QEMU_IO" ]; then 961 c=$QEMU_IO_PROG 962 elif [ "$1" = "QEMU_NBD" ]; then 963 c=$QEMU_NBD_PROG 964 else 965 eval c=\$$1 966 fi 967 [ -x "$c" ] || _notrun "$1 utility required, skipped this test" 968} 969 970# Check that a set of drivers has been whitelisted in the QEMU binary 971# 972_require_drivers() 973{ 974 available=$($QEMU -drive format=help | \ 975 sed -e '/Supported formats:/!d' -e 's/Supported formats://') 976 for driver 977 do 978 if ! echo "$available" | grep -q " $driver\( \|$\)"; then 979 _notrun "$driver not available" 980 fi 981 done 982} 983 984# Check that we have a file system that allows huge (but very sparse) files 985# 986_require_large_file() 987{ 988 if [ -z "$TEST_IMG_FILE" ]; then 989 FILENAME="$TEST_IMG" 990 else 991 FILENAME="$TEST_IMG_FILE" 992 fi 993 if ! truncate --size="$1" "$FILENAME"; then 994 _notrun "file system on $TEST_DIR does not support large enough files" 995 fi 996 rm "$FILENAME" 997} 998 999# Check whether disk_usage can be reliably used. 1000_require_disk_usage() 1001{ 1002 local unusable=false 1003 # ZFS triggers known failures on this front; it does not immediately 1004 # allocate files, and then aggressively compresses writes even when full 1005 # allocation was requested. 1006 if [ -z "$TEST_IMG_FILE" ]; then 1007 FILENAME="$TEST_IMG" 1008 else 1009 FILENAME="$TEST_IMG_FILE" 1010 fi 1011 if [ -e "FILENAME" ]; then 1012 echo "unwilling to overwrite existing file" 1013 exit 1 1014 fi 1015 $QEMU_IMG create -f raw "$FILENAME" 5M > /dev/null 1016 if [ $(disk_usage "$FILENAME") -gt $((1024*1024)) ]; then 1017 unusable=true 1018 fi 1019 $QEMU_IMG create -f raw -o preallocation=full "$FILENAME" 5M > /dev/null 1020 if [ $(disk_usage "$FILENAME") -lt $((4*1024*1024)) ]; then 1021 unusable=true 1022 fi 1023 rm -f "$FILENAME" 1024 if $unusable; then 1025 _notrun "file system on $TEST_DIR does not handle sparse files nicely" 1026 fi 1027} 1028 1029# Check that a set of devices is available in the QEMU binary 1030# 1031_require_devices() 1032{ 1033 available=$($QEMU -M none -device help 2> /dev/null | \ 1034 grep ^name | sed -e 's/^name "//' -e 's/".*$//') 1035 for device 1036 do 1037 if ! echo "$available" | grep -q "$device" ; then 1038 _notrun "$device not available" 1039 fi 1040 done 1041} 1042 1043_require_one_device_of() 1044{ 1045 available=$($QEMU -M none -device help 2> /dev/null | \ 1046 grep ^name | sed -e 's/^name "//' -e 's/".*$//') 1047 for device 1048 do 1049 if echo "$available" | grep -q "$device" ; then 1050 return 1051 fi 1052 done 1053 _notrun "$* not available" 1054} 1055 1056_qcow2_dump_header() 1057{ 1058 if [[ "$1" == "--no-filter-compression" ]]; then 1059 local filter_compression=0 1060 shift 1061 else 1062 local filter_compression=1 1063 fi 1064 1065 img="$1" 1066 if [ -z "$img" ]; then 1067 img="$TEST_IMG" 1068 fi 1069 1070 if [[ $filter_compression == 0 ]]; then 1071 $PYTHON qcow2.py "$img" dump-header 1072 else 1073 $PYTHON qcow2.py "$img" dump-header | _filter_qcow2_compression_type_bit 1074 fi 1075} 1076 1077# make sure this script returns success 1078true 1079