+function corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_bytes}
+{
+ # Repeatable magic corruption :-)
+ CORRUPT=$3
+ RANDOM=43
+ while [ "$CORRUPT" -gt 0 ]; do
+ SEEK=$RANDOM
+ while [ $SEEK -ge $2 ] ; do SEEK=$RANDOM; done
+ echo -n -e "\x55" | dd of=$1 bs=1 count=1 seek=$SEEK conv=notrunc > /dev/null 2>&1
+ CORRUPT=$(($CORRUPT - 1))
+ done
+}
+
+# $1 data_device, $2 hash_device, $3 fec_device, $4 data/hash_block_size(in bytes),
+# $5 data_size(in blocks), $6 device_size(in blocks), $7 hash_offset(in bytes),
+# $8 fec_offset(in bytes), $9 fec_roots, ${10} corrupted_bytes, [${11} superblock(y/n), ${12} salt]
+function check_fec()
+{
+ INDEX=25
+ dd if=/dev/zero of=$1 bs=$4 count=$6 > /dev/null 2>&1
+
+ echo -n "Block_size: $4, Data_size: $(($4 * $5))B, FEC_roots: $9, Corrupted_bytes: ${10} "
+
+ PARAMS=" --data-block-size=$4 --hash-block-size=$4 "
+ if [ "$5" -ne "$6" ]; then
+ PARAMS="$PARAMS --data-blocks=$5"
+ fi
+
+ if [ "$7" -ne 0 ]; then
+ PARAMS="$PARAMS --hash-offset=$7"
+ fi
+
+ if [ "$8" -ne 0 ]; then
+ PARAMS="$PARAMS --fec-offset=$8"
+ fi
+
+ if [ "${11}" == "n" ]; then
+ INDEX=24
+ echo -n "[no-superblock]"
+ PARAMS="$PARAMS --no-superblock -s=${12}"
+ elif [ -n "${12}" ]; then
+ PARAMS="$PARAMS -s=${12}"
+ fi
+
+ if [[ "$1" == "$2" && "$1" == "$3" ]]; then
+ echo -n "[one_device_test]"
+ dd if=/dev/zero of=$IMG_TMP bs=$4 count=$5 > /dev/null 2>&1
+ ARR=(`sha256sum $IMG_TMP`)
+ HASH_ORIG=${ARR[0]}
+ else
+ ARR=(`sha256sum $1`)
+ HASH_ORIG=${ARR[0]}
+ fi
+
+ ARR=(`$VERITYSETUP format $1 $2 --fec-device=$3 $PARAMS`)
+ SALT=${ARR[$INDEX]}
+ ROOT_HASH=${ARR[$(($INDEX+3))]}
+
+ corrupt_device $1 $(($5 * $4)) ${10}
+
+ $VERITYSETUP create $DEV_NAME $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS > /dev/null 2>&1
+ if [ "$?" -ne "0" ] ; then
+ echo "[N/A, test skipped]"
+ return 3
+ fi
+
+ udevadm settle
+
+ dd if=/dev/mapper/$DEV_NAME of=$IMG_TMP > /dev/null 2>&1
+ ARR=(`sha256sum $IMG_TMP`)
+
+ HASH_REPAIRED=${ARR[0]}
+
+ $VERITYSETUP close $DEV_NAME
+
+ if [ "$HASH_ORIG" != "$HASH_REPAIRED" ]; then
+ echo -n "[kernel correction failed]"
+ $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 && fail "Userspace verify should fail"
+ echo -n "[userspace verify failed]"
+ RET=1
+ else
+ echo -n "[repaired in kernel]"
+ $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 || fail "Userspace verify failed"
+ echo "[userspace verify][OK]"
+ RET=0
+ fi
+ rm $1 $2 $3 $IMG_TMP > /dev/null 2>&1
+ return $RET
+}
+
+function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI option, $7 status option
+{
+ DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
+ FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3"
+
+ echo -n "Option $6 "
+ $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >/dev/null 2>&1 || fail
+ $VERITYSETUP create $DEV_NAME $DEV_PARAMS $2 $6 >/dev/null 2>&1 || fail
+ check_exists
+ $VERITYSETUP status $DEV_NAME 2>/dev/null | grep flags | grep -q $7 || fail
+ dmsetup table $DEV_NAME 2>/dev/null | grep -q $7 || fail
+ $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
+ echo "[OK]"
+}
+