#!/bin/bash
#
# QUADStor init script 
# chkconfig: - 29 61
# description: QUADStor Storage Virtualization 
#
### BEGIN INIT INFO
# Provides:			quadstor	
# Required-Start:		$local_fs $remote_fs $network 
# Should-Start:			$named $time ypclient dhcp radiusd
# Should-Stop:			$named $time ypclient dhcp radiusd
# Required-Stop:		$local_fs $remote_fs $network
# Default-Start:		3 5
# Default-Stop:			0 1 2 6
# Short-Description:		QUADStor
# Description:			Start/Stop QUADStor services
### END INIT INFO

if [ -f /etc/init.d/functions ] ; then
  . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
fi


prog=quadstor

check_error() {
	if [ "$?" != "0" ]; then
		echo "$1"
		logger "$1"
		if [ "$2" != "0" ]; then
			stop
			exit 1
		fi
	fi
}

kvers=`uname -r`

PIDOF="/sbin/pidof"
if [ ! -f /sbin/pidof ]; then
	PIDOF="/bin/pidof"
fi

unload_module() {
	/sbin/rmmod $1 > /dev/null 2>&1
	modpresent=`/sbin/lsmod | grep $1`
	tries="0"
	while [ "$modpresent" != "" ]; do
		sleep .1
		/sbin/rmmod $1 > /dev/null 2>&1
		if [ "$tries" = "50" ]; then
			break
		fi
		tries=`expr $tries + 1`
		modpresent=`/sbin/lsmod | grep $1`
	done
}

kill_prog() {
	pkill -f $1
	progpid=`$PIDOF $1 2> /dev/null`
	tries="0"
	while [ "$progpid" != "" ]; do
		sleep .1
		if [ "$tries" = "50" ]; then
			break
		fi
		tries=`expr $tries + 1`
		progpid=`$PIDOF $1 2> /dev/null`
	done
}

