#! /bin/bash
### BEGIN INIT INFO
# Provides:             voyage-sync
# Required-Start:       $local_fs
# Required-Stop:        $local_fs
# X-Stop-After:     	$network
# Should-Start:
# Should-Stop:          
# Default-Start:        S
# Default-Stop:         0 6
# Short-Description:    Voyage tmpfs and sync
# Description:          Voyage tmpfs and sync
### END INIT INFO
#
# skeleton  example file to build /etc/init.d/ scripts.
#       This file should be used to construct scripts for /etc/init.d.
#
#       Written by Miquel van Smoorenburg <miquels@cistron.nl>.
#       Modified for Debian
#       by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
# Version:  @(#)skeleton  1.9  26-Feb-2001  miquels@cistron.nl
#

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#DAEMON=/usr/sbin/voyage-sync
NAME=voyage-sync
DESC=voyage-sync

TMPFS_ROOT=/lib/init/rw
SYNC_DIRS="var/log var/tmp"

NEED_REBOOT=no

# using the following commands to install
#	
#	update-rc.d voyage-sync start 36 S . stop 99 0 6 .

if [ -f /etc/default/voyage-util ] ; then 
	. /etc/default/voyage-util; 
fi

SYNC_DIRS="$SYNC_DIRS $VOYAGE_SYNC_DIRS"
UNIONFS=${VOYAGE_UNIONFS:=tmpfs}

reconfig_resolvconf() {
	PKG=$(dpkg-query --show|grep resolvconf)
	if  [ ! -z "$PKG" ] && [ ! -L /etc/resolv.conf ] ; then
		echo "Reconfiguring resolvconf."
		DEBIAN_FRONTEND=noninteractive dpkg-reconfigure resolvconf
	fi
}

copy_ro_to_rw() {
	echo "Copying /ro to /rw."
	#tar -C /ro -cf - . | tar -C /lib/init/rw -xf -  > /dev/null 2>&1
	tar -C /ro -cf - . | tar -C /lib/init/rw -xf - 
}

mount_dirs()
{
	# $1 : aufs|unionfs|tmpfs
	# $2 : source directory
	# $3 : target directory
	case $1 in
		'aufs')
			PERM=$(stat --format=%U:%G $2)
			chmod --reference=$2 $3
			chown --reference=$2 $3
			mount -t aufs -o dirs=$3:$2=ro none $2> /dev/null 2>&1
			#echo "chown $PERM $2"
			chown $PERM $2
			;;
		'unionfs')
			PERM=$(stat --format=%U:%G $2)
			chmod --reference=$2 $3
			chown --reference=$2 $3
			mount -t unionfs -o dirs=$3:$2=ro none $2> /dev/null 2>&1
			#echo "chown $PERM $2"
			chown $PERM $2
			;;
		'tmpfs')
			PERM=$(stat --format=%U:%G $2)
			chmod --reference=$2 $3
			chown --reference=$2 $3
			if [ "$(ls -A $2)" ] ; then cp -rp $2/. $3/; fi
			echo "    tmpfs: mount back $3 to $2"
			mount --bind $3 $2 
			#echo "chown $PERM $2"
			chown $PERM $2
			;;
		*)
	    	;;
	esac
}

case $1 in
	'start')
		# check SYNC_DIRS if recovery after a power failure is activated
		if [ "$VOYAGE_SYNC_RECOVER" = "YES" ] ; then
			echo "Voyage is now checking if recovery from a power failure is needed..."
			VOYAGE_SYNC_RECOVER_DIRS=${VOYAGE_SYNC_RECOVER_DIRS:-$SYNC_DIRS}
			for SYNC_DIR in $VOYAGE_SYNC_RECOVER_DIRS ; do
				if [ -d /.sync/$SYNC_DIR ] ; then
					echo "  Recover'ing /.sync/$SYNC_DIR to `dirname /$SYNC_DIR`	"
					rsync -a -q --delete-after /.sync/$SYNC_DIR `dirname /$SYNC_DIR`
					NEED_REBOOT=yes
				fi
			done
			# and now remove /.sync
			rm -rf /.sync
			# check if reboot is needed
			if [ "$NEED_REBOOT" = yes ] ; then
				echo "  Will now restart after recovery from a power failure"
				reboot -f
			fi
		fi

		reconfig_resolvconf
		copy_ro_to_rw
		
		echo "Voyage is now setting up tmpfs for changed files..."
		for SYNC_DIR in $SYNC_DIRS $VOYAGE_RW_DIRS; do
			[ ! -d $TMPFS_ROOT/$SYNC_DIR ] && mkdir -p $TMPFS_ROOT/$SYNC_DIR			
			
			mount_dirs $UNIONFS /$SYNC_DIR $TMPFS_ROOT/$SYNC_DIR
			
			#chmod --reference=/$SYNC_DIR $TMPFS_ROOT/$SYNC_DIR
			#chown --reference=/$SYNC_DIR $TMPFS_ROOT/$SYNC_DIR			
			#mount -t aufs -o dirs=$TMPFS_ROOT/$SYNC_DIR:$SYNC_DIR=ro none /$SYNC_DIR> /dev/null 2>&1
		done
		echo "Done."
		;;
	'sync')
		echo "Voyage is now synchronizing changed files..."
		for SYNC_DIR in $SYNC_DIRS ; do
			if [ ! -d /.sync/$SYNC_DIR ] ; then
				mkdir -p /.sync/$SYNC_DIR
				PERM=$(stat --format=%U:%G /$SYNC_DIR)
				chown $PERM /.sync/$SYNC_DIR
			fi
		
			echo "  Sync'ing /$SYNC_DIR to `dirname /.sync/$SYNC_DIR`	"
			if [ "$(ls -A /$SYNC_DIR)" ]; then
				rsync -a -q --delete-after /$SYNC_DIR/. /.sync/$SYNC_DIR
			fi
		done
		sync
		;;
		
	'stop')
		[ -f /usr/local/sbin/remountrw ] && /usr/local/sbin/remountrw

		# call "voyage-sync sync"
		$0 sync

		# then kill suspicous process in sync & RW dir and unmount
		for SYNC_DIR in $SYNC_DIRS $VOYAGE_RW_DIRS; do
			if [ "$(ls -A /$SYNC_DIR)" ]; then
			for P in `lsof -F p /$SYNC_DIR`
			do
				echo "Killing process: $(ps --no-heading --format=comm -p ${P:1})"
				kill ${P:1}
			done
			fi
			sleep 1

			echo "  unmount'ing /$SYNC_DIR	"
			umount /$SYNC_DIR		
			
			echo "  Sync'ing /.sync/$SYNC_DIR to `dirname /$SYNC_DIR`	"
			rsync -a -q --delete-after /.sync/$SYNC_DIR `dirname /$SYNC_DIR`			
			#PERM=$(stat --format=%U:%G /$SYNC_DIR)
			#echo "owner $PERM /$SYNC_DIR"
		done
		
		# at last remove /.sync
		rm -rf /.sync
		echo "Done."
		;;
  	force-reload|restart)
    	;;

	*)
		echo "Usage: /etc/init.d/voyage-sync {start|stop|sync}" >&2
	    ;;
esac

