2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
5 # FS QA Test No. ceph/001
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.
14 _begin_fstest auto quick copy_range
16 # get standard environment
21 # real QA test starts here
24 _require_xfs_io_command "copy_range"
25 _exclude_test_mount_option "test_dummy_encryption"
29 workdir=$TEST_DIR/test-$seq
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"
43 _read_range $file $off0 $off1 | grep -v -q $val
44 [ $? -eq 0 ] && echo "file $file is not '$val' in [ $off0 $off1 ]"
48 # The metrics file has the following fields:
55 get_copyfrom_total_copies()
59 if [ -d $metrics_dir ]; then
60 total=$(grep copyfrom $metrics_dir/size | tr -s '[:space:]' | cut -d ' ' -f 2)
64 get_copyfrom_total_size()
68 if [ -d $metrics_dir ]; then
69 total=$(grep copyfrom $metrics_dir/size | tr -s '[:space:]' | cut -d ' ' -f 6)
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
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()
87 local c1=$(get_copyfrom_total_copies)
88 local s1=$(get_copyfrom_total_size)
89 local hascopyfrom=$(_fs_options $TEST_DEV | grep "copyfrom")
92 if [ ! -d "$metrics_dir" ]; then
93 return # skip metrics check if debugfs isn't mounted
95 if [ -z "$hascopyfrom" ]; then
96 return # ... or if we don't have copyfrom mount option
100 if [ $sum -ne $c1 ]; then
101 echo "Wrong number of remote copies. Expected $sum, got $c1"
103 sum=$(($s0+$copies*$objsz))
104 if [ $sum -ne $s1 ]; then
105 echo "Wrong size of remote copies. Expected $sum, got $s1"
109 run_copy_range_tests()
111 total_copies=$(get_copyfrom_total_copies)
112 total_size=$(get_copyfrom_total_size)
114 halfobj=$(($objsz / 2))
115 file="$workdir/file-$objsz"
116 copy="$workdir/copy-$objsz"
117 dest="$workdir/dest-$objsz"
119 # create files and set file layout, which needs to be done before
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
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
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"
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
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
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
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
154 echo " Copy single object to middle:"
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
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
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
174 echo " Copy single object to end:"
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
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
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
190 echo " Copy 2 objects to beginning:"
192 echo " cccc|cccc|cccc => aaaa|bbbb|cccc"
193 $XFS_IO_PROG -c "copy_range -s 0 -d 0 -l $(($objsz * 2)) $file" "$dest"
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
201 echo " Copy 2 objects to end:"
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
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
214 echo " Append 1 object:"
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
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
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
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
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
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
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
274 # Confirm that we've done a total of 24 object copies
275 check_copyfrom_metrics $total_copies $total_size $objsz 24
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