#!/bin/bash
#
# chkconfig: 345 70 8
# description: Loads and unloads the drbd module
#
# complete rewrite from scratch by Philipp Reisner in March and April 2001
# rewrite from scratch by Lars Ellenberg in June 2002
# Jan 2003: Moved all the logic into a program written in C.
# Oct 2005: Adopted for ALTLinux by LAKostis <lakostis at altlinux.org>
# Apr 2006: Fix drbd unconfigured state when using udevd (tnx to Christopher Boumenot) 
#

WITHOUT_RC_COMPAT=1

# source function library
. /etc/init.d/functions

LOCKFILE=/var/lock/subsys/drbd
RETVAL=0

DEFAULTFILE="/etc/default/drbd"
DRBDADM="/sbin/drbdadm"
PROC_DRBD="/proc/drbd"
MODPROBE="modprobe"
RMMOD="rmmod"
UDEV_TIMEOUT_ORIG=10
ADD_MOD_PARAM=""

if [ -f $DEFAULTFILE ]; then
  . $DEFAULTFILE
fi

test -f $DRBDADM || exit 5

function assure_module_is_loaded
{
    [ -e "$PROC_DRBD" ] && return

    $MODPROBE -s drbd `$DRBDADM sh-mod-parms` $ADD_MOD_PARAM || { 
	echo "Can not load the drbd module."$'\n'; exit 20 
    }
    # tell klogd to reload module symbol information ...
    [ -e /var/run/klogd.pid ] && [ -x /sbin/klogd ] && /sbin/klogd -i

    # make sure udev has time to create the device files
    RESOURCE=`$DRBDADM sh-resources` || exit 20
    RESOURCE=${RESOURCE%%\ *}
    DEVICE=`$DRBDADM sh-dev $RESOURCE` || exit 20

    for resource in `$DRBDADM sh-resources`; do
       for dev in `$DRBDADM sh-dev $resource`; do
           UDEV_TIMEOUT=$UDEV_TIMEOUT_ORIG
           while [ ! -e $dev ] && [ $UDEV_TIMEOUT -gt 0 ] ; do
                       sleep 1
                       UDEV_TIMEOUT=$(( $UDEV_TIMEOUT-1 ))
           done
       done
    done
}

function adjust_with_progress
{
    IFS_O=$IFS
    NEWLINE='
'
    IFS=$NEWLINE
    local D=0
    local S=0
    local N=0

    COMMANDS=`$DRBDADM -d adjust all` || exit 20
    echo -n "[ "

    for CMD in $COMMANDS; do 
	if echo $CMD | grep -q disk; then echo -n "d$D "; D=$(( D+1 )); 
	elif echo $CMD | grep -q syncer; then echo -n "s$S "; S=$(( S+1 )); 
	elif echo $CMD | grep -q net; then echo -n "n$N "; N=$(( N+1 ));
	else echo echo -n ".. ";
	fi
	IFS=$IFS_O
	$CMD || { 
	    echo -e "\ncmd $CMD failed!"; exit 20 
	}
	IFS=$NEWLINE
    done
    echo -n "]"

    IFS=$IFS_O
}

case "$1" in
    start)
	msg_starting $"Starting DRBD resources:    "
	assure_module_is_loaded
	adjust_with_progress
	[ -d "$LOCKFILE" ] && touch "$LOCKFILE"
	echo "."
	$DRBDADM wait_con_int # User interruptible version of wait_connect all
	;;
    reload)
	msg_reloading $"Reloading DRBD configuration"
	$DRBDADM adjust all
	echo "."
	;;
    restart|force-reload)
	echo -n "Restarting all DRBD resources"
	$DRBDADM down all
	$RMMOD drbd
	assure_module_is_loaded
	$DRBDADM up all
	echo "."
	;;
    stop)
	msg_stopping $"Stopping all DRBD resources"
	if [ -e $PROC_DRBD ] ; then
		$DRBDADM down all
		$RMMOD drbd
	fi
	[ -f "$LOCKFILE" ] && rm "$LOCKFILE"
	echo "."
	;;
    condstop)
    	if [ -e "$LOCKFILE" ]; then
    		stop
    	fi
    	;;
    condrestart)
    	if [ -e "$LOCKFILE" ]; then
    		restart
	fi
    	;;
    condreload)
    	if [ -e "$LOCKFILE" ]; then
    		reload
    	fi
    	;;
    status)
	# NEEDS to be heartbeat friendly...
	# so: put some "OK" in the output.
	if [ -e $PROC_DRBD ]; then
	    echo "drbd driver loaded OK; device status:"
	    cat $PROC_DRBD
	    exit 0
	else
	    echo >&2 "drbd not loaded"
	    exit 3
	fi
	;;
    *)
	msg_usage "${0##*/} {start|stop|reload|restart|force-reload|condstop|condrestart|condreload|status}"
	RETVAL=1
	;;
esac

exit $RETVAL

