#
# description: Manages all PLC services on this machine
#
-# $Id: host.init,v 1.2 2006/03/27 22:01:36 mlhuang Exp $
+# $Id$
#
PATH=/sbin:/bin:/usr/bin:/usr/sbin
# Source function library.
-. /etc/init.d/functions
+if [ -f /etc/init.d/functions ] ; then
+ . /etc/init.d/functions
+fi
+
+# If success() or failure() are not defined
+if ! type -type success >/dev/null || ! type -type failure >/dev/null ; then
+ success() {
+ echo -ne "[ OK ]\r"
+ return 0
+ }
+ failure() {
+ echo -ne "[FAILED]\r"
+ return 1
+ }
+fi
# Source configuration
-if [ -f /etc/sysconfig/plc -a -z "${PLC_ROOT}${PLC_DATA}" ] ; then
- . /etc/sysconfig/plc
+SERVICE=$(basename $0)
+if [ ! -f /etc/sysconfig/$SERVICE ] ; then
+ SERVICE=plc
+fi
+if [ -f /etc/sysconfig/$SERVICE -a -z "${PLC_ROOT}${PLC_DATA}" ] ; then
+ . /etc/sysconfig/$SERVICE
fi
# Total number of errors
fi
}
-start ()
+mount_plc ()
{
echo -n $"Mounting PLC: "
[ $ERRORS -eq 0 ] && success $"PLC unmount" || failure $"PLC unmount"
echo
- chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS start
- check
}
-stop ()
+start ()
{
- if mounted $PLC_ROOT ; then
- chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS stop
- check
+ # Starting everything
+ if [ -z "$1" ] ; then
+ mount_plc
fi
+ chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS start $*
+ check
+}
+
+umount_plc ()
+{
echo -n $"Unmounting PLC: "
for dir in $PLC_ROOT/proc $PLC_ROOT/data $PLC_ROOT ; do
echo
}
-case "$1" in
+stop ()
+{
+ if mounted $PLC_ROOT ; then
+ chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS stop $*
+ check
+ fi
+
+ # Stopped everything
+ if [ -z "$1" ] ; then
+ umount_plc
+ fi
+}
+
+mountstatus_plc ()
+{
+ for dir in $PLC_ROOT/proc $PLC_ROOT/data $PLC_ROOT ; do
+ if mounted $dir ; then
+ echo $dir
+ fi
+ done
+}
+
+# safestop : tries to stop normally; if that fails, kills processes that are still using /plc
+# needs the lsof rpm in the root context (should be a dependency of the myplc spec)
+function check_command ()
+{
+ command=$1; shift
+ found=$(type -p $command)
+ if [ -z "$found" ] ; then
+ echo "$COMMAND : requires command $command, was not found - exiting"
+ exit 1
+ fi
+}
+
+
+### when process stil use /plc/root, we cannot umount it
+function kill_all ()
+{
+ [ -n "$DEBUG" ] && set -x
+ check_command lsof
+
+ echo -n "Killing processes using $PLC_ROOT and $PLC_DATA: "
+ # initialize process list
+ former_process_list="unlikely"
+
+ # we ignore unknown uids for now, since we run in the chroot jail anyway
+ # not too sure about that though,
+ while true; do
+ # get the list of processes - collapse and remove empty lines
+ process_list=$(lsof -t +D $PLC_ROOT +D $PLC_DATA)
+ if [ -z "$process_list" ] ; then
+ # we are done, let's bail out
+ success "$PLC_ROOT clear" ; echo ; return
+ fi
+ if [ "$process_list" = "$former_process_list" ] ; then
+ # we are stuck, no progress since last time : exit on error
+ failure "$PLC_ROOT locked" ; echo ; return
+ fi
+ # record for next loop
+ former_process_list="$process_list"
+ # kill them
+ kill $process_list
+ sleep 2
+ # check there are dead
+ for pid in $process_list ; do
+ ps -o pid $pid &> /dev/null
+ if [ "$?" = 0 ] ; then
+ [ -n "$DEBUG" ] && echo "$pid survived kill - forcing kill -9"
+ kill -9 $pid
+ fi
+ done
+ done
+}
+
+# Get command
+shift $(($OPTIND - 1))
+command=$1
+
+# Get step(s)
+shift 1
+
+case "$command" in
start|stop)
- $1
+ $command $*
;;
restart)
- stop
- start
+ stop $*
+ ERRORS=0
+ start $*
+ ;;
+
+ reload)
+ chroot $PLC_ROOT /sbin/service plc $PLC_OPTIONS reload $*
+ ;;
+
+ mount|umount|mountstatus)
+ ${command}_plc
;;
+ kill)
+ kill_all
+ ;;
+
+ safestop)
+ stop
+ ### Checking : we might need to run kill
+ mounted=$(mountstatus_plc)
+ if [ -n "$mounted" ] ; then
+ echo "Umount failed : killing remaining processes and trying again"
+ ERRORS=0
+ kill_all
+ ERRORS=0
+ stop
+ fi
+ ;;
+
*)
- echo "Usage: $0 {start|stop|restart}"
+ echo "Usage: $0 {start|stop|restart|reload|mount|umount|mountstatus|kill|safestop}"
RETVAL=1
;;
esac