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

154 (19006B)


      1#!/usr/bin/env bash
      2# group: rw auto backing quick
      3#
      4# qcow2 specific bdrv_pwrite_zeroes tests with backing files (complements 034)
      5#
      6# Copyright (C) 2016-2017 Red Hat, Inc.
      7#
      8# This program is free software; you can redistribute it and/or modify
      9# it under the terms of the GNU General Public License as published by
     10# the Free Software Foundation; either version 2 of the License, or
     11# (at your option) any later version.
     12#
     13# This program is distributed in the hope that it will be useful,
     14# but WITHOUT ANY WARRANTY; without even the implied warranty of
     15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16# GNU General Public License for more details.
     17#
     18# You should have received a copy of the GNU General Public License
     19# along with this program.  If not, see <http://www.gnu.org/licenses/>.
     20#
     21
     22# creator
     23owner=kwolf@redhat.com
     24
     25seq=`basename $0`
     26echo "QA output created by $seq"
     27
     28status=1	# failure is the default!
     29
     30_cleanup()
     31{
     32	_cleanup_test_img
     33}
     34trap "_cleanup; exit \$status" 0 1 2 3 15
     35
     36# get standard environment, filters and checks
     37. ./common.rc
     38. ./common.filter
     39
     40_supported_fmt qcow2
     41_supported_proto file fuse
     42_supported_os Linux
     43
     44CLUSTER_SIZE=4k
     45size=$((128 * 1024 * 1024))
     46
     47# This test requires zero clusters, added in v3 images
     48_unsupported_imgopts compat=0.10
     49
     50echo
     51echo == backing file contains zeros ==
     52
     53CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
     54_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
     55
     56# Make sure that the whole cluster is allocated even for partial write_zeroes
     57# when the backing file contains zeros
     58
     59# X = non-zero data sector in backing file
     60# - = sector unallocated in whole backing chain
     61# 0 = sector touched by write_zeroes request
     62
     63# 1. Tail unaligned:    00 00 -- --
     64# 2. Head unaligned:    -- -- 00 00
     65# 3. Both unaligned:    -- 00 00 --
     66# 4. Both, 2 clusters:  -- -- -- 00 | 00 -- -- --
     67
     68$QEMU_IO -c "write -z 0 2k" "$TEST_IMG" | _filter_qemu_io
     69$QEMU_IO -c "write -z 10k 2k" "$TEST_IMG" | _filter_qemu_io
     70$QEMU_IO -c "write -z 17k 2k" "$TEST_IMG" | _filter_qemu_io
     71$QEMU_IO -c "write -z 27k 2k" "$TEST_IMG" | _filter_qemu_io
     72$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
     73
     74echo
     75echo == backing file contains non-zero data before write_zeroes ==
     76
     77CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
     78_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
     79
     80# Single cluster; non-zero data at the cluster start
     81# ... | XX -- 00 -- | ...
     82$QEMU_IO -c "write -P 0x11 32k 1k" "$TEST_IMG.base" | _filter_qemu_io
     83$QEMU_IO -c "write -z 34k 1k" "$TEST_IMG" | _filter_qemu_io
     84$QEMU_IO -c "read -P 0x11 32k 1k" "$TEST_IMG" | _filter_qemu_io
     85$QEMU_IO -c "read -P 0 33k 3k" "$TEST_IMG" | _filter_qemu_io
     86
     87# Single cluster; non-zero data exists, but not at the cluster start
     88# ... | -- XX 00 -- | ...
     89$QEMU_IO -c "write -P 0x11 65k 1k" "$TEST_IMG.base" | _filter_qemu_io
     90$QEMU_IO -c "write -z 66k 1k" "$TEST_IMG" | _filter_qemu_io
     91$QEMU_IO -c "read -P 0x11 65k 1k" "$TEST_IMG" | _filter_qemu_io
     92$QEMU_IO -c "read -P 0 64k 1k" "$TEST_IMG" | _filter_qemu_io
     93$QEMU_IO -c "read -P 0 66k 2k" "$TEST_IMG" | _filter_qemu_io
     94
     95$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
     96
     97echo
     98echo == backing file contains non-zero data after write_zeroes ==
     99
    100CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    101_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    102
    103# Single cluster; non-zero data directly after request
    104# ... | -- 00 XX -- | ...
    105$QEMU_IO -c "write -P 0x11 34k 1k" "$TEST_IMG.base" | _filter_qemu_io
    106$QEMU_IO -c "write -z 33k 1k" "$TEST_IMG" | _filter_qemu_io
    107$QEMU_IO -c "read -P 0 32k 2k" "$TEST_IMG" | _filter_qemu_io
    108$QEMU_IO -c "read -P 0x11 34k 1k" "$TEST_IMG" | _filter_qemu_io
    109$QEMU_IO -c "read -P 0 35k 1k" "$TEST_IMG" | _filter_qemu_io
    110
    111# Single cluster; non-zero data exists, but not directly after request
    112# ... | -- 00 -- XX | ...
    113$QEMU_IO -c "write -P 0x11 43k 1k" "$TEST_IMG.base" | _filter_qemu_io
    114$QEMU_IO -c "write -z 41k 1k" "$TEST_IMG" | _filter_qemu_io
    115$QEMU_IO -c "read -P 0x11 43k 1k" "$TEST_IMG" | _filter_qemu_io
    116$QEMU_IO -c "read -P 0 40k 3k" "$TEST_IMG" | _filter_qemu_io
    117
    118$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    119
    120echo
    121echo == write_zeroes covers non-zero data ==
    122
    123CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    124_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    125
    126# non-zero data at front of request
    127# Backing file: -- XX -- --
    128# Active layer: -- 00 00 --
    129
    130$QEMU_IO -c "write -P 0x11 5k 1k" "$TEST_IMG.base" | _filter_qemu_io
    131$QEMU_IO -c "write -z 5k 2k" "$TEST_IMG" | _filter_qemu_io
    132$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io
    133
    134# non-zero data at end of request
    135# Backing file: -- -- XX --
    136# Active layer: -- 00 00 --
    137
    138$QEMU_IO -c "write -P 0x11 14k 1k" "$TEST_IMG.base" | _filter_qemu_io
    139$QEMU_IO -c "write -z 13k 2k" "$TEST_IMG" | _filter_qemu_io
    140$QEMU_IO -c "read -P 0 12k 4k" "$TEST_IMG" | _filter_qemu_io
    141
    142# non-zero data matches size of request
    143# Backing file: -- XX XX --
    144# Active layer: -- 00 00 --
    145
    146$QEMU_IO -c "write -P 0x11 21k 2k" "$TEST_IMG.base" | _filter_qemu_io
    147$QEMU_IO -c "write -z 21k 2k" "$TEST_IMG" | _filter_qemu_io
    148$QEMU_IO -c "read -P 0 20k 4k" "$TEST_IMG" | _filter_qemu_io
    149
    150# non-zero data smaller than request
    151# Backing file: -- -X X- --
    152# Active layer: -- 00 00 --
    153
    154$QEMU_IO -c "write -P 0x11 30208 1k" "$TEST_IMG.base" | _filter_qemu_io
    155$QEMU_IO -c "write -z 29k 2k" "$TEST_IMG" | _filter_qemu_io
    156$QEMU_IO -c "read -P 0 28k 4k" "$TEST_IMG" | _filter_qemu_io
    157
    158$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    159
    160echo
    161echo == spanning two clusters, non-zero before request ==
    162
    163CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    164_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    165
    166# Two clusters; non-zero data before request:
    167# 1. At cluster start:          32k: XX -- -- 00 | 00 -- -- --
    168# 2. Between unallocated space: 48k: -- XX -- 00 | 00 -- -- --
    169# 3. Directly before request:   64k: -- -- XX 00 | 00 -- -- --
    170
    171$QEMU_IO -c "write -P 0x11 32k 1k" "$TEST_IMG.base" | _filter_qemu_io
    172$QEMU_IO -c "write -z 35k 2k" "$TEST_IMG" | _filter_qemu_io
    173$QEMU_IO -c "read -P 0x11 32k 1k" "$TEST_IMG" | _filter_qemu_io
    174$QEMU_IO -c "read -P 0 33k 7k" "$TEST_IMG" | _filter_qemu_io
    175
    176$QEMU_IO -c "write -P 0x11 49k 1k" "$TEST_IMG.base" | _filter_qemu_io
    177$QEMU_IO -c "write -z 51k 2k" "$TEST_IMG" | _filter_qemu_io
    178$QEMU_IO -c "read -P 0 48k 1k" "$TEST_IMG" | _filter_qemu_io
    179$QEMU_IO -c "read -P 0x11 49k 1k" "$TEST_IMG" | _filter_qemu_io
    180$QEMU_IO -c "read -P 0 50k 6k" "$TEST_IMG" | _filter_qemu_io
    181
    182$QEMU_IO -c "write -P 0x11 66k 1k" "$TEST_IMG.base" | _filter_qemu_io
    183$QEMU_IO -c "write -z 67k 2k" "$TEST_IMG" | _filter_qemu_io
    184$QEMU_IO -c "read -P 0 64k 2k" "$TEST_IMG" | _filter_qemu_io
    185$QEMU_IO -c "read -P 0x11 66k 1k" "$TEST_IMG" | _filter_qemu_io
    186$QEMU_IO -c "read -P 0 67k 5k" "$TEST_IMG" | _filter_qemu_io
    187
    188$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    189
    190echo
    191echo == spanning two clusters, non-zero after request ==
    192
    193CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    194_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    195
    196# Two clusters; non-zero data after request:
    197# 1. Directly after request:    32k: -- -- -- 00 | 00 XX -- --
    198# 2. Between unallocated space: 48k: -- -- -- 00 | 00 -- XX --
    199# 3. At cluster end:            64k: -- -- -- 00 | 00 -- -- XX
    200
    201$QEMU_IO -c "write -P 0x11 37k 1k" "$TEST_IMG.base" | _filter_qemu_io
    202$QEMU_IO -c "write -z 35k 2k" "$TEST_IMG" | _filter_qemu_io
    203$QEMU_IO -c "read -P 0 32k 5k" "$TEST_IMG" | _filter_qemu_io
    204$QEMU_IO -c "read -P 0x11 37k 1k" "$TEST_IMG" | _filter_qemu_io
    205$QEMU_IO -c "read -P 0 38k 2k" "$TEST_IMG" | _filter_qemu_io
    206
    207$QEMU_IO -c "write -P 0x11 54k 1k" "$TEST_IMG.base" | _filter_qemu_io
    208$QEMU_IO -c "write -z 51k 2k" "$TEST_IMG" | _filter_qemu_io
    209$QEMU_IO -c "read -P 0 48k 6k" "$TEST_IMG" | _filter_qemu_io
    210$QEMU_IO -c "read -P 0x11 54k 1k" "$TEST_IMG" | _filter_qemu_io
    211$QEMU_IO -c "read -P 0 55k 1k" "$TEST_IMG" | _filter_qemu_io
    212
    213$QEMU_IO -c "write -P 0x11 71k 1k" "$TEST_IMG.base" | _filter_qemu_io
    214$QEMU_IO -c "write -z 67k 2k" "$TEST_IMG" | _filter_qemu_io
    215$QEMU_IO -c "read -P 0 64k 7k" "$TEST_IMG" | _filter_qemu_io
    216$QEMU_IO -c "read -P 0x11 71k 1k" "$TEST_IMG" | _filter_qemu_io
    217
    218$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    219
    220echo
    221echo == spanning two clusters, partially overwriting backing file ==
    222
    223CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    224_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    225
    226# Backing file: -- -- XX XX | XX XX -- --
    227# Active layer: -- -- XX 00 | 00 XX -- --
    228
    229$QEMU_IO -c "write -P 0x11 2k 4k" "$TEST_IMG.base" | _filter_qemu_io
    230$QEMU_IO -c "write -z 3k 2k" "$TEST_IMG" | _filter_qemu_io
    231$QEMU_IO -c "read -P 0 0k 2k" "$TEST_IMG" | _filter_qemu_io
    232$QEMU_IO -c "read -P 0x11 2k 1k" "$TEST_IMG" | _filter_qemu_io
    233$QEMU_IO -c "read -P 0 3k 2k" "$TEST_IMG" | _filter_qemu_io
    234$QEMU_IO -c "read -P 0x11 5k 1k" "$TEST_IMG" | _filter_qemu_io
    235$QEMU_IO -c "read -P 0 6k 2k" "$TEST_IMG" | _filter_qemu_io
    236
    237$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    238
    239echo
    240echo == spanning multiple clusters, non-zero in first cluster ==
    241
    242CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    243_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    244
    245# Backing file: 64k: XX XX -- -- | -- -- -- -- | -- -- -- --
    246# Active layer: 64k: XX XX 00 00 | 00 00 00 00 | 00 -- -- --
    247
    248$QEMU_IO -c "write -P 0x11 64k 2k" "$TEST_IMG.base" | _filter_qemu_io
    249$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
    250$QEMU_IO -c "read -P 0x11 64k 2k" "$TEST_IMG" | _filter_qemu_io
    251$QEMU_IO -c "read -P 0 66k 10k" "$TEST_IMG" | _filter_qemu_io
    252
    253$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    254
    255echo
    256echo == spanning multiple clusters, non-zero in intermediate cluster ==
    257
    258CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    259_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    260
    261# Backing file: 64k: -- -- -- -- | -- XX XX -- | -- -- -- --
    262# Active layer: 64k: -- -- 00 00 | 00 00 00 00 | 00 -- -- --
    263
    264$QEMU_IO -c "write -P 0x11 69k 2k" "$TEST_IMG.base" | _filter_qemu_io
    265$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
    266$QEMU_IO -c "read -P 0 64k 12k" "$TEST_IMG" | _filter_qemu_io
    267
    268$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    269
    270echo
    271echo == spanning multiple clusters, non-zero in final cluster ==
    272
    273CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    274_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    275
    276# Backing file: 64k: -- -- -- -- | -- -- -- -- | -- -- XX XX
    277# Active layer: 64k: -- -- 00 00 | 00 00 00 00 | 00 -- XX XX
    278
    279$QEMU_IO -c "write -P 0x11 74k 2k" "$TEST_IMG.base" | _filter_qemu_io
    280$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
    281$QEMU_IO -c "read -P 0 64k 10k" "$TEST_IMG" | _filter_qemu_io
    282$QEMU_IO -c "read -P 0x11 74k 2k" "$TEST_IMG" | _filter_qemu_io
    283
    284$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    285
    286echo
    287echo == spanning multiple clusters, partially overwriting backing file ==
    288
    289CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size
    290_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
    291
    292# Backing file: 64k: -- XX XX XX | XX XX XX XX | XX XX XX --
    293# Active layer: 64k: -- XX 00 00 | 00 00 00 00 | 00 XX XX --
    294
    295$QEMU_IO -c "write -P 0x11 65k 10k" "$TEST_IMG.base" | _filter_qemu_io
    296$QEMU_IO -c "write -z 66k 7k" "$TEST_IMG" | _filter_qemu_io
    297$QEMU_IO -c "read -P 0 64k 1k" "$TEST_IMG" | _filter_qemu_io
    298$QEMU_IO -c "read -P 0x11 65k 1k" "$TEST_IMG" | _filter_qemu_io
    299$QEMU_IO -c "read -P 0 66k 7k" "$TEST_IMG" | _filter_qemu_io
    300$QEMU_IO -c "read -P 0x11 73k 2k" "$TEST_IMG" | _filter_qemu_io
    301$QEMU_IO -c "read -P 0 75k 1k" "$TEST_IMG" | _filter_qemu_io
    302
    303$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    304
    305echo
    306echo == unaligned image tail cluster, no allocation needed ==
    307
    308# With no backing file, write to all or part of unallocated partial cluster
    309# will mark the cluster as zero, but does not allocate.
    310# Re-create the image each time to get back to unallocated clusters.
    311
    312# Write at the front: sector-wise, the request is: 128m... | 00 -- -- --
    313_make_test_img $((size + 2048))
    314$QEMU_IO -c "write -z $size 512" "$TEST_IMG" | _filter_qemu_io
    315$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    316$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    317
    318# Write at the back: sector-wise, the request is: 128m... | -- -- -- 00
    319_make_test_img $((size + 2048))
    320$QEMU_IO -c "write -z $((size + 1536)) 512" "$TEST_IMG" | _filter_qemu_io
    321$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    322$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    323
    324# Write at middle: sector-wise, the request is: 128m... | -- 00 00 --
    325_make_test_img $((size + 2048))
    326$QEMU_IO -c "write -z $((size + 512)) 1024" "$TEST_IMG" | _filter_qemu_io
    327$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    328$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    329
    330# Write entire cluster: sector-wise, the request is: 128m... | 00 00 00 00
    331_make_test_img $((size + 2048))
    332$QEMU_IO -c "write -z $size 2048" "$TEST_IMG" | _filter_qemu_io
    333$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    334$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    335
    336# Repeat with backing file holding unallocated cluster.
    337CLUSTER_SIZE=2048 TEST_IMG="$TEST_IMG.base" _make_test_img $((size + 1024))
    338
    339# Write at the front: sector-wise, the request is:
    340# backing: 128m... | -- --
    341# active:  128m... | 00 -- -- --
    342_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    343$QEMU_IO -c "write -z $size 512" "$TEST_IMG" | _filter_qemu_io
    344$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    345$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    346
    347# Write at the back: sector-wise, the request is:
    348# backing: 128m... | -- --
    349# active:  128m... | -- -- -- 00
    350_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    351$QEMU_IO -c "write -z $((size + 1536)) 512" "$TEST_IMG" | _filter_qemu_io
    352$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    353$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    354
    355# Write at middle: sector-wise, the request is:
    356# backing: 128m... | -- --
    357# active:  128m... | -- 00 00 --
    358_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    359$QEMU_IO -c "write -z $((size + 512)) 1024" "$TEST_IMG" | _filter_qemu_io
    360$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    361$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    362
    363# Write entire cluster: sector-wise, the request is:
    364# backing: 128m... | -- --
    365# active:  128m... | 00 00 00 00
    366_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    367$QEMU_IO -c "write -z $size 2048" "$TEST_IMG" | _filter_qemu_io
    368$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    369$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    370
    371# Repeat with backing file holding zero'd cluster
    372$QEMU_IO -c "write -z $size 512" "$TEST_IMG.base" | _filter_qemu_io
    373
    374# Write at the front: sector-wise, the request is:
    375# backing: 128m... | 00 00
    376# active:  128m... | 00 -- -- --
    377_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    378$QEMU_IO -c "write -z $size 512" "$TEST_IMG" | _filter_qemu_io
    379$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    380$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    381
    382# Write at the back: sector-wise, the request is:
    383# backing: 128m... | 00 00
    384# active:  128m... | -- -- -- 00
    385_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    386$QEMU_IO -c "write -z $((size + 1536)) 512" "$TEST_IMG" | _filter_qemu_io
    387$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    388$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    389
    390# Write at middle: sector-wise, the request is:
    391# backing: 128m... | 00 00
    392# active:  128m... | -- 00 00 --
    393_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    394$QEMU_IO -c "write -z $((size + 512)) 1024" "$TEST_IMG" | _filter_qemu_io
    395$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    396$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    397
    398# Write entire cluster: sector-wise, the request is:
    399# backing: 128m... | 00 00
    400# active:  128m... | 00 00 00 00
    401_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    402$QEMU_IO -c "write -z $size 2048" "$TEST_IMG" | _filter_qemu_io
    403$QEMU_IO -c "alloc $size 2048" "$TEST_IMG" | _filter_qemu_io
    404$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    405
    406# A preallocated cluster maintains its allocation, whether it stays as
    407# data due to a partial write:
    408# Convert 128m... | XX XX => ... | XX 00
    409_make_test_img $((size + 1024))
    410$QEMU_IO -c "write -P 1 $((size)) 1024" "$TEST_IMG" | _filter_qemu_io
    411$QEMU_IO -c "write -z $((size + 512)) 512" "$TEST_IMG" | _filter_qemu_io
    412$QEMU_IO -c "read -P 1 $((size)) 512" "$TEST_IMG" | _filter_qemu_io
    413$QEMU_IO -c "read -P 0 $((size + 512)) 512" "$TEST_IMG" | _filter_qemu_io
    414$QEMU_IO -c "alloc $size 1024" "$TEST_IMG" | _filter_qemu_io
    415$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    416
    417# or because it is the entire cluster and can use the zero flag:
    418# Convert 128m... | XX XX => ... | 00 00
    419$QEMU_IO -c "write -z $((size)) 1024" "$TEST_IMG" | _filter_qemu_io
    420$QEMU_IO -c "alloc $size 1024" "$TEST_IMG" | _filter_qemu_io
    421$QEMU_IO -c "read -P 0 $size 1024" "$TEST_IMG" | _filter_qemu_io
    422$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    423
    424echo
    425echo == unaligned image tail cluster, allocation required ==
    426
    427# Write beyond backing file must COW
    428# Backing file: 128m... | XX --
    429# Active layer: 128m... | -- -- 00 --
    430CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $((size + 1024))
    431_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    432$QEMU_IO -c "write -P 1 $((size)) 512" "$TEST_IMG.base" | _filter_qemu_io
    433$QEMU_IO -c "write -z $((size + 1024)) 512" "$TEST_IMG" | _filter_qemu_io
    434$QEMU_IO -c "read -P 1 $((size)) 512" "$TEST_IMG" | _filter_qemu_io
    435$QEMU_IO -c "read -P 0 $((size + 512)) 1536" "$TEST_IMG" | _filter_qemu_io
    436$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    437
    438# Writes at boundaries of (partial) cluster must not lose mid-cluster data
    439# Backing file: 128m: ... | -- XX
    440# Active layer: 128m: ... | 00 -- -- 00
    441CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $((size + 1024))
    442_make_test_img -b "$TEST_IMG.base" -F $IMGFMT $((size + 2048))
    443$QEMU_IO -c "write -P 1 $((size + 512)) 512" "$TEST_IMG.base" | _filter_qemu_io
    444$QEMU_IO -c "write -z $((size)) 512" "$TEST_IMG" | _filter_qemu_io
    445$QEMU_IO -c "read -P 0 $((size)) 512" "$TEST_IMG" | _filter_qemu_io
    446$QEMU_IO -c "read -P 1 $((size + 512)) 512" "$TEST_IMG" | _filter_qemu_io
    447$QEMU_IO -c "read -P 0 $((size + 1024)) 1024" "$TEST_IMG" | _filter_qemu_io
    448$QEMU_IO -c "write -z $((size + 1536)) 512" "$TEST_IMG" | _filter_qemu_io
    449$QEMU_IO -c "read -P 0 $((size)) 512" "$TEST_IMG" | _filter_qemu_io
    450$QEMU_IO -c "read -P 1 $((size + 512)) 512" "$TEST_IMG" | _filter_qemu_io
    451$QEMU_IO -c "read -P 0 $((size + 1024)) 1024" "$TEST_IMG" | _filter_qemu_io
    452$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
    453
    454# success, all done
    455echo "*** done"
    456rm -f $seq.full
    457status=0