1 #!/usr/bin/env bash 2 # group: rw auto 3 # 4 # Test qcow2 images with extended L2 entries 5 # 6 # Copyright (C) 2019-2020 Igalia, S.L. 7 # Author: Alberto Garcia <berto@igalia.com> 8 # 9 # This program is free software; you can redistribute it and/or modify 10 # it under the terms of the GNU General Public License as published by 11 # the Free Software Foundation; either version 2 of the License, or 12 # (at your option) any later version. 13 # 14 # This program is distributed in the hope that it will be useful, 15 # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 # GNU General Public License for more details. 18 # 19 # You should have received a copy of the GNU General Public License 20 # along with this program. If not, see <http://www.gnu.org/licenses/>. 21 # 22 23 # creator 24 owner=berto@igalia.com 25 26 seq="$(basename $0)" 27 echo "QA output created by $seq" 28 29 here="$PWD" 30 status=1 # failure is the default! 31 32 _cleanup() 33 { 34 _cleanup_test_img 35 rm -f "$TEST_IMG.raw" 36 } 37 trap "_cleanup; exit \$status" 0 1 2 3 15 38 39 # get standard environment, filters and checks 40 . ./common.rc 41 . ./common.filter 42 43 _supported_fmt qcow2 44 _supported_proto file nfs 45 _supported_os Linux 46 _unsupported_imgopts extended_l2 compat=0.10 cluster_size data_file refcount_bits=1[^0-9] 47 48 l2_offset=$((0x40000)) 49 50 _verify_img() 51 { 52 $QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.raw" | grep -v 'Images are identical' 53 $QEMU_IMG check "$TEST_IMG" | _filter_qemu_img_check | \ 54 grep -v 'No errors were found on the image' 55 } 56 57 # Compare the bitmap of an extended L2 entry against an expected value 58 _verify_l2_bitmap() 59 { 60 entry_no="$1" # L2 entry number, starting from 0 61 expected_alloc="$alloc" # Space-separated list of allocated subcluster indexes 62 expected_zero="$zero" # Space-separated list of zero subcluster indexes 63 64 offset=$(($l2_offset + $entry_no * 16)) 65 entry=$(peek_file_be "$TEST_IMG" $offset 8) 66 offset=$(($offset + 8)) 67 bitmap=$(peek_file_be "$TEST_IMG" $offset 8) 68 69 expected_bitmap=0 70 for bit in $expected_alloc; do 71 expected_bitmap=$(($expected_bitmap | (1 << $bit))) 72 done 73 for bit in $expected_zero; do 74 expected_bitmap=$(($expected_bitmap | (1 << (32 + $bit)))) 75 done 76 printf -v expected_bitmap "%u" $expected_bitmap # Convert to unsigned 77 78 printf "L2 entry #%d: 0x%016x %016x\n" "$entry_no" "$entry" "$bitmap" 79 if [ "$bitmap" != "$expected_bitmap" ]; then 80 printf "ERROR: expecting bitmap 0x%016x\n" "$expected_bitmap" 81 fi 82 } 83 84 # This should be called as _run_test c=XXX sc=XXX off=XXX len=XXX cmd=XXX 85 # c: cluster number (0 if unset) 86 # sc: subcluster number inside cluster @c (0 if unset) 87 # off: offset inside subcluster @sc, in kilobytes (0 if unset) 88 # len: request length, passed directly to qemu-io (e.g: 256, 4k, 1M, ...) 89 # cmd: the command to pass to qemu-io, must be one of 90 # write -> write 91 # zero -> write -z 92 # unmap -> write -z -u 93 # compress -> write -c 94 # discard -> discard 95 _run_test() 96 { 97 unset c sc off len cmd 98 for var in "$@"; do eval "$var"; done 99 case "${cmd:-write}" in 100 zero) 101 cmd="write -q -z";; 102 unmap) 103 cmd="write -q -z -u";; 104 compress) 105 pat=$((${pat:-0} + 1)) 106 cmd="write -q -c -P ${pat}";; 107 write) 108 pat=$((${pat:-0} + 1)) 109 cmd="write -q -P ${pat}";; 110 discard) 111 cmd="discard -q";; 112 *) 113 echo "Unknown option $cmd" 114 exit 1;; 115 esac 116 c="${c:-0}" 117 sc="${sc:-0}" 118 off="${off:-0}" 119 offset="$(($c * 64 + $sc * 2 + $off))" 120 [ "$offset" != 0 ] && offset="${offset}k" 121 cmd="$cmd ${offset} ${len}" 122 raw_cmd=$(echo $cmd | sed s/-c//) # Raw images don't support -c 123 echo $cmd | sed 's/-P [0-9][0-9]\?/-P PATTERN/' 124 $QEMU_IO -c "$cmd" "$TEST_IMG" | _filter_qemu_io 125 $QEMU_IO -c "$raw_cmd" -f raw "$TEST_IMG.raw" | _filter_qemu_io 126 _verify_img 127 _verify_l2_bitmap "$c" 128 } 129 130 _reset_img() 131 { 132 size="$1" 133 $QEMU_IMG create -f raw "$TEST_IMG.raw" "$size" | _filter_img_create 134 if [ "$use_backing_file" = "yes" ]; then 135 $QEMU_IMG create -f raw "$TEST_IMG.base" "$size" | _filter_img_create 136 $QEMU_IO -c "write -q -P 0xFF 0 $size" -f raw "$TEST_IMG.base" | _filter_qemu_io 137 $QEMU_IO -c "write -q -P 0xFF 0 $size" -f raw "$TEST_IMG.raw" | _filter_qemu_io 138 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" "$size" 139 else 140 _make_test_img -o extended_l2=on "$size" 141 fi 142 } 143 144 ############################################################ 145 ############################################################ 146 ############################################################ 147 148 # Test that writing to an image with subclusters produces the expected 149 # results, in images with and without backing files 150 for use_backing_file in yes no; do 151 echo 152 echo "### Standard write tests (backing file: $use_backing_file) ###" 153 echo 154 _reset_img 1M 155 ### Write subcluster #0 (beginning of subcluster) ### 156 alloc="0"; zero="" 157 _run_test sc=0 len=1k 158 159 ### Write subcluster #1 (middle of subcluster) ### 160 alloc="0 1"; zero="" 161 _run_test sc=1 off=1 len=512 162 163 ### Write subcluster #2 (end of subcluster) ### 164 alloc="0 1 2"; zero="" 165 _run_test sc=2 off=1 len=1k 166 167 ### Write subcluster #3 (full subcluster) ### 168 alloc="0 1 2 3"; zero="" 169 _run_test sc=3 len=2k 170 171 ### Write subclusters #4-6 (full subclusters) ### 172 alloc="$(seq 0 6)"; zero="" 173 _run_test sc=4 len=6k 174 175 ### Write subclusters #7-9 (partial subclusters) ### 176 alloc="$(seq 0 9)"; zero="" 177 _run_test sc=7 off=1 len=4k 178 179 ### Write subcluster #16 (partial subcluster) ### 180 alloc="$(seq 0 9) 16"; zero="" 181 _run_test sc=16 len=1k 182 183 ### Write subcluster #31-#33 (cluster overlap) ### 184 alloc="$(seq 0 9) 16 31"; zero="" 185 _run_test sc=31 off=1 len=4k 186 alloc="0 1" ; zero="" 187 _verify_l2_bitmap 1 188 189 ### Zero subcluster #1 190 alloc="0 $(seq 2 9) 16 31"; zero="1" 191 _run_test sc=1 len=2k cmd=zero 192 193 ### Zero cluster #0 194 alloc=""; zero="$(seq 0 31)" 195 _run_test sc=0 len=64k cmd=zero 196 197 ### Fill cluster #0 with data 198 alloc="$(seq 0 31)"; zero="" 199 _run_test sc=0 len=64k 200 201 ### Zero and unmap half of cluster #0 (this won't unmap it) 202 alloc="$(seq 16 31)"; zero="$(seq 0 15)" 203 _run_test sc=0 len=32k cmd=unmap 204 205 ### Zero and unmap cluster #0 206 alloc=""; zero="$(seq 0 31)" 207 _run_test sc=0 len=64k cmd=unmap 208 209 ### Write subcluster #1 (middle of subcluster) 210 alloc="1"; zero="0 $(seq 2 31)" 211 _run_test sc=1 off=1 len=512 212 213 ### Fill cluster #0 with data 214 alloc="$(seq 0 31)"; zero="" 215 _run_test sc=0 len=64k 216 217 ### Discard cluster #0 218 alloc=""; zero="$(seq 0 31)" 219 _run_test sc=0 len=64k cmd=discard 220 221 ### Write compressed data to cluster #0 222 alloc=""; zero="" 223 _run_test sc=0 len=64k cmd=compress 224 225 ### Write subcluster #1 (middle of subcluster) 226 alloc="$(seq 0 31)"; zero="" 227 _run_test sc=1 off=1 len=512 228 done 229 230 ############################################################ 231 ############################################################ 232 ############################################################ 233 234 # calculate_l2_meta() checks if none of the clusters affected by a 235 # write operation need COW or changes to their L2 metadata and simply 236 # returns when they don't. This is a test for that optimization. 237 # Here clusters #0-#3 are overwritten but only #1 and #2 need changes. 238 echo 239 echo '### Overwriting several clusters without COW ###' 240 echo 241 use_backing_file="no" _reset_img 1M 242 # Write cluster #0, subclusters #12-#31 243 alloc="$(seq 12 31)"; zero="" 244 _run_test sc=12 len=40k 245 246 # Write cluster #1, subcluster #13 247 alloc="13"; zero="" 248 _run_test c=1 sc=13 len=2k 249 250 # Zeroize cluster #2, subcluster #14 251 alloc="14"; zero="" 252 _run_test c=2 sc=14 len=2k 253 alloc=""; zero="14" 254 _run_test c=2 sc=14 len=2k cmd=zero 255 256 # Write cluster #3, subclusters #0-#16 257 alloc="$(seq 0 16)"; zero="" 258 _run_test c=3 sc=0 len=34k 259 260 # Write from cluster #0, subcluster #12 to cluster #3, subcluster #11 261 alloc="$(seq 12 31)"; zero="" 262 _run_test sc=12 len=192k 263 alloc="$(seq 0 31)"; zero="" 264 _verify_l2_bitmap 1 265 _verify_l2_bitmap 2 266 267 alloc="$(seq 0 16)"; zero="" 268 _verify_l2_bitmap 3 269 270 ############################################################ 271 ############################################################ 272 ############################################################ 273 274 # Test different patterns of writing zeroes 275 for use_backing_file in yes no; do 276 echo 277 echo "### Writing zeroes 1: unallocated clusters (backing file: $use_backing_file) ###" 278 echo 279 # Note that the image size is not a multiple of the cluster size 280 _reset_img 2083k 281 282 # Cluster-aligned request from clusters #0 to #2 283 alloc=""; zero="$(seq 0 31)" 284 _run_test c=0 sc=0 len=192k cmd=zero 285 _verify_l2_bitmap 1 286 _verify_l2_bitmap 2 287 288 # Subcluster-aligned request from clusters #3 to #5 289 alloc=""; zero="$(seq 16 31)" 290 _run_test c=3 sc=16 len=128k cmd=zero 291 alloc=""; zero="$(seq 0 31)" 292 _verify_l2_bitmap 4 293 alloc=""; zero="$(seq 0 15)" 294 _verify_l2_bitmap 5 295 296 # Unaligned request from clusters #6 to #8 297 if [ "$use_backing_file" = "yes" ]; then 298 alloc="15"; zero="$(seq 16 31)" # copy-on-write happening here 299 else 300 alloc=""; zero="$(seq 15 31)" 301 fi 302 _run_test c=6 sc=15 off=1 len=128k cmd=zero 303 alloc=""; zero="$(seq 0 31)" 304 _verify_l2_bitmap 7 305 if [ "$use_backing_file" = "yes" ]; then 306 alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here 307 else 308 alloc=""; zero="$(seq 0 15)" 309 fi 310 _verify_l2_bitmap 8 311 312 echo 313 echo "### Writing zeroes 2: allocated clusters (backing file: $use_backing_file) ###" 314 echo 315 alloc="$(seq 0 31)"; zero="" 316 _run_test c=9 sc=0 len=576k 317 _verify_l2_bitmap 10 318 _verify_l2_bitmap 11 319 _verify_l2_bitmap 12 320 _verify_l2_bitmap 13 321 _verify_l2_bitmap 14 322 _verify_l2_bitmap 15 323 _verify_l2_bitmap 16 324 _verify_l2_bitmap 17 325 326 # Cluster-aligned request from clusters #9 to #11 327 alloc=""; zero="$(seq 0 31)" 328 _run_test c=9 sc=0 len=192k cmd=zero 329 _verify_l2_bitmap 10 330 _verify_l2_bitmap 11 331 332 # Subcluster-aligned request from clusters #12 to #14 333 alloc="$(seq 0 15)"; zero="$(seq 16 31)" 334 _run_test c=12 sc=16 len=128k cmd=zero 335 alloc=""; zero="$(seq 0 31)" 336 _verify_l2_bitmap 13 337 alloc="$(seq 16 31)"; zero="$(seq 0 15)" 338 _verify_l2_bitmap 14 339 340 # Unaligned request from clusters #15 to #17 341 alloc="$(seq 0 15)"; zero="$(seq 16 31)" 342 _run_test c=15 sc=15 off=1 len=128k cmd=zero 343 alloc=""; zero="$(seq 0 31)" 344 _verify_l2_bitmap 16 345 alloc="$(seq 15 31)"; zero="$(seq 0 14)" 346 _verify_l2_bitmap 17 347 348 echo 349 echo "### Writing zeroes 3: compressed clusters (backing file: $use_backing_file) ###" 350 echo 351 alloc=""; zero="" 352 for c in $(seq 18 28); do 353 _run_test c=$c sc=0 len=64k cmd=compress 354 done 355 356 # Cluster-aligned request from clusters #18 to #20 357 alloc=""; zero="$(seq 0 31)" 358 _run_test c=18 sc=0 len=192k cmd=zero 359 _verify_l2_bitmap 19 360 _verify_l2_bitmap 20 361 362 # Subcluster-aligned request from clusters #21 to #23. 363 # We cannot partially zero a compressed cluster so the code 364 # returns -ENOTSUP, which means copy-on-write of the compressed 365 # data and fill the rest with actual zeroes on disk. 366 # TODO: cluster #22 should use the 'all zeroes' bits. 367 alloc="$(seq 0 31)"; zero="" 368 _run_test c=21 sc=16 len=128k cmd=zero 369 _verify_l2_bitmap 22 370 _verify_l2_bitmap 23 371 372 # Unaligned request from clusters #24 to #26 373 # In this case QEMU internally sends a 1k request followed by a 374 # subcluster-aligned 128k request. The first request decompresses 375 # cluster #24, but that's not enough to perform the second request 376 # efficiently because it partially writes to cluster #26 (which is 377 # compressed) so we hit the same problem as before. 378 alloc="$(seq 0 31)"; zero="" 379 _run_test c=24 sc=15 off=1 len=129k cmd=zero 380 _verify_l2_bitmap 25 381 _verify_l2_bitmap 26 382 383 # Unaligned request from clusters #27 to #29 384 # Similar to the previous case, but this time the tail of the 385 # request does not correspond to a compressed cluster, so it can 386 # be zeroed efficiently. 387 # Note that the very last subcluster is partially written, so if 388 # there's a backing file we need to perform cow. 389 alloc="$(seq 0 15)"; zero="$(seq 16 31)" 390 _run_test c=27 sc=15 off=1 len=128k cmd=zero 391 alloc=""; zero="$(seq 0 31)" 392 _verify_l2_bitmap 28 393 if [ "$use_backing_file" = "yes" ]; then 394 alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here 395 else 396 alloc=""; zero="$(seq 0 15)" 397 fi 398 _verify_l2_bitmap 29 399 400 echo 401 echo "### Writing zeroes 4: other tests (backing file: $use_backing_file) ###" 402 echo 403 # Unaligned request in the middle of cluster #30. 404 # If there's a backing file we need to allocate and do 405 # copy-on-write on the partially zeroed subclusters. 406 # If not we can set the 'all zeroes' bit on them. 407 if [ "$use_backing_file" = "yes" ]; then 408 alloc="15 19"; zero="$(seq 16 18)" # copy-on-write happening here 409 else 410 alloc=""; zero="$(seq 15 19)" 411 fi 412 _run_test c=30 sc=15 off=1 len=8k cmd=zero 413 414 # Fill the last cluster with zeroes, up to the end of the image 415 # (the image size is not a multiple of the cluster or subcluster size). 416 alloc=""; zero="$(seq 0 17)" 417 _run_test c=32 sc=0 len=35k cmd=zero 418 done 419 420 ############################################################ 421 ############################################################ 422 ############################################################ 423 424 # Zero + unmap 425 for use_backing_file in yes no; do 426 echo 427 echo "### Zero + unmap 1: allocated clusters (backing file: $use_backing_file) ###" 428 echo 429 # Note that the image size is not a multiple of the cluster size 430 _reset_img 2083k 431 alloc="$(seq 0 31)"; zero="" 432 _run_test c=9 sc=0 len=576k 433 _verify_l2_bitmap 10 434 _verify_l2_bitmap 11 435 _verify_l2_bitmap 12 436 _verify_l2_bitmap 13 437 _verify_l2_bitmap 14 438 _verify_l2_bitmap 15 439 _verify_l2_bitmap 16 440 _verify_l2_bitmap 17 441 442 # Cluster-aligned request from clusters #9 to #11 443 alloc=""; zero="$(seq 0 31)" 444 _run_test c=9 sc=0 len=192k cmd=unmap 445 _verify_l2_bitmap 10 446 _verify_l2_bitmap 11 447 448 # Subcluster-aligned request from clusters #12 to #14 449 alloc="$(seq 0 15)"; zero="$(seq 16 31)" 450 _run_test c=12 sc=16 len=128k cmd=unmap 451 alloc=""; zero="$(seq 0 31)" 452 _verify_l2_bitmap 13 453 alloc="$(seq 16 31)"; zero="$(seq 0 15)" 454 _verify_l2_bitmap 14 455 456 # Unaligned request from clusters #15 to #17 457 alloc="$(seq 0 15)"; zero="$(seq 16 31)" 458 _run_test c=15 sc=15 off=1 len=128k cmd=unmap 459 alloc=""; zero="$(seq 0 31)" 460 _verify_l2_bitmap 16 461 alloc="$(seq 15 31)"; zero="$(seq 0 14)" 462 _verify_l2_bitmap 17 463 464 echo 465 echo "### Zero + unmap 2: compressed clusters (backing file: $use_backing_file) ###" 466 echo 467 alloc=""; zero="" 468 for c in $(seq 18 28); do 469 _run_test c=$c sc=0 len=64k cmd=compress 470 done 471 472 # Cluster-aligned request from clusters #18 to #20 473 alloc=""; zero="$(seq 0 31)" 474 _run_test c=18 sc=0 len=192k cmd=unmap 475 _verify_l2_bitmap 19 476 _verify_l2_bitmap 20 477 478 # Subcluster-aligned request from clusters #21 to #23. 479 # We cannot partially zero a compressed cluster so the code 480 # returns -ENOTSUP, which means copy-on-write of the compressed 481 # data and fill the rest with actual zeroes on disk. 482 # TODO: cluster #22 should use the 'all zeroes' bits. 483 alloc="$(seq 0 31)"; zero="" 484 _run_test c=21 sc=16 len=128k cmd=unmap 485 _verify_l2_bitmap 22 486 _verify_l2_bitmap 23 487 488 # Unaligned request from clusters #24 to #26 489 # In this case QEMU internally sends a 1k request followed by a 490 # subcluster-aligned 128k request. The first request decompresses 491 # cluster #24, but that's not enough to perform the second request 492 # efficiently because it partially writes to cluster #26 (which is 493 # compressed) so we hit the same problem as before. 494 alloc="$(seq 0 31)"; zero="" 495 _run_test c=24 sc=15 off=1 len=129k cmd=unmap 496 _verify_l2_bitmap 25 497 _verify_l2_bitmap 26 498 499 # Unaligned request from clusters #27 to #29 500 # Similar to the previous case, but this time the tail of the 501 # request does not correspond to a compressed cluster, so it can 502 # be zeroed efficiently. 503 # Note that the very last subcluster is partially written, so if 504 # there's a backing file we need to perform cow. 505 alloc="$(seq 0 15)"; zero="$(seq 16 31)" 506 _run_test c=27 sc=15 off=1 len=128k cmd=unmap 507 alloc=""; zero="$(seq 0 31)" 508 _verify_l2_bitmap 28 509 if [ "$use_backing_file" = "yes" ]; then 510 alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here 511 else 512 alloc=""; zero="$(seq 0 15)" 513 fi 514 _verify_l2_bitmap 29 515 done 516 517 ############################################################ 518 ############################################################ 519 ############################################################ 520 521 # Test qcow2_cluster_discard() with full and normal discards 522 for use_backing_file in yes no; do 523 echo 524 echo "### Discarding clusters with non-zero bitmaps (backing file: $use_backing_file) ###" 525 echo 526 if [ "$use_backing_file" = "yes" ]; then 527 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 1M 528 else 529 _make_test_img -o extended_l2=on 1M 530 fi 531 # Write clusters #0-#2 and then discard them 532 $QEMU_IO -c 'write -q 0 128k' "$TEST_IMG" 533 $QEMU_IO -c 'discard -q 0 128k' "$TEST_IMG" 534 # 'qemu-io discard' doesn't do a full discard, it zeroizes the 535 # cluster, so both clusters have all zero bits set now 536 alloc=""; zero="$(seq 0 31)" 537 _verify_l2_bitmap 0 538 _verify_l2_bitmap 1 539 # Now mark the 2nd half of the subclusters from cluster #0 as unallocated 540 poke_file "$TEST_IMG" $(($l2_offset+8)) "\x00\x00" 541 # Discard cluster #0 again to see how the zero bits have changed 542 $QEMU_IO -c 'discard -q 0 64k' "$TEST_IMG" 543 # And do a full discard of cluster #1 by shrinking and growing the image 544 $QEMU_IMG resize --shrink "$TEST_IMG" 64k 545 $QEMU_IMG resize "$TEST_IMG" 1M 546 # A normal discard sets all 'zero' bits only if the image has a 547 # backing file, otherwise it won't touch them. 548 if [ "$use_backing_file" = "yes" ]; then 549 alloc=""; zero="$(seq 0 31)" 550 else 551 alloc=""; zero="$(seq 0 15)" 552 fi 553 _verify_l2_bitmap 0 554 # A full discard should clear the L2 entry completely. However 555 # when growing an image with a backing file the new clusters are 556 # zeroized to hide the stale data from the backing file 557 if [ "$use_backing_file" = "yes" ]; then 558 alloc=""; zero="$(seq 0 31)" 559 else 560 alloc=""; zero="" 561 fi 562 _verify_l2_bitmap 1 563 done 564 565 ############################################################ 566 ############################################################ 567 ############################################################ 568 569 # Test that corrupted L2 entries are detected in both read and write 570 # operations 571 for corruption_test_cmd in read write; do 572 echo 573 echo "### Corrupted L2 entries - $corruption_test_cmd test (allocated) ###" 574 echo 575 echo "# 'cluster is zero' bit set on the standard cluster descriptor" 576 echo 577 # We actually don't consider this a corrupted image. 578 # The 'cluster is zero' bit is unused in extended L2 entries so 579 # QEMU ignores it. 580 # TODO: maybe treat the image as corrupted and make qemu-img check fix it? 581 _make_test_img -o extended_l2=on 1M 582 $QEMU_IO -c 'write -q -P 0x11 0 2k' "$TEST_IMG" 583 poke_file "$TEST_IMG" $(($l2_offset+7)) "\x01" 584 alloc="0"; zero="" 585 _verify_l2_bitmap 0 586 $QEMU_IO -c "$corruption_test_cmd -q -P 0x11 0 1k" "$TEST_IMG" 587 if [ "$corruption_test_cmd" = "write" ]; then 588 alloc="0"; zero="" 589 fi 590 _verify_l2_bitmap 0 591 592 echo 593 echo "# Both 'subcluster is zero' and 'subcluster is allocated' bits set" 594 echo 595 _make_test_img -o extended_l2=on 1M 596 # Write from the middle of cluster #0 to the middle of cluster #2 597 $QEMU_IO -c 'write -q 32k 128k' "$TEST_IMG" 598 # Corrupt the L2 entry from cluster #1 599 poke_file_be "$TEST_IMG" $(($l2_offset+24)) 4 1 600 alloc="$(seq 0 31)"; zero="0" 601 _verify_l2_bitmap 1 602 $QEMU_IO -c "$corruption_test_cmd 0 192k" "$TEST_IMG" 603 604 echo 605 echo "### Corrupted L2 entries - $corruption_test_cmd test (unallocated) ###" 606 echo 607 echo "# 'cluster is zero' bit set on the standard cluster descriptor" 608 echo 609 # We actually don't consider this a corrupted image. 610 # The 'cluster is zero' bit is unused in extended L2 entries so 611 # QEMU ignores it. 612 # TODO: maybe treat the image as corrupted and make qemu-img check fix it? 613 _make_test_img -o extended_l2=on 1M 614 # We want to modify the (empty) L2 entry from cluster #0, 615 # but we write to #4 in order to initialize the L2 table first 616 $QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG" 617 poke_file "$TEST_IMG" $(($l2_offset+7)) "\x01" 618 alloc=""; zero="" 619 _verify_l2_bitmap 0 620 $QEMU_IO -c "$corruption_test_cmd -q 0 1k" "$TEST_IMG" 621 if [ "$corruption_test_cmd" = "write" ]; then 622 alloc="0"; zero="" 623 fi 624 _verify_l2_bitmap 0 625 626 echo 627 echo "# 'subcluster is allocated' bit set" 628 echo 629 _make_test_img -o extended_l2=on 1M 630 # We want to corrupt the (empty) L2 entry from cluster #0, 631 # but we write to #4 in order to initialize the L2 table first 632 $QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG" 633 poke_file "$TEST_IMG" $(($l2_offset+15)) "\x01" 634 alloc="0"; zero="" 635 _verify_l2_bitmap 0 636 $QEMU_IO -c "$corruption_test_cmd 0 1k" "$TEST_IMG" 637 638 echo 639 echo "# Both 'subcluster is zero' and 'subcluster is allocated' bits set" 640 echo 641 _make_test_img -o extended_l2=on 1M 642 # We want to corrupt the (empty) L2 entry from cluster #1, 643 # but we write to #4 in order to initialize the L2 table first 644 $QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG" 645 # Corrupt the L2 entry from cluster #1 646 poke_file_be "$TEST_IMG" $(($l2_offset+24)) 8 $(((1 << 32) | 1)) 647 alloc="0"; zero="0" 648 _verify_l2_bitmap 1 649 $QEMU_IO -c "$corruption_test_cmd 0 192k" "$TEST_IMG" 650 651 echo 652 echo "### Compressed cluster with subcluster bitmap != 0 - $corruption_test_cmd test ###" 653 echo 654 # We actually don't consider this a corrupted image. 655 # The bitmap in compressed clusters is unused so QEMU should just ignore it. 656 _make_test_img -o extended_l2=on 1M 657 $QEMU_IO -c 'write -q -P 11 -c 0 64k' "$TEST_IMG" 658 # Change the L2 bitmap to allocate subcluster #31 and zeroize subcluster #0 659 poke_file "$TEST_IMG" $(($l2_offset+11)) "\x01\x80" 660 alloc="31"; zero="0" 661 _verify_l2_bitmap 0 662 $QEMU_IO -c "$corruption_test_cmd -P 11 0 64k" "$TEST_IMG" | _filter_qemu_io 663 # Writing allocates a new uncompressed cluster so we get a new bitmap 664 if [ "$corruption_test_cmd" = "write" ]; then 665 alloc="$(seq 0 31)"; zero="" 666 fi 667 _verify_l2_bitmap 0 668 done 669 670 ############################################################ 671 ############################################################ 672 ############################################################ 673 674 echo 675 echo "### Detect and repair unaligned clusters ###" 676 echo 677 # Create a backing file and fill it with data 678 $QEMU_IMG create -f raw "$TEST_IMG.base" 128k | _filter_img_create 679 $QEMU_IO -c "write -q -P 0xff 0 128k" -f raw "$TEST_IMG.base" | _filter_qemu_io 680 681 echo "# Corrupted L2 entry, allocated subcluster #" 682 # Create a new image, allocate a cluster and write some data to it 683 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 684 $QEMU_IO -c 'write -q -P 1 4k 2k' "$TEST_IMG" 685 # Corrupt the L2 entry by making the offset unaligned 686 poke_file "$TEST_IMG" "$(($l2_offset+6))" "\x02" 687 # This cannot be repaired, qemu-img check will fail to fix it 688 _check_test_img -r all 689 # Attempting to read the image will still show that it's corrupted 690 $QEMU_IO -c 'read -q 0 2k' "$TEST_IMG" 691 692 echo "# Corrupted L2 entry, no allocated subclusters #" 693 # Create a new image, allocate a cluster and zeroize subcluster #2 694 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 695 $QEMU_IO -c 'write -q -P 1 4k 2k' "$TEST_IMG" 696 $QEMU_IO -c 'write -q -z 4k 2k' "$TEST_IMG" 697 # Corrupt the L2 entry by making the offset unaligned 698 poke_file "$TEST_IMG" "$(($l2_offset+6))" "\x02" 699 # This time none of the subclusters are allocated so we can repair the image 700 _check_test_img -r all 701 # And the data can be read normally 702 $QEMU_IO -c 'read -q -P 0xff 0 4k' "$TEST_IMG" 703 $QEMU_IO -c 'read -q -P 0x00 4k 2k' "$TEST_IMG" 704 $QEMU_IO -c 'read -q -P 0xff 6k 122k' "$TEST_IMG" 705 706 ############################################################ 707 ############################################################ 708 ############################################################ 709 710 echo 711 echo "### Image creation options ###" 712 echo 713 echo "# cluster_size < 16k" 714 _make_test_img -o extended_l2=on,cluster_size=8k 1M 715 716 echo "# backing file and preallocation=metadata" 717 # For preallocation with backing files, create a backing file first 718 $QEMU_IMG create -f raw "$TEST_IMG.base" 1M | _filter_img_create 719 $QEMU_IO -c "write -q -P 0xff 0 1M" -f raw "$TEST_IMG.base" | _filter_qemu_io 720 721 _make_test_img -o extended_l2=on,preallocation=metadata -F raw -b "$TEST_IMG.base" 512k 722 $QEMU_IMG resize "$TEST_IMG" 1M 723 $QEMU_IO -c 'read -P 0xff 0 512k' "$TEST_IMG" | _filter_qemu_io 724 $QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io 725 $QEMU_IMG map "$TEST_IMG" | _filter_testdir 726 727 echo "# backing file and preallocation=falloc" 728 _make_test_img -o extended_l2=on,preallocation=falloc -F raw -b "$TEST_IMG.base" 512k 729 $QEMU_IMG resize "$TEST_IMG" 1M 730 $QEMU_IO -c 'read -P 0xff 0 512k' "$TEST_IMG" | _filter_qemu_io 731 $QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io 732 $QEMU_IMG map "$TEST_IMG" | _filter_testdir 733 734 echo "# backing file and preallocation=full" 735 _make_test_img -o extended_l2=on,preallocation=full -F raw -b "$TEST_IMG.base" 512k 736 $QEMU_IMG resize "$TEST_IMG" 1M 737 $QEMU_IO -c 'read -P 0xff 0 512k' "$TEST_IMG" | _filter_qemu_io 738 $QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io 739 $QEMU_IMG map "$TEST_IMG" | _filter_testdir 740 741 echo 742 echo "### Image resizing with preallocation and backing files ###" 743 echo 744 # In this case the new subclusters must have the 'all zeroes' bit set 745 echo "# resize --preallocation=metadata" 746 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k 747 $QEMU_IMG resize --preallocation=metadata "$TEST_IMG" 1013k 748 $QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 749 $QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io 750 751 # In this case and the next one the new subclusters must be allocated 752 echo "# resize --preallocation=falloc" 753 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k 754 $QEMU_IMG resize --preallocation=falloc "$TEST_IMG" 1013k 755 $QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 756 $QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io 757 758 echo "# resize --preallocation=full" 759 _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k 760 $QEMU_IMG resize --preallocation=full "$TEST_IMG" 1013k 761 $QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 762 $QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io 763 764 echo 765 echo "### Image resizing with preallocation without backing files ###" 766 echo 767 # In this case the new subclusters must have the 'all zeroes' bit set 768 echo "# resize --preallocation=metadata" 769 _make_test_img -o extended_l2=on 503k 770 $QEMU_IO -c 'write -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 771 $QEMU_IMG resize --preallocation=metadata "$TEST_IMG" 1013k 772 $QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 773 $QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io 774 775 # In this case and the next one the new subclusters must be allocated 776 echo "# resize --preallocation=falloc" 777 _make_test_img -o extended_l2=on 503k 778 $QEMU_IO -c 'write -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 779 $QEMU_IMG resize --preallocation=falloc "$TEST_IMG" 1013k 780 $QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 781 $QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io 782 783 echo "# resize --preallocation=full" 784 _make_test_img -o extended_l2=on 503k 785 $QEMU_IO -c 'write -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 786 $QEMU_IMG resize --preallocation=full "$TEST_IMG" 1013k 787 $QEMU_IO -c 'read -P 0xff 0 503k' "$TEST_IMG" | _filter_qemu_io 788 $QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io 789 790 echo 791 echo "### qemu-img measure ###" 792 echo 793 echo "# 512MB, extended_l2=off" # This needs one L2 table 794 $QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=off 795 echo "# 512MB, extended_l2=on" # This needs two L2 tables 796 $QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=on 797 798 echo "# 16K clusters, 64GB, extended_l2=off" # This needs one full L1 table cluster 799 $QEMU_IMG measure --size 64G -O qcow2 -o cluster_size=16k,extended_l2=off 800 echo "# 16K clusters, 64GB, extended_l2=on" # This needs two full L2 table clusters 801 $QEMU_IMG measure --size 64G -O qcow2 -o cluster_size=16k,extended_l2=on 802 803 echo "# 8k clusters" # This should fail 804 $QEMU_IMG measure --size 1M -O qcow2 -o cluster_size=8k,extended_l2=on 805 806 echo "# 1024 TB" # Maximum allowed size with extended_l2=on and 64K clusters 807 $QEMU_IMG measure --size 1024T -O qcow2 -o extended_l2=on 808 echo "# 1025 TB" # This should fail 809 $QEMU_IMG measure --size 1025T -O qcow2 -o extended_l2=on 810 811 echo 812 echo "### qemu-img amend ###" 813 echo 814 _make_test_img -o extended_l2=on 1M 815 $QEMU_IMG amend -o extended_l2=off "$TEST_IMG" && echo "Unexpected pass" 816 817 _make_test_img -o extended_l2=off 1M 818 $QEMU_IMG amend -o extended_l2=on "$TEST_IMG" && echo "Unexpected pass" 819 820 echo 821 echo "### Test copy-on-write on an image with snapshots ###" 822 echo 823 _make_test_img -o extended_l2=on 1M 824 825 # For each cluster from #0 to #9 this loop zeroes subcluster #7 826 # and allocates subclusters #13 and #18. 827 alloc="13 18"; zero="7" 828 for c in $(seq 0 9); do 829 $QEMU_IO -c "write -q -z $((64*$c+14))k 2k" \ 830 -c "write -q -P $((0xd0+$c)) $((64*$c+26))k 2k" \ 831 -c "write -q -P $((0xe0+$c)) $((64*$c+36))k 2k" "$TEST_IMG" 832 _verify_l2_bitmap "$c" 833 done 834 835 # Create a snapshot and set l2_offset to the new L2 table 836 $QEMU_IMG snapshot -c snap1 "$TEST_IMG" 837 l2_offset=$((0x110000)) 838 839 # Write different patterns to each one of the clusters 840 # in order to see how copy-on-write behaves in each case. 841 $QEMU_IO -c "write -q -P 0xf0 $((64*0+30))k 1k" \ 842 -c "write -q -P 0xf1 $((64*1+20))k 1k" \ 843 -c "write -q -P 0xf2 $((64*2+40))k 1k" \ 844 -c "write -q -P 0xf3 $((64*3+26))k 1k" \ 845 -c "write -q -P 0xf4 $((64*4+14))k 1k" \ 846 -c "write -q -P 0xf5 $((64*5+1))k 1k" \ 847 -c "write -q -z $((64*6+30))k 3k" \ 848 -c "write -q -z $((64*7+26))k 2k" \ 849 -c "write -q -z $((64*8+26))k 1k" \ 850 -c "write -q -z $((64*9+12))k 1k" \ 851 "$TEST_IMG" 852 alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 0 853 alloc="$(seq 10 18)"; zero="7" _verify_l2_bitmap 1 854 alloc="$(seq 13 20)"; zero="7" _verify_l2_bitmap 2 855 alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 3 856 alloc="$(seq 7 18)"; zero="" _verify_l2_bitmap 4 857 alloc="$(seq 0 18)"; zero="" _verify_l2_bitmap 5 858 alloc="13 18"; zero="7 15 16" _verify_l2_bitmap 6 859 alloc="18"; zero="7 13" _verify_l2_bitmap 7 860 alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 8 861 alloc="13 18"; zero="6 7" _verify_l2_bitmap 9 862 863 echo 864 echo "### Test concurrent requests ###" 865 echo 866 867 _concurrent_io() 868 { 869 # Allocate three subclusters in the same cluster. 870 # This works because handle_dependencies() checks whether the requests 871 # allocate the same cluster, even if the COW regions don't overlap (in 872 # this case they don't). 873 cat <<EOF 874 open -o driver=$IMGFMT blkdebug::$TEST_IMG 875 break write_aio A 876 aio_write -P 10 30k 2k 877 wait_break A 878 aio_write -P 11 20k 2k 879 aio_write -P 12 40k 2k 880 resume A 881 aio_flush 882 EOF 883 } 884 885 _concurrent_verify() 886 { 887 cat <<EOF 888 open -o driver=$IMGFMT $TEST_IMG 889 read -q -P 10 30k 2k 890 read -q -P 11 20k 2k 891 read -q -P 12 40k 2k 892 EOF 893 } 894 895 _make_test_img -o extended_l2=on 1M 896 # Second and third writes in _concurrent_io() are independent and may finish in 897 # different order. So, filter offset out to match both possible variants. 898 _concurrent_io | $QEMU_IO | _filter_qemu_io | \ 899 sed -e 's/\(20480\|40960\)/OFFSET/' 900 _concurrent_verify | $QEMU_IO | _filter_qemu_io 901 902 ############################################################ 903 ############################################################ 904 ############################################################ 905 906 echo 907 echo "### Rebase of qcow2 images with subclusters ###" 908 echo 909 910 l2_offset=$((0x400000)) 911 912 # Check that rebase operation preserve holes between allocated subclusters 913 # within one cluster (i.e. does not allocate extra space). Check that the 914 # data is preserved as well. 915 # 916 # Base (new backing): -- -- -- ... -- -- -- 917 # Mid (old backing): -- 11 -- ... -- 22 -- 918 # Top: -- -- -- ... -- -- -- 919 920 echo "### Preservation of unallocated holes after rebase ###" 921 echo 922 923 echo "# create backing chain" 924 echo 925 926 TEST_IMG="$TEST_IMG.base" _make_test_img -o cluster_size=1M,extended_l2=on 1M 927 TEST_IMG="$TEST_IMG.mid" _make_test_img -o cluster_size=1M,extended_l2=on \ 928 -b "$TEST_IMG.base" -F qcow2 1M 929 TEST_IMG="$TEST_IMG.top" _make_test_img -o cluster_size=1M,extended_l2=on \ 930 -b "$TEST_IMG.mid" -F qcow2 1M 931 932 echo 933 echo "# fill old backing with data (separate subclusters within cluster)" 934 echo 935 936 $QEMU_IO -c "write -P 0x11 32k 32k" \ 937 -c "write -P 0x22 $(( 30 * 32 ))k 32k" \ 938 "$TEST_IMG.mid" | _filter_qemu_io 939 940 echo 941 echo "# rebase topmost image onto the new backing" 942 echo 943 944 $QEMU_IMG rebase -b "$TEST_IMG.base" -F qcow2 "$TEST_IMG.top" 945 946 echo "# verify that data is read the same before and after rebase" 947 echo 948 949 $QEMU_IO -c "read -P 0x00 0 32k" \ 950 -c "read -P 0x11 32k 32k" \ 951 -c "read -P 0x00 64k $(( 28 * 32 ))k" \ 952 -c "read -P 0x22 $(( 30 * 32 ))k 32k" \ 953 -c "read -P 0x00 $(( 31 * 32 ))k 32k" \ 954 "$TEST_IMG.top" | _filter_qemu_io 955 956 echo 957 echo "# verify that only selected subclusters remain allocated" 958 echo 959 960 $QEMU_IMG map "$TEST_IMG.top" | _filter_testdir 961 962 echo 963 echo "# verify image bitmap" 964 echo 965 966 TEST_IMG="$TEST_IMG.top" alloc="1 30" zero="" _verify_l2_bitmap 0 967 968 # Check that rebase with compression works correctly with images containing 969 # subclusters. When compression is enabled and we allocate a new 970 # subcluster within the target (overlay) image, we expect the entire cluster 971 # containing that subcluster to become compressed. 972 # 973 # Here we expect 1st and 3rd clusters of the top (overlay) image to become 974 # compressed after the rebase, while cluster 2 to remain unallocated and 975 # be read from the base (new backing) image. 976 # 977 # Base (new backing): |-- -- .. -- --|11 11 .. 11 11|-- -- .. -- --| 978 # Mid (old backing): |-- -- .. -- 22|-- -- .. -- --|33 -- .. -- --| 979 # Top: |-- -- .. -- --|-- -- -- -- --|-- -- .. -- --| 980 981 echo 982 echo "### Rebase with compression for images with subclusters ###" 983 echo 984 985 echo "# create backing chain" 986 echo 987 988 TEST_IMG="$TEST_IMG.base" _make_test_img -o cluster_size=1M,extended_l2=on 3M 989 TEST_IMG="$TEST_IMG.mid" _make_test_img -o cluster_size=1M,extended_l2=on \ 990 -b "$TEST_IMG.base" -F qcow2 3M 991 TEST_IMG="$TEST_IMG.top" _make_test_img -o cluster_size=1M,extended_l2=on \ 992 -b "$TEST_IMG.mid" -F qcow2 3M 993 994 echo 995 echo "# fill old and new backing with data" 996 echo 997 998 $QEMU_IO -c "write -P 0x11 1M 1M" "$TEST_IMG.base" | _filter_qemu_io 999 $QEMU_IO -c "write -P 0x22 $(( 31 * 32 ))k 32k" \ 1000 -c "write -P 0x33 $(( 64 * 32 ))k 32k" \ 1001 "$TEST_IMG.mid" | _filter_qemu_io 1002 1003 echo 1004 echo "# rebase topmost image onto the new backing, with compression" 1005 echo 1006 1007 $QEMU_IMG rebase -c -b "$TEST_IMG.base" -F qcow2 "$TEST_IMG.top" 1008 1009 echo "# verify that the 1st and 3rd clusters've become compressed" 1010 echo 1011 1012 $QEMU_IMG map --output=json "$TEST_IMG.top" | _filter_testdir 1013 1014 echo 1015 echo "# verify that data is read the same before and after rebase" 1016 echo 1017 1018 $QEMU_IO -c "read -P 0x22 $(( 31 * 32 ))k 32k" \ 1019 -c "read -P 0x11 1M 1M" \ 1020 -c "read -P 0x33 $(( 64 * 32 ))k 32k" \ 1021 "$TEST_IMG.top" | _filter_qemu_io 1022 1023 echo 1024 echo "# verify image bitmap" 1025 echo 1026 1027 # For compressed clusters bitmap is always 0. For unallocated cluster 1028 # there should be no entry at all, thus bitmap is also 0. 1029 TEST_IMG="$TEST_IMG.top" alloc="" zero="" _verify_l2_bitmap 0 1030 TEST_IMG="$TEST_IMG.top" alloc="" zero="" _verify_l2_bitmap 1 1031 TEST_IMG="$TEST_IMG.top" alloc="" zero="" _verify_l2_bitmap 2 1032 1033 # success, all done 1034 echo "*** done" 1035 rm -f $seq.full 1036 status=0 1037