qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

271 (32703B)


      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 # success, all done
    903 echo "*** done"
    904 rm -f $seq.full
    905 status=0