#! /bin/bash -e

export TMPDIR=/var/tmp
export LC_ALL=C

SNAPSIZE=1G
DST=${1?need destination folder}
VG=`hostname`
DEV=/dev/sda1
NICE=

now=`date +%s`
tmp=`mktemp`
snaps=`mktemp`

_lvremove() {
	local dev=$1
	local vg=${dev%/*}
	local lv=${dev#*/}

	udevadm settle || true
	lvremove -f "$dev" || {
		dmsetup remove /dev/$vg/$lv \
		&& udevadm settle \
		&& dmsetup remove /dev/$vg/$lv-cow \
		&& udevadm settle \
		&& lvremove -f "$dev" || true
	}
}

cleanup() {

	while read lvm dev orig cleanup; do
		udevadm settle
		test -e "$dev" && test "$cleanup" || continue
		eval $cleanup || true
	done < $snaps

	rm -f $tmp $snaps
}

trap cleanup EXIT INT

for dev in $DEV; do
	if mount -o remount,ro $dev; then
		echo "- $tmp - rm -fv $tmp" >>$snaps
		cp -v $dev $tmp
		mount -o remount,rw $dev
		file -s $tmp | egrep -q "ext[234] filesystem" && e2fsck -C0 -f -y $tmp || true
		imager save --now=$now -z $tmp:$dev $DST
		rm -f $tmp
	fi
done


lvs -o vg_name,lv_name,origin --noheadings $VG | while read vg lv origin; do
	# LVM-name DEV-name ORIG-name (cleanup)

	orig="$vg/$lv"
	if test "$origin"; then
		dev="/dev/$vg/$lv"
		echo "$vg/$lv $dev $dev" >>$snaps
		continue
	fi
	snap="$vg/$lv.snap.$now"
	dev="/dev/$vg/$lv.snap.$now"
	lvcreate -s -L $SNAPSIZE -n "$snap" "$orig"
	echo "$snap $dev /dev/$vg/$lv _lvremove $snap" >>$snaps
done

udevadm settle

while read snap dev name cleanup; do
	test "$snap" = "-" && continue
	for a in 1 2 3; do
		file -s `readlink -f $dev` | egrep -q "ext[234] filesystem" && $NICE fsck -y "$dev" && break
		case $? in
			32)	exit;;
			*)	true;;
		esac
	done
	if test $? = 0; then
		$NICE imager save --now=$now -z $dev:$name $DST 
		case `lvs -o snap_percent --noheadings "$snap"` in
			100*)	echo "****************** $snap is full!";;
		esac
	fi
	test "$cleanup" && eval $cleanup || true
done <$snaps
date
date  >/var/log/backup.done
