generic: test MADV_POPULATE_READ with IO errors
[xfstests-dev.git] / tests / ceph / 001
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FS QA Test No. ceph/001
6 #
7 # Test remote copy operation (CEPH_OSD_OP_COPY_FROM) with several combinations
8 # of both object sizes and copy sizes.  It also uses several combinations of
9 # copy ranges.  For example, copying the 1st object in the src file into
10 # 1) the beginning (1st object) of dst file, 2) the end (last object) of dst
11 # file and 3) the middle of the dst file.
12 #
13 . ./common/preamble
14 _begin_fstest auto quick copy_range
15
16 # get standard environment
17 . common/filter
18 . common/attr
19 . common/reflink
20
21 # real QA test starts here
22 _supported_fs ceph
23
24 _require_xfs_io_command "copy_range"
25 _exclude_test_mount_option "test_dummy_encryption"
26 _require_attrs
27 _require_test
28
29 workdir=$TEST_DIR/test-$seq
30 rm -rf $workdir
31 mkdir $workdir
32
33 cluster_fsid=$(_ceph_get_cluster_fsid)
34 client_id=$(_ceph_get_client_id)
35 metrics_dir="$DEBUGFS_MNT/ceph/$cluster_fsid.$client_id/metrics"
36
37 check_range()
38 {
39         local file=$1
40         local off0=$2
41         local off1=$3
42         local val=$4
43         _read_range $file $off0 $off1 | grep -v -q $val
44         [ $? -eq 0 ] && echo "file $file is not '$val' in [ $off0 $off1 ]"
45 }
46
47 #
48 # The metrics file has the following fields:
49 #   1. item
50 #   2. total
51 #   3. avg_sz(bytes)
52 #   4. min_sz(bytes)
53 #   5. max_sz(bytes)
54 #   6. total_sz(bytes)
55 get_copyfrom_total_copies()
56 {
57         local total=0
58
59         if [ -d $metrics_dir ]; then
60                 total=$(grep copyfrom $metrics_dir/size | tr -s '[:space:]' | cut -d ' ' -f 2)
61         fi
62         echo $total
63 }
64 get_copyfrom_total_size()
65 {
66         local total=0
67
68         if [ -d $metrics_dir ]; then
69                 total=$(grep copyfrom $metrics_dir/size | tr -s '[:space:]' | cut -d ' ' -f 6)
70         fi
71         echo $total
72 }
73
74 # This function checks that the metrics file has the expected values for number
75 # of remote object copies and the total size of the copies.  For this, it
76 # expects a input:
77 #   $1 - initial number copies in metrics file (field 'total')
78 #   $2 - initial total size in bytes in metrics file (field 'total_sz')
79 #   $3 - object size used for copies
80 #   $4 - number of remote objects copied
81 check_copyfrom_metrics()
82 {
83         local c0=$1
84         local s0=$2
85         local objsz=$3
86         local copies=$4
87         local c1=$(get_copyfrom_total_copies)
88         local s1=$(get_copyfrom_total_size)
89         local hascopyfrom=$(_fs_options $TEST_DEV | grep "copyfrom")
90         local sum
91
92         if [ ! -d "$metrics_dir" ]; then
93                 return # skip metrics check if debugfs isn't mounted
94         fi
95         if [ -z "$hascopyfrom" ]; then
96                 return # ... or if we don't have copyfrom mount option
97         fi
98
99         sum=$(($c0+$copies))
100         if [ $sum -ne $c1 ]; then
101                 echo "Wrong number of remote copies.  Expected $sum, got $c1"
102         fi
103         sum=$(($s0+$copies*$objsz))
104         if [ $sum -ne $s1 ]; then
105                 echo "Wrong size of remote copies.  Expected $sum, got $s1"
106         fi
107 }
108
109 run_copy_range_tests()
110 {
111         total_copies=$(get_copyfrom_total_copies)
112         total_size=$(get_copyfrom_total_size)
113         objsz=$1
114         halfobj=$(($objsz / 2))
115         file="$workdir/file-$objsz"
116         copy="$workdir/copy-$objsz"
117         dest="$workdir/dest-$objsz"
118
119         # create files and set file layout, which needs to be done before
120         # writing any data
121         _ceph_create_file_layout $file $objsz 1 $objsz
122         _ceph_create_file_layout $copy $objsz 1 $objsz
123         _ceph_create_file_layout $dest $objsz 1 $objsz
124
125         # file containing 3 objects with 'aaaa|bbbb|cccc'
126         $XFS_IO_PROG -c "pwrite -S 0x61 0 $objsz" $file >> $seqres.full 2>&1
127         $XFS_IO_PROG -c "pwrite -S 0x62 $objsz $objsz" $file >> $seqres.full 2>&1
128         $XFS_IO_PROG -c "pwrite -S 0x63 $(($objsz * 2)) $objsz" $file >> $seqres.full 2>&1
129
130         echo "  Copy whole file (3 objects):"
131         echo "    aaaa|bbbb|cccc => aaaa|bbbb|cccc"
132         $XFS_IO_PROG -c "copy_range -s 0 -d 0 -l $(($objsz * 3)) $file" "$copy"
133         cmp $file $copy
134
135         echo "  Copy single object to beginning:"
136         # dest file with 3 objects with 'dddd|dddd|dddd'
137         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 3))" $dest >> $seqres.full 2>&1
138
139         echo "    dddd|dddd|dddd => aaaa|dddd|dddd"
140         $XFS_IO_PROG -c "copy_range -s 0 -d 0 -l $objsz $file" "$dest"
141         check_range $dest 0 $objsz 61
142         check_range $dest $objsz $(($objsz * 2)) 64
143
144         echo "    aaaa|dddd|dddd => bbbb|dddd|dddd"
145         $XFS_IO_PROG -c "copy_range -s $objsz -d 0 -l $objsz $file" "$dest"
146         check_range $dest 0 $objsz 62
147         check_range $dest $objsz $(($objsz * 2)) 64
148
149         echo "    bbbb|dddd|dddd => cccc|dddd|dddd"
150         $XFS_IO_PROG -c "copy_range -s $(($objsz * 2)) -d 0 -l $objsz $file" "$dest"
151         check_range $dest 0 $objsz 63
152         check_range $dest $objsz $(($objsz * 2)) 64
153
154         echo "  Copy single object to middle:"
155
156         echo "    cccc|dddd|dddd => cccc|aaaa|dddd"
157         $XFS_IO_PROG -c "copy_range -s 0 -d $objsz -l $objsz $file" "$dest"
158         check_range $dest 0 $objsz 63
159         check_range $dest $objsz $objsz 61
160         check_range $dest $(($objsz * 2)) $objsz 64
161
162         echo "    cccc|aaaa|dddd => cccc|bbbb|dddd"
163         $XFS_IO_PROG -c "copy_range -s $objsz -d $objsz -l $objsz $file" "$dest"
164         check_range $dest 0 $objsz 63
165         check_range $dest $objsz $objsz 62
166         check_range $dest $(($objsz * 2)) $objsz 64
167
168         echo "    cccc|bbbb|dddd => cccc|cccc|dddd"
169         $XFS_IO_PROG -c "copy_range -s $((objsz * 2)) -d $objsz -l $objsz $file" "$dest"
170         check_range $dest 0 $objsz 63
171         check_range $dest $objsz $objsz 63
172         check_range $dest $(($objsz * 2)) $objsz 64
173
174         echo "  Copy single object to end:"
175
176         echo "    cccc|cccc|dddd => cccc|cccc|aaaa"
177         $XFS_IO_PROG -c "copy_range -s 0 -d $(($objsz * 2)) -l $objsz $file" "$dest"
178         check_range $dest 0 $(($objsz * 2)) 63
179         check_range $dest $(($objsz * 2)) $objsz 61
180
181         echo "    cccc|cccc|aaaa => cccc|cccc|bbbb"
182         $XFS_IO_PROG -c "copy_range -s $objsz -d $(($objsz * 2)) -l $objsz $file" "$dest"
183         check_range $dest 0 $(($objsz * 2)) 63
184         check_range $dest $(($objsz * 2)) $objsz 62
185
186         echo "    cccc|cccc|aaaa => cccc|cccc|cccc"
187         $XFS_IO_PROG -c "copy_range -s $(($objsz * 2)) -d $(($objsz * 2)) -l $objsz $file" "$dest"
188         check_range $dest 0 $(($objsz * 3)) 63
189
190         echo "  Copy 2 objects to beginning:"
191
192         echo "    cccc|cccc|cccc => aaaa|bbbb|cccc"
193         $XFS_IO_PROG -c "copy_range -s 0 -d 0 -l $(($objsz * 2)) $file" "$dest"
194         cmp $file $dest
195
196         echo "    aaaa|bbbb|cccc => bbbb|cccc|cccc"
197         $XFS_IO_PROG -c "copy_range -s $objsz -d 0 -l $(($objsz * 2)) $file" "$dest"
198         check_range $dest 0 $objsz 62
199         check_range $dest $objsz $(($objsz * 2)) 63
200
201         echo "  Copy 2 objects to end:"
202
203         echo "    bbbb|cccc|cccc => bbbb|aaaa|bbbb"
204         $XFS_IO_PROG -c "copy_range -s 0 -d $objsz -l $(($objsz * 2)) $file" "$dest"
205         check_range $dest 0 $objsz 62
206         check_range $dest $objsz $objsz 61
207         check_range $dest $(($objsz * 2)) $objsz 62
208
209         echo "    bbbb|aaaa|bbbb => bbbb|bbbb|cccc"
210         $XFS_IO_PROG -c "copy_range -s $objsz -d $objsz -l $(($objsz * 2)) $file" "$dest"
211         check_range $dest 0 $(($objsz * 2)) 62
212         check_range $dest $(($objsz * 2)) $objsz 63
213
214         echo "  Append 1 object:"
215
216         echo "    bbbb|bbbb|cccc => bbbb|bbbb|cccc|aaaa"
217         $XFS_IO_PROG -c "copy_range -s 0 -d $(($objsz * 3)) -l $objsz $file" "$dest"
218         check_range $dest 0 $(($objsz * 2)) 62
219         check_range $dest $(($objsz * 2)) $objsz 63
220         check_range $dest $(($objsz * 3)) $objsz 61
221
222         echo "  Cross object boundary (no full object copy)"
223         echo "    dddd|dddd|dddd|dddd => ddaa|aadd|dddd|dddd"
224         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 4))" $dest >> $seqres.full 2>&1
225         $XFS_IO_PROG -c "copy_range -s 0 -d $halfobj -l $objsz $file" "$dest"
226         check_range $dest 0 $halfobj 64
227         check_range $dest $halfobj $objsz 61
228         check_range $dest $(($objsz + $halfobj)) $(($objsz * 2 + $halfobj)) 64
229
230         echo "    dddd|dddd|dddd|dddd => ddaa|bbdd|dddd|dddd"
231         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 4))" $dest >> $seqres.full 2>&1
232         $XFS_IO_PROG -c "copy_range -s $halfobj -d $halfobj -l $objsz $file" "$dest"
233         check_range $dest 0 $halfobj 64
234         check_range $dest $halfobj $halfobj 61
235         check_range $dest $objsz $halfobj 62
236         check_range $dest $(($objsz + $halfobj)) $(($objsz * 2 + $halfobj)) 64
237
238         echo "  Cross object boundaries (with full object copy)"
239         echo "    dddd|dddd|dddd|dddd => ddaa|bbbb|dddd|dddd"
240         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 4))" $dest >> $seqres.full 2>&1
241         $XFS_IO_PROG -c "copy_range -s $halfobj -d $halfobj -l $(($objsz + $halfobj)) $file" "$dest"
242         check_range $dest 0 $halfobj 64
243         check_range $dest $halfobj $halfobj 61
244         check_range $dest $objsz $objsz 62
245         check_range $dest $(($objsz * 2)) $(($objsz * 2)) 64
246
247         echo "    dddd|dddd|dddd|dddd => ddaa|bbbb|ccdd|dddd"
248         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 4))" $dest >> $seqres.full 2>&1
249         $XFS_IO_PROG -c "copy_range -s $halfobj -d $halfobj -l $(($objsz * 2)) $file" "$dest"
250         check_range $dest 0 $halfobj 64
251         check_range $dest $halfobj $halfobj 61
252         check_range $dest $objsz $objsz 62
253         check_range $dest $(($objsz * 2)) $halfobj 63
254         check_range $dest $(($objsz * 2 + $halfobj)) $(($objsz + $halfobj)) 64
255
256         echo "    dddd|dddd|dddd|dddd => dddd|aaaa|bbdd|dddd"
257         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 4))" $dest >> $seqres.full 2>&1
258         $XFS_IO_PROG -c "copy_range -s 0 -d $objsz -l $(($objsz + $halfobj)) $file" "$dest"
259         check_range $dest 0 $objsz 64
260         check_range $dest $objsz $objsz 61
261         check_range $dest $(($objsz * 2)) $halfobj 62
262         check_range $dest $(($objsz * 2 + $halfobj)) $(($objsz + $halfobj)) 64
263
264         echo "  Cross object boundaries (with 2 full object copies)"
265         echo "    dddd|dddd|dddd|dddd => ddaa|aabb|bbcc|ccdd"
266         $XFS_IO_PROG -c "pwrite -S 0x64 0 $(($objsz * 4))" $dest >> $seqres.full 2>&1
267         $XFS_IO_PROG -c "copy_range -s 0 -d $halfobj -l $(($objsz * 3)) $file" "$dest"
268         check_range $dest 0 $halfobj 64
269         check_range $dest $halfobj $objsz 61
270         check_range $dest $(($objsz + $halfobj)) $objsz 62
271         check_range $dest $(($objsz * 2 + $halfobj)) $objsz 63
272         check_range $dest $(($objsz * 3 + $halfobj)) $halfobj 64
273
274         # Confirm that we've done a total of 24 object copies
275         check_copyfrom_metrics $total_copies $total_size $objsz 24
276 }
277
278 echo "Object size: 65536" # CEPH_MIN_STRIPE_UNIT
279 run_copy_range_tests 65536
280 echo "Object size: 1M"
281 run_copy_range_tests 1048576
282 echo "Object size: 4M"
283 run_copy_range_tests 4194304
284 # the max object size is 1TB, but by default OSDs only accept a max of 128M objects
285 echo "Object size: 128M"
286 run_copy_range_tests 134217728
287
288 # success, all done
289 status=0
290 exit