ansitest/zfs-test-encryption-speeds-v2.sh

231 lines
8.0 KiB
Bash

#!/bin/bash
# script version: v2.2021.0408 nobackticks edition, with moar comments and clarifications
# NOTE - check this code for EDITME and modify according to your environment
# Parses man page, creates all supported types of encrypted datasets and copies an ISO file to ramdisk
# RUN AS ROOT - tested on Linux Mint / Ubuntu 18.04 and 20.04 (rpool), should be fairly easily adaptable
# NOTE Pass arg $1 = "cleanup" to delete test encryption datasets / cleanup ramdisk
# REF: https://github.com/openzfs/zfs/issues/10363
# REF: https://www.cyberciti.biz/faq/how-to-find-out-aes-ni-advanced-encryption-enabled-on-linux-system/
##Check for root priviliges
if [ "$(id -u)" -ne 0 ]; then
echo "Please run $0 as root."
exit 1
fi
# if we on OSX, you running the wrong version of this script
# ex. OSTYPE=darwin17.7.0
if [ $(echo $OSTYPE |grep -c darwin) -gt 0 ]; then
echo "You need to be running this on a non-OSX (e.g. Linux) box. There is an OSX version of this script available."
echo "See: https://github.com/kneutron/ansitest/tree/master/OSX"
exit 10
fi
# DEFINE VARS
zp=rpool # xxx TODO EDITME # NOTE this zpool is SSD-based
logfile=~/zfs-test-encryption-speeds.log
# will be copied to ramdisk (prep) - put "" to skip
# NOTE nothing prevents you from copying an .iso over SMB or NFS ;-)
isofile=/zdell500/shrcompr/ISO/bionic-desktop-amd64.iso # xxx TODO EDITME
#isofile="/mnt/imac5/ISO/bionic-desktop-amd64.iso" # EDITME
#isofile=""
compr=lz4
# compr=zstd-2
# ^ for zfs 2.0.x
# where are we storing the key for these test datasets (will be created if not exist)
zfskeyloc=~/zek-testencr-zfs.key
#=====================================
# failexit.mrg
function failexit () {
echo '! Something failed! Code: '"$1 $2" # code # (and optional description)
exit $1
}
# Echo something to current console AND log
# Can also handle piped input ( cmd |logecho )
# Warning: Has trouble echoing '*' even when quoted.
function loggit () {
args=$@
if [ -z "$args" ]; then
args='tmp'
while [ 1 ]; do
read -e -t2 args
if [ -n "$args" ]; then
echo "$args" |tee -a $logfile;
else
break;
fi
done
else
echo "$args" |tee -a $logfile;
fi
} # END FUNC
function ridmeofthesedatasets () {
loggit "$0 - $(date) - Cleanup called"
if [ "$zp" = "rpool" ]; then
cd /
else
cd /$zp || failexit 404 "! Cleanup failed - /$zp not found"
fi
for zdel in $(echo Test-aes*); do loggit "$0 - Destroying encryption test dataset: $zp/$zdel"; time zfs destroy -rv "$zp/$zdel"; done
# need only filename, not path - strippit
isofile2=$(basename "$isofile")
C_ALL=C; declare -i chklen # integer
chklen=$(echo ${#isofile2})
if [ $chklen -gt 0 ] && [ -e "/dev/shm/$isofile2" ]; then
loggit "Cleaning up $isofile2 from ramdisk"
/bin/rm -fv "/dev/shm/$isofile2"
fi # sanity, will give error if we try to remove /dev/shm if var=blank
df -hT |head -n 1
df -hT |grep $zp
df -hT |grep /dev/shm
exit;
}
[ "$1" = "cleanup" ] && ridmeofthesedatasets
# MAIN ====================================================================
mv -v $logfile $logfile-old 2>/dev/null
echo "$(date) - $(hostname) - BEGIN encryption speed tests" |tee $logfile
loggit "o Kernel: $(uname -r)"
loggit "o Zpool version: $(zpool version)"
loggit "$(dmesg |grep ZFS)"
loggit "o CPU detected: $(grep -m1 "model name" /proc/cpuinfo |awk -F: '{print $2}')"
loggit "o Number of CPU cores/hyperthreads: $(grep -c 'processor' /proc/cpuinfo)"
loggit "o Actual number of $(grep -m1 cores /proc/cpuinfo)"
loggit "o CPU supports AES acceleration (blank=NO): $(grep -m1 -o aes /proc/cpuinfo)"
loggit "o Crypto modules loaded:"
loggit "$(sort -u /proc/crypto |grep module)"
loggit "o Check for openssl / run benchmarks"
which openssl && loggit "$(openssl speed aes)"
loggit "o Check for cryptsetup - please wait, this will take a few"
which cryptsetup && loggit "$(cryptsetup benchmark)"
loggit "o PREP - Copy ~1GB iso file to ramdisk if not already there"
LC_ALL=C; declare -i chklen # integer
chklen=$(echo ${#isofile})
[ $chklen -gt 0 ] && [ -e /dev/shm ] && [ -e "$isofile" ] && time cp -vn "$isofile" /dev/shm |tee -a $logfile
[ -e "/dev/shm/*.iso" ] || loggit "o Skipped ISO -> RAMdisk"
# get current zfs supported encryption types (NOTE depends on up-to-date man page) - output commasep
# yes, this is 3 different replace methods ;-) who doesn't like to show off a bit now and then
# read zfs man page, get ciphers, change pipe to comma, blank out unnec. stuff
encrline=$(man zfs|grep "encryption=" |head -n 1 |sed 's/|/,/g') # |sed 's/off,on,//g')
# NOTE on/off is REVERSED from osx manpage(!) so we process differently below in case they change it to match
encrline=$(echo "$encrline" |tr -d '[:space:]') # strip blanks
encrline=${encrline/on,/} # bash inline sed, replace string with blank
encrline=${encrline/off,/}
encrline=${encrline/encryption=/}
loggit "o Supported ZFS encryption types (per ' man zfs ')"
loggit "$encrline"
# we expect something like:
#aes-128-ccm,aes-192-ccm,aes-256-ccm,aes-128-gcm,aes-192-gcm,aes-256-gcm
# REF: https://stackoverflow.com/questions/918886/how-do-i-split-a-string-on-a-delimiter-in-bash#tab-top
# read string into bash array
oIFS="$IFS"
IFS=","
declare -a encrtype=($encrline)
IFS="$oIFS"
unset oIFS
#generate 32 byte passkey ONLY if not already exist
[ -e $zfskeyloc ] || dd if=/dev/urandom of="$zfskeyloc" bs=1 count=32
# NOTE omit xattr=sa for freebsd as of 2020.0526, may change after support is added to their code
# NOTE relatime and acltype=posixacl are missing from OSX zfs port as of 2020.0526
for testencr in "${encrtype[@]}"; do
loggit "o Creating $zp dataset for $testencr (if it doesnt already exist)"
# [ -e /$zp/Test-$testencr ] || \ # fails on rpool
[ $(df |grep -c Test-$testencr) -gt 0 ] || \
zfs create -o \
atime=off -o relatime=off -o compression=$compr -o sharesmb=off -o recordsize=1024k \
-o encryption=$testencr \
-o keyformat=raw \
-o keylocation=file://"$zfskeyloc" \
-o acltype=posixacl -o normalization=formD \
-o xattr=sa \
$zp/Test-$testencr || failexit 99 "! Failed to create ZFS $zp/$testencr"
loggit "$(zfs get encryption,keylocation $zp/Test-$testencr)"
done
#sync # may not want to do this if you have a long e.g. backup process running
free
echo 1 > /proc/sys/vm/drop_caches # free pagecache
free
df -hT |head -n 1
df -hT |grep -v '/ROOT/' |grep $zp
df -hT |grep /dev/shm
ls -lh /dev/shm/*.iso
loggit "$(date) $0 - $(hostname) - Ready for testing" # from here you can test how long it takes to copy iso file, run fio, etc
# time (cp -v $isofile /$zp/aesdataset; sync)
echo "o $0 Logfile is: $logfile"
exit;
#################################################
2020.0526 Author: Kneutron - knocked together a zfs test script to create datasets per encryption type, to test speeds of each cipher
Tested OK on Ubuntu 18.04 / Ubuntu 20.04 / Linux Mint
# Future changes will be in reverse-date order
2021.0408 backticks to $()
2020.0527 v2A - bugfix edition, chklen was ($ instead of $(
2020.0527 V2 - fixed minor bug in cleanup to fail if cant cd to /$zp, cd "/" if zp=rpool
sanity - fixed check length of isofile var, skip if 0
zp=rpool related fixes
+ added ramdisk cleanup + sanity checks (will ONLY delete defined iso file)
+ tested on ubuntu 20.04 with zfs rpool
NOTE if reboot or $thing happens to zpool such as export, you may need to:
zfs load-key $zp/encrtype
zfs mount -a
NOTE if doing this on an ssd-based pool, you may want to "zpool trim $zp" after doing cleanup
# note this does not work on osx (fixed in osx port) - REF: https://stackoverflow.com/questions/41489692/how-to-search-linux-man-pages-e-g-with-grep
$ man zfs|grep "encryption=" |head -n 1 |sed 's/|/,/g' |sed 's/off,on,//g'
encryption=off|on|aes-128-ccm|aes-192-ccm|aes-256-ccm|aes-128-gcm|aes-192-gcm|aes-256-gcm
encryption=off,on,aes-128-ccm,aes-192-ccm,aes-256-ccm,aes-128-gcm,aes-192-gcm,aes-256-gcm
encryption=aes-128-ccm,aes-192-ccm,aes-256-ccm,aes-128-gcm,aes-192-gcm,aes-256-gcm
/zmsata480 # for z in `echo aes*`; do echo $z; zfs destroy zmsata480/$z;done