cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

271 (32704B)


      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
     24owner=berto@igalia.com
     25
     26seq="$(basename $0)"
     27echo "QA output created by $seq"
     28
     29here="$PWD"
     30status=1	# failure is the default!
     31
     32_cleanup()
     33{
     34        _cleanup_test_img
     35        rm -f "$TEST_IMG.raw"
     36}
     37trap "_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
     48l2_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
    150for 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
    228done
    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.
    238echo
    239echo '### Overwriting several clusters without COW ###'
    240echo
    241use_backing_file="no" _reset_img 1M
    242# Write cluster #0, subclusters #12-#31
    243alloc="$(seq 12 31)"; zero=""
    244_run_test sc=12 len=40k
    245
    246# Write cluster #1, subcluster #13
    247alloc="13"; zero=""
    248_run_test c=1 sc=13 len=2k
    249
    250# Zeroize cluster #2, subcluster #14
    251alloc="14"; zero=""
    252_run_test c=2 sc=14 len=2k
    253alloc=""; zero="14"
    254_run_test c=2 sc=14 len=2k cmd=zero
    255
    256# Write cluster #3, subclusters #0-#16
    257alloc="$(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
    261alloc="$(seq 12 31)"; zero=""
    262_run_test sc=12 len=192k
    263alloc="$(seq 0 31)"; zero=""
    264_verify_l2_bitmap 1
    265_verify_l2_bitmap 2
    266
    267alloc="$(seq 0 16)"; zero=""
    268_verify_l2_bitmap 3
    269
    270############################################################
    271############################################################
    272############################################################
    273
    274# Test different patterns of writing zeroes
    275for 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
    418done
    419
    420############################################################
    421############################################################
    422############################################################
    423
    424# Zero + unmap
    425for 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
    515done
    516
    517############################################################
    518############################################################
    519############################################################
    520
    521# Test qcow2_cluster_discard() with full and normal discards
    522for 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
    563done
    564
    565############################################################
    566############################################################
    567############################################################
    568
    569# Test that corrupted L2 entries are detected in both read and write
    570# operations
    571for 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
    668done
    669
    670############################################################
    671############################################################
    672############################################################
    673
    674echo
    675echo "### Detect and repair unaligned clusters ###"
    676echo
    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
    681echo "# 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
    686poke_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
    692echo "# 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
    698poke_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
    710echo
    711echo "### Image creation options ###"
    712echo
    713echo "# cluster_size < 16k"
    714_make_test_img -o extended_l2=on,cluster_size=8k 1M
    715
    716echo "# 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
    727echo "# 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
    734echo "# 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
    741echo
    742echo "### Image resizing with preallocation and backing files ###"
    743echo
    744# In this case the new subclusters must have the 'all zeroes' bit set
    745echo "# 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
    752echo "# 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
    758echo "# 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
    764echo
    765echo "### Image resizing with preallocation without backing files ###"
    766echo
    767# In this case the new subclusters must have the 'all zeroes' bit set
    768echo "# 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
    776echo "# 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
    783echo "# 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
    790echo
    791echo "### qemu-img measure ###"
    792echo
    793echo "# 512MB, extended_l2=off" # This needs one L2 table
    794$QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=off
    795echo "# 512MB, extended_l2=on"  # This needs two L2 tables
    796$QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=on
    797
    798echo "# 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
    800echo "# 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
    803echo "# 8k clusters" # This should fail
    804$QEMU_IMG measure --size 1M -O qcow2 -o cluster_size=8k,extended_l2=on
    805
    806echo "# 1024 TB" # Maximum allowed size with extended_l2=on and 64K clusters
    807$QEMU_IMG measure --size 1024T -O qcow2 -o extended_l2=on
    808echo "# 1025 TB" # This should fail
    809$QEMU_IMG measure --size 1025T -O qcow2 -o extended_l2=on
    810
    811echo
    812echo "### qemu-img amend ###"
    813echo
    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
    820echo
    821echo "### Test copy-on-write on an image with snapshots ###"
    822echo
    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.
    827alloc="13 18"; zero="7"
    828for 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"
    833done
    834
    835# Create a snapshot and set l2_offset to the new L2 table
    836$QEMU_IMG snapshot -c snap1 "$TEST_IMG"
    837l2_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"
    852alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 0
    853alloc="$(seq 10 18)"; zero="7" _verify_l2_bitmap 1
    854alloc="$(seq 13 20)"; zero="7" _verify_l2_bitmap 2
    855alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 3
    856alloc="$(seq 7 18)";  zero=""  _verify_l2_bitmap 4
    857alloc="$(seq 0 18)";  zero=""  _verify_l2_bitmap 5
    858alloc="13 18";  zero="7 15 16" _verify_l2_bitmap 6
    859alloc="18";        zero="7 13" _verify_l2_bitmap 7
    860alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 8
    861alloc="13 18";      zero="6 7" _verify_l2_bitmap 9
    862
    863echo
    864echo "### Test concurrent requests ###"
    865echo
    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).
    873cat <<EOF
    874open -o driver=$IMGFMT blkdebug::$TEST_IMG
    875break write_aio A
    876aio_write -P 10 30k 2k
    877wait_break A
    878aio_write -P 11 20k 2k
    879aio_write -P 12 40k 2k
    880resume A
    881aio_flush
    882EOF
    883}
    884
    885_concurrent_verify()
    886{
    887cat <<EOF
    888open -o driver=$IMGFMT $TEST_IMG
    889read -q -P 10 30k 2k
    890read -q -P 11 20k 2k
    891read -q -P 12 40k 2k
    892EOF
    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
    903echo "*** done"
    904rm -f $seq.full
    905status=0