start() {

	/sbin/ldconfig > /dev/null 2>&1

	mdaemonpid=`$PIDOF /quadstor/sbin/mdaemon 2> /dev/null`
	if [ "$mdaemonpid" != "" ]; then
		echo "QUADStor Daemon already running..."
		exit 1
	fi

	rm -f /var/run/vtcdaemonrcv.sock > /dev/null 2>&1
	rm -f /var/run/mdaemon.sock > /dev/null 2>&1
	rm -f /var/run/vtmdaemonusr.sock > /dev/null 2>&1

	ietmod=`/sbin/lsmod 2> /dev/null | grep iscsi_trgt`
	if [ "$ietmod" != "" ]; then
		echo "iscsi_trgt kernel module conflicts with QUADStor. Exiting..."
		exit 1
	fi

	if [ ! -f /quadstor/lib/modules/$kvers/coredev.ko ]; then
 		echo "Compiling missing QUADStor modules. This may take a few minutes."
 		mkdir -p /quadstor/tmp/
 		echo `uname -a` > /quadstor/tmp/build.log 2>&1
		/quadstor/bin/builditfusr > /quadstor/tmp/build.log 2>&1
 		check_error "Building kernel modules failed!!!"
 	fi

	if [ -f /usr/bin/chcon ]; then
		/usr/bin/chcon -t textrel_shlib_t /quadstor/lib/libtl* > /dev/null 2>&1
		if [ -f /var/www/cgi-bin/system.cgi ]; then
			/usr/bin/chcon -v -R -t httpd_unconfined_script_exec_t /var/www/cgi-bin/*.cgi > /dev/null 2>&1
		fi
		if [ -f /srv/www/cgi-bin/system.cgi ]; then
			/usr/bin/chcon -R -t httpd_sys_content_t /srv/www/htdocs/quadstor > /dev/null 2>&1
			/usr/bin/chcon -R -t httpd_sys_content_t /srv/www/htdocs/index.html > /dev/null 2>&1
			/usr/bin/chcon -R -t httpd_sys_content_t /srv/www/htdocs/vtindex.html > /dev/null 2>&1
			/usr/bin/chcon -v -R -t httpd_unconfined_script_exec_t /srv/www/cgi-bin/*.cgi > /dev/null 2>&1
		fi
		if [ -f /usr/lib/cgi-bin/system.cgi ]; then
			/usr/bin/chcon -v -R -t httpd_unconfined_script_exec_t /usr/lib/cgi-bin/*.cgi > /dev/null 2>&1
		fi
		if [ -d /var/www/quadstor ]; then
			/usr/bin/chcon -R -t httpd_sys_content_t /var/www/quadstor > /dev/null 2>&1
			/usr/bin/chcon -R -t httpd_sys_content_t /var/www/index.html > /dev/null 2>&1
			/usr/bin/chcon -R -t httpd_sys_content_t /var/www/vtindex.html > /dev/null 2>&1
		fi
		if [ -d /var/www/html/quadstor ]; then
			/usr/bin/chcon -R -t httpd_sys_content_t /var/www/html/quadstor > /dev/null 2>&1
			/usr/bin/chcon -R -t httpd_sys_content_t /var/www/html/index.html > /dev/null 2>&1
			/usr/bin/chcon -R -t httpd_sys_content_t /var/www/html/vtindex.html > /dev/null 2>&1
		fi
	fi

        echo -n $"Starting $prog: " > /quadstor/tmp/start.log

	mkdir -p /quadstor/tmp
	chmod 777 /quadstor/tmp

	if [ -f /var/run/postgresql/.s.PGSQL.9984 -o -f /var/run/postgresql/.s.PGSQL.9984.lock ]; then
		/quadstor/pgsqlsys/etc/pgsql stop > /dev/null 2>&1
	fi

	ulimit -n 65536
	/quadstor/pgsqlsys/etc/pgsql start
	check_error "Cannot start database"

	/sbin/modprobe -q scsi_mod > /dev/null 2>&1
	/sbin/modprobe -q sg > /dev/null 2>&1
	/sbin/modprobe -q scsi_transport_fc > /dev/null 2>&1
	/sbin/modprobe -q nvme_fc > /dev/null 2>&1
	/sbin/modprobe -q qla2xxx > /dev/null 2>&1

	/sbin/insmod /quadstor/lib/modules/$kvers/fcint.ko >> /quadstor/tmp/start.log 2>&1
	check_error "Failed to insert fcint module. A reboot is probably needed for Fiber Channel networks." 0

	/sbin/insmod /quadstor/lib/modules/$kvers/coredev.ko >> /quadstor/tmp/start.log 2>&1
	check_error "Failed to insert core module"

	sysctl -w vm.max_map_count=524240 >> /quadstor/tmp/start.log 2>&1
 	check_error "Cannot set vm.max_map_count=524240"

	/quadstor/sbin/coredev
	check_error "Cannot start coredev daemon"

	sleep 6

	/sbin/insmod /quadstor/lib/modules/$kvers/ldev.ko >> /quadstor/tmp/start.log 2>&1 
	check_error "Failed to insert ldev module"

	/sbin/insmod /quadstor/lib/modules/$kvers/iscsit.ko >> /quadstor/tmp/start.log 2>&1
	check_error "Failed to insert iscsi target module"

 	iscsidebug=`cat /quadstor/etc/quadstor.conf | grep -i "^iSCSIDebug=" | cut -f 2 -d'='`
 	if [ "$iscsidebug" != "" ]; then
 		iscsidebug="-d $iscsidebug"
 	fi
	/quadstor/sbin/ietd $iscsidebug

	while  [ ! -S /var/run/vtcdaemonrcv.sock ]; do
		logger "Waiting for core daemon socket"
		sleep 2
	done

	export PATH=$PATH:/quadstor/bin:/sbin:/usr/sbin
	rm -f /quadstor/.mdaemon
	/quadstor/sbin/mdaemon >> /quadstor/tmp/start.log 2>&1
	check_error "Cannot start master daemon"

	sleep 5

	while  [ ! -S /var/run/mdaemon.sock ]; do
		logger "Waiting for daemon socket"
		sleep 2
	done

	/quadstor/bin/scctl -l >> /quadstor/tmp/start.log 2>&1

	if [ -d /var/lock/subsys ]; then
		touch /var/lock/subsys/quadstor
	fi

	sleep 3
	udevadm settle
	for i in `/quadstor/bin/vdconfig -l | sed -n '1!p' | awk '{print $1}'`; do
		stat /dev/quadstor/$i > /dev/null 2>&1
		if [ "$?" != "0" ]; then
			logger -s "WARN: Cannot yet find symlink /dev/quadstor/$i"
			continue
		fi
		
		mount /dev/quadstor/$i > /dev/null 2>&1
	done
}

stop() {
	echo -n $"Stopping $prog: "
	/quadstor/bin/ietadm --op delete >/dev/null 2>/dev/null
	kill_prog "/quadstor/sbin/ietd"

	/quadstor/bin/scctl -u > /dev/null 2>&1

	kill_prog "/quadstor/sbin/mdaemon"
	rm -f /quadstor/.mdaemon

	/quadstor/pgsqlsys/etc/pgsql stop

	unload_module "iscsit"
	unload_module "ldev"
	kill_prog "/quadstor/sbin/coredev"

	i=0
	while [ $i -lt 30 ]; do
		coredev=`/sbin/lsmod | grep coredev`
		if [ "$coredev" = "" ]; then
			break
		fi
		/sbin/rmmod coredev
		if [ "$?" -eq 0 ]; then
			break
		fi
		sleep 10 
		let i=i+1
	done

	unload_module "fcint"
	rm -f /quadstor/tmp/.quadstortl.* > /dev/null 2>&1
	rm -f /var/lock/subsys/quadstor
	rm -f /var/run/vtcdaemonrcv.sock > /dev/null 2>&1
	rm -f /var/run/mdaemon.sock > /dev/null 2>&1
	rm -f /var/run/vtmdaemonusr.sock > /dev/null 2>&1
}

status_check() {
	mdaemonpid=`$PIDOF /quadstor/sbin/mdaemon 2> /dev/null`
	if [ "${mdaemonpid}" != "" ] ; then 
		echo "QUADStor daemon is running..."
		exit 0
	else
		echo "QUADStor daemon is stopped"
		exit 1
	fi
	
}

RETVAL=0

# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  restart)
	stop
	start
	;;
  status)
        status_check
	;;
 *)
	echo $"Usage: $prog {start|stop|restart|status}"
	exit 1
esac

exit 0 

