#!/bin/sh
# Requires: dm-writeboost-dkms stress-ng
# If not started as root, should allow sudo without password

# Size of test volumes in GB
B_SIZE=10
C_SIZE=4

# Names for loop files and mount point
B_NAME="backing-$$.img"
C_NAME="cache-$$.img"
M_NAME="wbmnt-$$"

DoCleanup() {
	if [ "$(mount|grep $M_NAME)" != "" ]; then
		echo "II: Unmounting $M_NAME..."
		sudo umount $M_NAME
	fi
	if [ -d $M_NAME ]; then
		echo "II: Removing mount directory..."
		rmdir $M_NAME
	fi
	if [ "$(sudo dmsetup ls|grep ^wbtgt)" != "" ]; then
		echo "II: Deleting dm-writeboost target..."
		sudo dmsetup remove wbtgt
	fi
	DEVNAME=$(losetup -j $C_NAME | cut -d: -f1)
	if [ "$DEVNAME" != "" ]; then
		echo "II: Detaching $DEVNAME..."
		sudo losetup -d $DEVNAME
	fi
	DEVNAME=$(losetup -j $B_NAME | cut -d: -f1)
	if [ "$DEVNAME" != "" ]; then
		echo "II: Detaching $DEVNAME..."
		sudo losetup -d $DEVNAME
	fi
	echo "II: Deleting file images..."
	rm -f $B_NAME $C_NAME
}

FailAbort() {
	echo "FAILED!"
	DoCleanup
	echo "EE: FAIL"
	exit 1
}

# Want to fit both image files (+1G safety margin) into current path
AVAIL=$(df -BG --output=avail .|tail -1|tr -d ' G')

echo -n "II: Checking for $(($B_SIZE + $C_SIZE))G available disk space..."
if [ $AVAIL -lt $(($B_SIZE + $C_SIZE + 1)) ]; then
	echo "SKIP"
	exit 77
fi
CPU_NUM=$(getconf _NPROCESSORS_ONLN)
if [ $CPU_NUM -lt 8 ]; then
	echo "SKIP"
	exit 77
fi
echo "OK"

echo "II: Creating loop files:"
echo -n "II: - $B_NAME..."
fallocate -l ${B_SIZE}G ${B_NAME} || FailAbort
echo "OK"
echo -n "II: - $C_NAME..."
fallocate -l ${C_SIZE}G ${C_NAME} || FailAbort
echo "OK"

echo "II: Connecting to loop devices:"
B_DEV=$(losetup -f)
echo -n "II: - $B_NAME -> $B_DEV..."
sudo losetup $B_DEV $B_NAME || FailAbort
echo "OK"
C_DEV=$(losetup -f)
echo -n "II: - $C_NAME -> $C_DEV..."
sudo losetup $C_DEV $C_NAME || FailAbort
echo "OK"

echo -n "II: Initialize cache..."
sudo dd if=/dev/zero of=$C_DEV oflag=direct bs=1M count=1 status=none || \
	FailAbort
echo "OK"

if ! lsmod | grep -q dm.writeboost; then
	echo -n "II: Loading dm-writeboost module..."
	sudo modprobe dm-writeboost || FailAbort
	echo "OK"
fi

SIZE=$(sudo blockdev --getsize $B_DEV)
echo -n "II: Creating dm-writeboost logical device..."
sudo dmsetup create wbtgt \
	--table "0 $SIZE writeboost $B_DEV $C_DEV" || FailAbort
echo "OK"

echo -n "II: Creating mount-point..."
mkdir $M_NAME || FailAbort
echo "OK"

echo -n "II: Create filesystem on dm-writeboost target..."
sudo mkfs.ext4 /dev/mapper/wbtgt >/dev/null 2>&1 || FailAbort
echo "OK"

echo -n "II: Mounting dm-writeboost target to $M_NAME..."
sudo mount /dev/mapper/wbtgt $M_NAME || FailAbort
echo "OK"

echo "II: Testing..."
if [ $CPU_NUM -gt 8 ]; then
	CPU_NUM=8
fi
HDD_SIZE=$((8 / $CPU_NUM))
(
	cd $M_NAME
	sudo stress-ng --timeout=5m --hdd=$CPU_NUM --verify --hdd-opts=wr-rnd \
		--hdd-bytes=${HDD_SIZE}g
) 2>&1 || FailAbort

DoCleanup
echo "PASS"

exit 0

