Fixed the build error for riscv64 arch using gcc 13
[platform/upstream/cryptsetup.git] / tests / blockwise-compat
1 #!/bin/bash
2
3 # set _FORCE_LOCAL environment variable to run blockwise unit tests even on local
4 # nfs. Some tests will fail because nfs is eager to write for example 4095 bytes
5 # in O_DIRECT mode.
6
7 BW_UNIT=./unit-utils-io
8 STRACE=strace
9 MNT_DIR=./mnt_bwunit
10 LOCAL_FILE=./blockwise_localfile
11
12 # $1 path to scsi debug bdev
13 scsi_debug_teardown() {
14         local _tries=15;
15
16         while [ -b "$1" -a $_tries -gt 0 ]; do
17                 rmmod scsi_debug 2> /dev/null
18                 if [ -b "$1" ]; then
19                         sleep .1
20                         _tries=$((_tries-1))
21                 fi
22         done
23
24         test ! -b "$1" || rmmod scsi_debug
25 }
26
27 cleanup() {
28         if [ -d "$MNT_DIR" ] ; then
29             umount -f $MNT_DIR 2>/dev/null
30             rmdir $MNT_DIR 2>/dev/null
31         fi
32         rm -f $LOCAL_FILE 2> /dev/null
33         scsi_debug_teardown "$DEV" || exit 100
34 }
35
36 fail()
37 {
38         if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
39         cleanup
40         exit 100
41 }
42
43 fail_count()
44 {
45         echo "$MSG[FAIL]"
46         FAILS=$((FAILS+1))
47 }
48
49 warn_count()
50 {
51         echo "$MSG[WARNING]"
52         WARNS=$((WARNS+1))
53 }
54
55 skip()
56 {
57         echo "TEST SKIPPED: $1"
58         cleanup
59         exit 0
60 }
61
62 add_device() {
63         modprobe scsi_debug $@ delay=0
64         if [ $? -ne 0 ] ; then
65                 echo "This kernel seems to not support proper scsi_debug module, test skipped."
66                 exit 77
67         fi
68         DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
69         DEV="/dev/$DEV"
70         [ -b $DEV ] || fail "Cannot find $DEV."
71 }
72
73 falloc() {
74         dd if=/dev/zero of=$2 bs=1M count=$1 2> /dev/null
75 }
76
77 run_all_in_fs() {
78         for file in $(ls img_fs_*.img.xz) ; do
79             echo "Run tests in $file put on top block device."
80             xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
81             [ ! -d $MNT_DIR ] && mkdir $MNT_DIR
82             mount $DEV $MNT_DIR
83             if [ $? -ne 0 ]; then
84                 echo "Mounting image $file failed, skipped."
85                 continue;
86             fi
87             rm -rf $MNT_DIR/* 2>/dev/null
88             local tfile=$MNT_DIR/bwunit_tstfile
89             falloc $DEVSIZEMB $tfile || fail "enospc?"
90             local iobsize=$(stat -c "%o" $tfile)
91             test -n "$iobsize" -a $iobsize -gt 0 || fail
92             local oldbsize=$BSIZE
93             BSIZE=$iobsize
94             run_all $tfile
95             BSIZE=$oldbsize
96             umount $MNT_DIR
97         done
98 }
99
100 trunc_file() {
101         test $1 -eq 0 || truncate -c -s $1 $2 2>/dev/null || dd if=/dev/zero of=$2 bs=$1 count=1 2>/dev/null || fail "Failed to truncate test file $2."
102 }
103
104 RUN() {
105         local _res=$1
106         shift
107         local _dev=$1
108         shift
109         local _fn=$1
110         shift
111         local _type="bdev"
112         local _fsize=0
113
114         test -b $_dev || {
115                 _type="file"
116                 _fsize=$(stat -c "%s" $_dev)
117         }
118
119         case "$_res" in
120         P)
121                 MSG="Testing $_fn on $_type with params $@ [expecting TRUE]..."
122                 $BW_UNIT $_dev $_fn $@
123                 if [ $? -ne 0 ]; then
124                         if [ $_type = "file" ]; then
125                                 warn_count
126                         else
127                                 fail_count
128                         fi
129                         trunc_file $_fsize $_dev
130                         test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-pass.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
131                 else
132                         MSG="$MSG[OK]"
133                 fi
134                 ;;
135         F)
136                 MSG="Testing $_fn on $_type with params $@ [expecting FALSE]..."
137                 $BW_UNIT $_dev $_fn $@ 2> /dev/null
138                 if [ $? -eq 0 ]; then
139                         if [ $_type = "file" ]; then
140                                 warn_count
141                         else
142                                 fail_count
143                         fi
144                         trunc_file $_fsize $_dev
145                         test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-fail.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
146                 else
147                         MSG="$MSG[OK]"
148                 fi
149                 ;;
150         *)
151                 fail "Internal test error"
152                 ;;
153         esac
154
155         trunc_file $_fsize $_dev
156 }
157
158 run_all() {
159         if [ -b "$1" ]; then
160                 BD_FAIL="F"
161         else
162                 BD_FAIL="P"
163         fi
164
165         # buffer io support only blocksize aligned ios
166         # device/file fn_name length
167         RUN "P" $1 read_buffer $BSIZE
168         RUN "P" $1 read_buffer $((2*BSIZE))
169         RUN "F" $1 read_buffer $((BSIZE-1))
170         RUN "F" $1 read_buffer $((BSIZE+1))
171         RUN "P" $1 read_buffer 0
172
173         RUN "P" $1 write_buffer $BSIZE
174         RUN "P" $1 write_buffer $((2*BSIZE))
175
176         RUN "F" $1 write_buffer $((BSIZE-1))
177         RUN "F" $1 write_buffer $((BSIZE+1))
178         RUN "F" $1 write_buffer 0
179
180         # basic blockwise functions
181         # device/file fn_name length bsize
182         RUN "P" $1 read_blockwise 0 $BSIZE
183         RUN "P" $1 read_blockwise $((BSIZE)) $BSIZE
184         RUN "P" $1 read_blockwise $((BSIZE-1)) $BSIZE
185         RUN "P" $1 read_blockwise $((BSIZE+1)) $BSIZE
186         RUN "P" $1 read_blockwise $((DEVSIZE)) $BSIZE
187         RUN "P" $1 read_blockwise $((DEVSIZE-1)) $BSIZE
188         RUN "F" $1 read_blockwise $((DEVSIZE+1)) $BSIZE
189
190         RUN "P" $1 write_blockwise 0 $BSIZE
191         RUN "P" $1 write_blockwise $((BSIZE)) $BSIZE
192         RUN "P" $1 write_blockwise $((BSIZE-1)) $BSIZE
193         RUN "P" $1 write_blockwise $((BSIZE+1)) $BSIZE
194         RUN "P" $1 write_blockwise $((DEVSIZE)) $BSIZE
195         RUN "P" $1 write_blockwise $((DEVSIZE-1)) $BSIZE
196         RUN "$BD_FAIL" $1 write_blockwise $((DEVSIZE+1)) $BSIZE
197
198         # seek variant blockwise functions
199         # device/file fn_name length bsize offset
200         RUN "P" $1 read_lseek_blockwise 0 $BSIZE 0
201         RUN "P" $1 read_lseek_blockwise 0 $BSIZE 1
202         RUN "P" $1 read_lseek_blockwise 0 $BSIZE $((DEVSIZE))
203         # length = 0 is significant here
204         RUN "P" $1 read_lseek_blockwise 0 $BSIZE $((DEVSIZE+1))
205
206         # beginning of device
207         RUN "P" $1 read_lseek_blockwise 1 $BSIZE 0
208         RUN "P" $1 read_lseek_blockwise 1 $BSIZE 1
209         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE-1))
210         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE/2))
211
212         # somewhere in the 'middle'
213         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $BSIZE
214         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE+1))
215         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((2*BSIZE-1))
216         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE+BSIZE/2-1))
217
218         # cross-sector tests
219         RUN "P" $1 read_lseek_blockwise 2 $BSIZE $((BSIZE-1))
220         RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
221         RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
222         RUN "P" $1 read_lseek_blockwise 2 $BSIZE $((2*BSIZE-1))
223         RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
224         RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((2*BSIZE-1))
225
226         # including one whole sector
227         RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE))
228         RUN "P" $1 read_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
229         RUN "P" $1 read_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE-1))
230         RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
231         RUN "P" $1 read_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
232         RUN "P" $1 read_lseek_blockwise $((3*BSIZE-2)) $BSIZE $((BSIZE+1))
233
234         # hiting exactly the sector boundary
235         RUN "P" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE 1
236         RUN "P" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE $((BSIZE+1))
237         RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
238         RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
239
240         # device end
241         RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((DEVSIZE-1))
242         RUN "P" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+1))
243         RUN "P" $1 read_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE))
244         RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE-1))
245
246         # this must fail on both device and file
247         RUN "F" $1 read_lseek_blockwise 1 $BSIZE $((DEVSIZE))
248         RUN "F" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+2))
249         RUN "F" $1 read_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE+1))
250         RUN "F" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE))
251
252         RUN "P" $1 write_lseek_blockwise 0 $BSIZE 0
253         # TODO: this may pass but must not write a byte (write(0) is undefined).
254         #       Test it with underlying dm-error or phony read/write syscalls.
255         #       Skipping read is optimization.
256         # HINT: currently it performs useless write and read as well
257         RUN "P" $1 write_lseek_blockwise 0 $BSIZE 1
258         RUN "P" $1 write_lseek_blockwise 0 $BSIZE $BSIZE
259
260         # beginning of device
261         RUN "P" $1 write_lseek_blockwise 1 $BSIZE 0
262         RUN "P" $1 write_lseek_blockwise 1 $BSIZE 1
263         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE-1))
264         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE/2))
265
266         # somewhere in the 'middle'
267         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $BSIZE
268         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE+1))
269         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((2*BSIZE-1))
270         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE+BSIZE/2-1))
271
272         # cross-sector tests
273         RUN "P" $1 write_lseek_blockwise 2 $BSIZE $((BSIZE-1))
274         RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
275         RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
276         RUN "P" $1 write_lseek_blockwise 2 $BSIZE $((2*BSIZE-1))
277         RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
278         RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((2*BSIZE-1))
279
280         # including one whole sector
281         RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE))
282         RUN "P" $1 write_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
283         RUN "P" $1 write_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE-1))
284         RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
285         RUN "P" $1 write_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
286         RUN "P" $1 write_lseek_blockwise $((3*BSIZE-2)) $BSIZE $((BSIZE+1))
287
288         # hiting exactly the sector boundary
289         RUN "P" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE 1
290         RUN "P" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE $((BSIZE+1))
291         RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
292         RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
293
294         # device end
295         RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((DEVSIZE-1))
296         RUN "P" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+1))
297         RUN "P" $1 write_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE))
298         RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE-1))
299
300         # this must fail on device, but pass on file (which is unfortunate and maybe design mistake)
301         RUN "$BD_FAIL" $1 write_lseek_blockwise 1 $BSIZE $((DEVSIZE))
302         RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+2))
303         RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE+1))
304         RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE))
305 }
306
307 [ -n "$CRYPTSETUP_PATH" ] && skip "Cannot run this test with CRYPTSETUP_PATH set."
308
309 which $STRACE > /dev/null 2>&1 || unset STRACE
310 test -x $BW_UNIT || skip "Run \"make `basename $BW_UNIT`\" first"
311
312 FAILS=0
313 WARNS=0
314 DEVSIZEMB=2
315 DEVSIZE=$((DEVSIZEMB*1024*1024))
316
317 PAGE_SIZE=$(getconf PAGE_SIZE)
318 echo "System PAGE_SIZE=$PAGE_SIZE"
319
320 echo "Run tests in local filesystem"
321 falloc $DEVSIZEMB $LOCAL_FILE || fail "Failed to create file in local filesystem."
322 BSIZE=$(stat -c "%o" $LOCAL_FILE)
323 if [ $BSIZE -gt $((512*1024)) ]; then
324         echo "Detected file block size: $BSIZE bytes"
325         echo "Tuning it down to system page size ($PAGE_SIZE bytes)"
326         BSIZE=$PAGE_SIZE
327 fi
328 run_all $LOCAL_FILE
329
330 [ $(id -u) -eq 0 ] || {
331         echo "WARNING: You must be root to run remaining tests."
332         test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"
333         cleanup
334         exit 0
335 }
336
337 DEVBSIZE=512
338 BSIZE=$DEVBSIZE
339 EXP=0
340 DEVSIZEMBIMG=32
341
342 echo "# Create classic 512B drive"
343 echo "# (logical_block_size=$DEVBSIZE, physical_block_size=$((DEVBSIZE*(1<<EXP))))"
344 add_device dev_size_mb=$DEVSIZEMB sector_size=$DEVBSIZE physblk_exp=$EXP num_tgts=1
345 run_all $DEV
346 cleanup
347 add_device dev_size_mb=$DEVSIZEMBIMG sector_size=$DEVBSIZE physblk_exp=$EXP num_tgts=1
348 run_all_in_fs
349 cleanup
350
351 EXP=3
352 echo "# Create desktop-class 4K drive"
353 echo "# (logical_block_size=$DEVBSIZE, physical_block_size=$((DEVBSIZE*(1<<EXP))))"
354 add_device dev_size_mb=$DEVSIZEMB physblk_exp=$EXP sector_size=$DEVBSIZE num_tgts=1
355 run_all $DEV
356 BSIZE=$((DEVBSIZE*(1<<EXP)))
357 run_all $DEV
358 cleanup
359
360 add_device dev_size_mb=$DEVSIZEMBIMG physblk_exp=$EXP sector_size=$DEVBSIZE num_tgts=1
361 run_all_in_fs
362 cleanup
363
364 DEVBSIZE=4096
365 BSIZE=$DEVBSIZE
366 EXP=0
367 echo "# Create enterprise-class 4K drive"
368 echo "# (logical_block_size=$DEVBSIZE, physical_block_size=$((DEVBSIZE*(1<<EXP))))"
369 add_device dev_size_mb=$DEVSIZEMB physblk_exp=$EXP sector_size=$DEVBSIZE num_tgts=1
370 run_all $DEV
371 cleanup
372 add_device dev_size_mb=$DEVSIZEMBIMG sector_size=$DEVBSIZE physblk_exp=$EXP num_tgts=1
373 run_all_in_fs
374 cleanup
375
376 test $WARNS -eq 0 || echo "(WARNING: $WARNS suspicious result(s) in total)"
377 test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"