mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2026-01-06 07:25:29 +01:00
AFAIK older versions of the POSIX Standard didn't specify a way to
locate commands. Many operating systems and distributions added a
which(1) utility for that purpose, unfortunately without consistent
behavior across the board.
OTOH POSIX.1-2008 (or was it older? POSIX.1-2001 mentions it too, but
with a restriction: “On systems supporting the User Portability Utilities
option”) specifies that `command -v` can be used for that purpose:
https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/command.html
Moreover the standard adds that if the argument is neither a valid
utility, builtin, shell function nor alias then “no output shall be
written and the exit status shall reflect that the name was not found”.
It's therefore no longer needed to void the error output (spewing error
messages was one of the inconsistent behavior of the different which(1)
utilities).
The upcoming Debian 12 (codename Bookworm) appears to have deprecated
its which(1) utility (as a first step for its removal from the base
system):
$ which foo
/usr/bin/which: this version of `which' is deprecated; use `command -v' in scripts instead.
In most places the deprecation notice isn't visible when running the
test suite because most `which` calls run with the error output
redirected to /dev/null, however this is not the case everywhere:
https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.4.3/tests/integrity-compat-test#L333
https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.4.3/tests/reencryption-compat-test2#L232
This commit replaces all `which` calls from tests/* with `command -v`,
and removes the error output redirection.
383 lines
12 KiB
Bash
Executable File
383 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# set _FORCE_LOCAL environment variable to run blockwise unit tests even on local
|
|
# nfs. Some tests will fail because nfs is eager to write for example 4095 bytes
|
|
# in O_DIRECT mode.
|
|
|
|
BW_UNIT=./unit-utils-io
|
|
STRACE=strace
|
|
MNT_DIR=./mnt_bwunit
|
|
LOCAL_FILE=./blockwise_localfile
|
|
|
|
# $1 path to scsi debug bdev
|
|
scsi_debug_teardown() {
|
|
local _tries=15;
|
|
|
|
while [ -b "$1" -a $_tries -gt 0 ]; do
|
|
rmmod scsi_debug >/dev/null 2>&1
|
|
if [ -b "$1" ]; then
|
|
sleep .1
|
|
_tries=$((_tries-1))
|
|
fi
|
|
done
|
|
|
|
test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1
|
|
}
|
|
|
|
cleanup() {
|
|
if [ -d "$MNT_DIR" ] ; then
|
|
umount -f $MNT_DIR 2>/dev/null
|
|
rmdir $MNT_DIR 2>/dev/null
|
|
fi
|
|
rm -f $LOCAL_FILE 2> /dev/null
|
|
scsi_debug_teardown "$DEV" || exit 100
|
|
}
|
|
|
|
fail()
|
|
{
|
|
if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi
|
|
cleanup
|
|
exit 100
|
|
}
|
|
|
|
fail_count()
|
|
{
|
|
echo "$MSG[FAIL]"
|
|
FAILS=$((FAILS+1))
|
|
}
|
|
|
|
warn_count()
|
|
{
|
|
echo "$MSG[WARNING]"
|
|
WARNS=$((WARNS+1))
|
|
}
|
|
|
|
skip()
|
|
{
|
|
echo "TEST SKIPPED: $1"
|
|
cleanup
|
|
exit 0
|
|
}
|
|
|
|
add_device() {
|
|
rmmod scsi_debug >/dev/null 2>&1
|
|
if [ -d /sys/module/scsi_debug ] ; then
|
|
echo "Cannot use scsi_debug module (in use or compiled-in), test skipped."
|
|
exit 77
|
|
fi
|
|
modprobe scsi_debug $@ delay=0 >/dev/null 2>&1
|
|
if [ $? -ne 0 ] ; then
|
|
echo "This kernel seems to not support proper scsi_debug module, test skipped."
|
|
exit 77
|
|
fi
|
|
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
|
DEV="/dev/$DEV"
|
|
[ -b $DEV ] || fail "Cannot find $DEV."
|
|
}
|
|
|
|
falloc() {
|
|
dd if=/dev/zero of=$2 bs=1M count=$1 2> /dev/null
|
|
}
|
|
|
|
run_all_in_fs() {
|
|
for file in $(ls img_fs_*.img.xz) ; do
|
|
echo "Run tests in $file put on top block device."
|
|
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
|
|
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
|
|
mount $DEV $MNT_DIR
|
|
if [ $? -ne 0 ]; then
|
|
echo "Mounting image $file failed, skipped."
|
|
continue;
|
|
fi
|
|
rm -rf $MNT_DIR/* 2>/dev/null
|
|
local tfile=$MNT_DIR/bwunit_tstfile
|
|
falloc $DEVSIZEMB $tfile || fail "enospc?"
|
|
local iobsize=$(stat -c "%o" $tfile)
|
|
test -n "$iobsize" -a $iobsize -gt 0 || fail
|
|
local oldbsize=$BSIZE
|
|
BSIZE=$iobsize
|
|
run_all $tfile
|
|
BSIZE=$oldbsize
|
|
umount $MNT_DIR
|
|
done
|
|
}
|
|
|
|
trunc_file() {
|
|
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."
|
|
}
|
|
|
|
RUN() {
|
|
local _res=$1
|
|
shift
|
|
local _dev=$1
|
|
shift
|
|
local _fn=$1
|
|
shift
|
|
local _type="bdev"
|
|
local _fsize=0
|
|
|
|
test -b $_dev || {
|
|
_type="file"
|
|
_fsize=$(stat -c "%s" $_dev)
|
|
}
|
|
|
|
case "$_res" in
|
|
P)
|
|
MSG="Testing $_fn on $_type with params $@ [expecting TRUE]..."
|
|
$BW_UNIT $_dev $_fn $@
|
|
if [ $? -ne 0 ]; then
|
|
if [ $_type = "file" ]; then
|
|
warn_count
|
|
else
|
|
fail_count
|
|
fi
|
|
trunc_file $_fsize $_dev
|
|
test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-pass.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
|
|
else
|
|
MSG="$MSG[OK]"
|
|
fi
|
|
;;
|
|
F)
|
|
MSG="Testing $_fn on $_type with params $@ [expecting FALSE]..."
|
|
$BW_UNIT $_dev $_fn $@ 2> /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
if [ $_type = "file" ]; then
|
|
warn_count
|
|
else
|
|
fail_count
|
|
fi
|
|
trunc_file $_fsize $_dev
|
|
test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-fail.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
|
|
else
|
|
MSG="$MSG[OK]"
|
|
fi
|
|
;;
|
|
*)
|
|
fail "Internal test error"
|
|
;;
|
|
esac
|
|
|
|
trunc_file $_fsize $_dev
|
|
}
|
|
|
|
run_all() {
|
|
if [ -b "$1" ]; then
|
|
BD_FAIL="F"
|
|
else
|
|
BD_FAIL="P"
|
|
fi
|
|
|
|
# buffer io support only blocksize aligned ios
|
|
# device/file fn_name length
|
|
RUN "P" $1 read_buffer $BSIZE
|
|
RUN "P" $1 read_buffer $((2*BSIZE))
|
|
RUN "F" $1 read_buffer $((BSIZE-1))
|
|
RUN "F" $1 read_buffer $((BSIZE+1))
|
|
RUN "P" $1 read_buffer 0
|
|
|
|
RUN "P" $1 write_buffer $BSIZE
|
|
RUN "P" $1 write_buffer $((2*BSIZE))
|
|
|
|
RUN "F" $1 write_buffer $((BSIZE-1))
|
|
RUN "F" $1 write_buffer $((BSIZE+1))
|
|
RUN "F" $1 write_buffer 0
|
|
|
|
# basic blockwise functions
|
|
# device/file fn_name length bsize
|
|
RUN "P" $1 read_blockwise 0 $BSIZE
|
|
RUN "P" $1 read_blockwise $((BSIZE)) $BSIZE
|
|
RUN "P" $1 read_blockwise $((BSIZE-1)) $BSIZE
|
|
RUN "P" $1 read_blockwise $((BSIZE+1)) $BSIZE
|
|
RUN "P" $1 read_blockwise $((DEVSIZE)) $BSIZE
|
|
RUN "P" $1 read_blockwise $((DEVSIZE-1)) $BSIZE
|
|
RUN "F" $1 read_blockwise $((DEVSIZE+1)) $BSIZE
|
|
|
|
RUN "P" $1 write_blockwise 0 $BSIZE
|
|
RUN "P" $1 write_blockwise $((BSIZE)) $BSIZE
|
|
RUN "P" $1 write_blockwise $((BSIZE-1)) $BSIZE
|
|
RUN "P" $1 write_blockwise $((BSIZE+1)) $BSIZE
|
|
RUN "P" $1 write_blockwise $((DEVSIZE)) $BSIZE
|
|
RUN "P" $1 write_blockwise $((DEVSIZE-1)) $BSIZE
|
|
RUN "$BD_FAIL" $1 write_blockwise $((DEVSIZE+1)) $BSIZE
|
|
|
|
# seek variant blockwise functions
|
|
# device/file fn_name length bsize offset
|
|
RUN "P" $1 read_lseek_blockwise 0 $BSIZE 0
|
|
RUN "P" $1 read_lseek_blockwise 0 $BSIZE 1
|
|
RUN "P" $1 read_lseek_blockwise 0 $BSIZE $((DEVSIZE))
|
|
# length = 0 is significant here
|
|
RUN "P" $1 read_lseek_blockwise 0 $BSIZE $((DEVSIZE+1))
|
|
|
|
# beginning of device
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE 0
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE 1
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE/2))
|
|
|
|
# somewhere in the 'middle'
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $BSIZE
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((2*BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((BSIZE+BSIZE/2-1))
|
|
|
|
# cross-sector tests
|
|
RUN "P" $1 read_lseek_blockwise 2 $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise 2 $BSIZE $((2*BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((2*BSIZE-1))
|
|
|
|
# including one whole sector
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE))
|
|
RUN "P" $1 read_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 read_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 read_lseek_blockwise $((3*BSIZE-2)) $BSIZE $((BSIZE+1))
|
|
|
|
# hiting exactly the sector boundary
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE 1
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
|
|
|
|
# device end
|
|
RUN "P" $1 read_lseek_blockwise 1 $BSIZE $((DEVSIZE-1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+1))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE))
|
|
RUN "P" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE-1))
|
|
|
|
# this must fail on both device and file
|
|
RUN "F" $1 read_lseek_blockwise 1 $BSIZE $((DEVSIZE))
|
|
RUN "F" $1 read_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+2))
|
|
RUN "F" $1 read_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE+1))
|
|
RUN "F" $1 read_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE))
|
|
|
|
RUN "P" $1 write_lseek_blockwise 0 $BSIZE 0
|
|
# TODO: this may pass but must not write a byte (write(0) is undefined).
|
|
# Test it with underlying dm-error or phony read/write syscalls.
|
|
# Skipping read is optimization.
|
|
# HINT: currently it performs useless write and read as well
|
|
RUN "P" $1 write_lseek_blockwise 0 $BSIZE 1
|
|
RUN "P" $1 write_lseek_blockwise 0 $BSIZE $BSIZE
|
|
|
|
# beginning of device
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE 0
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE 1
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE/2))
|
|
|
|
# somewhere in the 'middle'
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $BSIZE
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((2*BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((BSIZE+BSIZE/2-1))
|
|
|
|
# cross-sector tests
|
|
RUN "P" $1 write_lseek_blockwise 2 $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise 2 $BSIZE $((2*BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((2*BSIZE-1))
|
|
|
|
# including one whole sector
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE))
|
|
RUN "P" $1 write_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 write_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+2)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((2*BSIZE)) $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 write_lseek_blockwise $((3*BSIZE-2)) $BSIZE $((BSIZE+1))
|
|
|
|
# hiting exactly the sector boundary
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE 1
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE $((BSIZE+1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((BSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((2*BSIZE-1))
|
|
|
|
# device end
|
|
RUN "P" $1 write_lseek_blockwise 1 $BSIZE $((DEVSIZE-1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+1))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE))
|
|
RUN "P" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE-1))
|
|
|
|
# this must fail on device, but pass on file (which is unfortunate and maybe design mistake)
|
|
RUN "$BD_FAIL" $1 write_lseek_blockwise 1 $BSIZE $((DEVSIZE))
|
|
RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE-1)) $BSIZE $((DEVSIZE-BSIZE+2))
|
|
RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE)) $BSIZE $((DEVSIZE-BSIZE+1))
|
|
RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE))
|
|
}
|
|
|
|
[ -n "$CRYPTSETUP_PATH" ] && skip "Cannot run this test with CRYPTSETUP_PATH set."
|
|
|
|
command -v $STRACE >/dev/null || unset STRACE
|
|
test -x $BW_UNIT || skip "Run \"make `basename $BW_UNIT`\" first"
|
|
|
|
FAILS=0
|
|
WARNS=0
|
|
DEVSIZEMB=2
|
|
DEVSIZE=$((DEVSIZEMB*1024*1024))
|
|
|
|
PAGE_SIZE=$(getconf PAGE_SIZE)
|
|
echo "System PAGE_SIZE=$PAGE_SIZE"
|
|
|
|
echo "Run tests in local filesystem"
|
|
falloc $DEVSIZEMB $LOCAL_FILE || fail "Failed to create file in local filesystem."
|
|
BSIZE=$(stat -c "%o" $LOCAL_FILE)
|
|
if [ $BSIZE -gt $((512*1024)) ]; then
|
|
echo "Detected file block size: $BSIZE bytes"
|
|
echo "Tuning it down to system page size ($PAGE_SIZE bytes)"
|
|
BSIZE=$PAGE_SIZE
|
|
fi
|
|
run_all $LOCAL_FILE
|
|
|
|
[ $(id -u) -eq 0 ] || {
|
|
echo "WARNING: You must be root to run remaining tests."
|
|
test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"
|
|
cleanup
|
|
exit 0
|
|
}
|
|
|
|
DEVBSIZE=512
|
|
BSIZE=$DEVBSIZE
|
|
EXP=0
|
|
DEVSIZEMBIMG=32
|
|
|
|
echo "# Create classic 512B drive"
|
|
echo "# (logical_block_size=$DEVBSIZE, physical_block_size=$((DEVBSIZE*(1<<EXP))))"
|
|
add_device dev_size_mb=$DEVSIZEMB sector_size=$DEVBSIZE physblk_exp=$EXP num_tgts=1
|
|
run_all $DEV
|
|
cleanup
|
|
add_device dev_size_mb=$DEVSIZEMBIMG sector_size=$DEVBSIZE physblk_exp=$EXP num_tgts=1
|
|
run_all_in_fs
|
|
cleanup
|
|
|
|
EXP=3
|
|
echo "# Create desktop-class 4K drive"
|
|
echo "# (logical_block_size=$DEVBSIZE, physical_block_size=$((DEVBSIZE*(1<<EXP))))"
|
|
add_device dev_size_mb=$DEVSIZEMB physblk_exp=$EXP sector_size=$DEVBSIZE num_tgts=1
|
|
run_all $DEV
|
|
BSIZE=$((DEVBSIZE*(1<<EXP)))
|
|
run_all $DEV
|
|
cleanup
|
|
|
|
add_device dev_size_mb=$DEVSIZEMBIMG physblk_exp=$EXP sector_size=$DEVBSIZE num_tgts=1
|
|
run_all_in_fs
|
|
cleanup
|
|
|
|
DEVBSIZE=4096
|
|
BSIZE=$DEVBSIZE
|
|
EXP=0
|
|
echo "# Create enterprise-class 4K drive"
|
|
echo "# (logical_block_size=$DEVBSIZE, physical_block_size=$((DEVBSIZE*(1<<EXP))))"
|
|
add_device dev_size_mb=$DEVSIZEMB physblk_exp=$EXP sector_size=$DEVBSIZE num_tgts=1
|
|
run_all $DEV
|
|
cleanup
|
|
add_device dev_size_mb=$DEVSIZEMBIMG sector_size=$DEVBSIZE physblk_exp=$EXP num_tgts=1
|
|
run_all_in_fs
|
|
cleanup
|
|
|
|
test $WARNS -eq 0 || echo "(WARNING: $WARNS suspicious result(s) in total)"
|
|
test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"
|