xref: /qemu/tests/qemu-iotests/020 (revision e3a6e0da)
1#!/usr/bin/env bash
2#
3# Commit changes to backing file
4#
5# Copyright (C) 2009 Red Hat, Inc.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19#
20
21# creator
22owner=kwolf@redhat.com
23
24seq=`basename $0`
25echo "QA output created by $seq"
26
27status=1	# failure is the default!
28
29_cleanup()
30{
31    _cleanup_test_img
32    _rm_test_img "$TEST_IMG.base"
33    _rm_test_img "$TEST_IMG.orig"
34
35    _rm_test_img "$TEST_DIR/subdir/t.$IMGFMT.base"
36    _rm_test_img "$TEST_DIR/subdir/t.$IMGFMT.mid"
37    _rm_test_img "$TEST_DIR/subdir/t.$IMGFMT"
38    rmdir "$TEST_DIR/subdir" &> /dev/null
39}
40trap "_cleanup; exit \$status" 0 1 2 3 15
41
42# get standard environment, filters and checks
43. ./common.rc
44. ./common.filter
45. ./common.pattern
46
47# Any format supporting backing files
48_supported_fmt qcow qcow2 vmdk qed
49_supported_proto file
50_unsupported_imgopts "subformat=monolithicFlat" \
51                     "subformat=twoGbMaxExtentFlat" \
52                     "subformat=twoGbMaxExtentSparse" \
53                     "subformat=streamOptimized"
54
55TEST_OFFSETS="0 4294967296"
56
57TEST_IMG_SAVE="$TEST_IMG"
58TEST_IMG="$TEST_IMG.base"
59
60_make_test_img 6G
61
62echo "Filling base image"
63echo
64
65for offset in $TEST_OFFSETS; do
66    # Some clusters with alternating backing file/image file reads
67    io writev $(( offset )) 512 1024 64
68
69    # Complete backing clusters
70    io writev $(( offset  + 64 * 1024))  65536 65536 1
71done
72_check_test_img
73
74echo "Creating test image with backing file"
75echo
76
77TEST_IMG="$TEST_IMG_SAVE"
78_make_test_img -b "$TEST_IMG.base" -F $IMGFMT 6G
79
80echo "Filling test image"
81echo
82
83for offset in $TEST_OFFSETS; do
84    # Some clusters with alternating backing file/image file reads
85    io writev $(( offset + 512 )) 512 1024 64
86
87    # Complete test image clusters
88    io writev $(( offset + 64 * 1024 + 65536))  65536 65536 1
89done
90_check_test_img
91
92$QEMU_IMG commit "$TEST_IMG"
93TEST_IMG="$TEST_IMG.base"
94
95echo "Reading from the backing file"
96echo
97
98for offset in $TEST_OFFSETS; do
99    # Some clusters with alternating backing file/image file reads
100    io readv $(( offset )) 512 1024 64
101    io readv $(( offset + 512 )) 512 1024 64
102
103    # Complete test image clusters
104    io readv $(( offset  + 64 * 1024))  65536 65536 1
105    io readv $(( offset + 64 * 1024 + 65536))  65536 65536 1
106
107    # Empty sectors
108    io_zero readv $(( offset + 64 * 1024 + 65536 * 4 )) 65536 65536 1
109done
110_check_test_img
111_cleanup
112TEST_IMG=$TEST_IMG_SAVE
113
114echo
115echo 'Testing failing commit'
116echo
117
118TEST_IMG="$TEST_IMG.base" _make_test_img 1M
119
120# Create an image with a null backing file to which committing will fail (with
121# ENOSPC so we can distinguish the result from some generic EIO which may be
122# generated anywhere in the block layer)
123backing="json:{'driver': '$IMGFMT',
124               'file': {
125                   'driver': 'blkdebug',
126                   'inject-error': [{
127                       'event': 'write_aio',
128                       'errno': 28,
129                       'once': true
130                   }],
131                   'image': {
132                       'driver': 'file',
133                       'filename': '$TEST_IMG.base'
134                   }}}"
135
136# Filter out newlines and collapse spaces
137backing=$(echo "$backing" | tr -d '\n' | tr -s ' ')
138
139_make_test_img -b "$backing" -F $IMGFMT
140
141# Just write anything so committing will not be a no-op
142$QEMU_IO -c 'writev 0 64k' "$TEST_IMG" | _filter_qemu_io
143
144$QEMU_IMG commit "$TEST_IMG"
145_cleanup
146
147
148echo
149echo 'Testing commit in sub-directory with relative filenames'
150echo
151
152pushd "$TEST_DIR" > /dev/null
153
154mkdir subdir
155
156TEST_IMG="subdir/t.$IMGFMT.base" _make_test_img 1M
157TEST_IMG="subdir/t.$IMGFMT.mid" _make_test_img -b "t.$IMGFMT.base" -F $IMGFMT
158TEST_IMG="subdir/t.$IMGFMT" _make_test_img -b "t.$IMGFMT.mid" -F $IMGFMT
159
160# Should work
161$QEMU_IMG commit -b "t.$IMGFMT.mid" "subdir/t.$IMGFMT"
162
163# Might theoretically work, but does not in practice (we have to
164# decide between this and the above; and since we always represent
165# backing file names as relative to the overlay, we go for the above)
166$QEMU_IMG commit -b "subdir/t.$IMGFMT.mid" "subdir/t.$IMGFMT" 2>&1 | \
167    _filter_imgfmt
168
169# This should work as well
170$QEMU_IMG commit -b "$TEST_DIR/subdir/t.$IMGFMT.mid" "subdir/t.$IMGFMT"
171
172popd > /dev/null
173
174# Now let's try with just absolute filenames
175# (This will not work with external data files, though, because when
176# using relative paths for those, qemu will always resolve them
177# relative to its CWD.  Therefore, it cannot find those data files now
178# that we left $TEST_DIR.)
179if _get_data_file '' > /dev/null; then
180    echo 'Image committed.' # Skip test
181else
182    $QEMU_IMG commit -b "$TEST_DIR/subdir/t.$IMGFMT.mid" \
183        "$TEST_DIR/subdir/t.$IMGFMT"
184fi
185
186# success, all done
187echo "*** done"
188rm -f $seq.full
189status=0
190