#!/bin/bash
#
# Secondary (Slave) Server
# Failover functions for ENBD + Fast RAID-1
#
# Author:	Steve Purkis <steve.purkis@multimap.com>
#		(derived work)
# Originals by:	Peter T. Breuer <ptb@it.uc3m.es>
#		Matthew Sackman <matthew@wellquite.org>
# License:	GNU GPL v2.1
#
# These scripts are for Red Hat machines.
# Designed to be used with Linux-HA (aka Heartbeat).

# Source RedHat function library.
. /etc/init.d/functions

FS_TYPE="ext2"
SHARED_DEVICE="/dev/hda8"
MOUNTPOINT="/usr/local/perforce"
MOUNT_OPTS=""

# Scenario 1 - Normal operation
start_secondary() {
    # TODO: sometimes heartbeat calls secondary start
    #       even when it doesn't need to...  check if
    #       $SHARED_DEVICE is mounted, maybe touch a file...
    is_device_mounted $SHARED_DEVICE
    ALREADY_MOUNTED=$?
    if [ $ALREADY_MOUNTED -eq 0 ]; then
    	echo "WARNING: Shared device $SHARED_DEVICE is already mounted - not continuing!"
    	return
    fi

    service enbd-server start
}

# Scenario 2 - Slave fails
stop_secondary() {
    service enbd-server stop
}

# Scenario 3 - Slave revived
# in pratice, this will never be called - heartbeat will just call start/stop
start_secondary_after_failure() {
    start_secondary
}

# Scenario 4 - Master fails
secondary_takeover_primary() {
    service enbd-server stop

    # TODO: make sure enbd-server has stopped

    fsck_shared_device
    mount_shared_device

    # Start services - TODO: move this to a 'enbd-functions' file
    service p4d start
    die_if_not_ok $? "Error starting P4D!"
}

# Scenario 5 - Master revived
secondary_giveback_primary() {
    # Stop services - TODO: move this to a 'enbd-functions' file
    service p4d stop

    umount_shared_device

    service enbd-server start
}


fsck_shared_device() {
    echo -n "Fsck'ing $FS_TYPE shared device $SHARED_DEVICE: "

    fsck -T -a -t $FS_TYPE $SHARED_DEVICE
    RETVAL=$?

    if [ $RETVAL -eq 1 ]; then
    	echo "NOTE: fsck corrected errors on $SHARED_DEVICE"
    else
	die_if_not_ok $RETVAL "Un-fixable errors encountered while fsck'ing $SHARED_DEVICE!"
    fi

    success
    echo
}

mount_shared_device() {
    is_device_mounted $SHARED_DEVICE
    ALREADY_MOUNTED=$?
    if [ $ALREADY_MOUNTED -eq 0 ]; then
    	echo "$DEVICE is already mounted"
    	return
    fi

    echo -n "Mounting shared device locally: "
    mount -t $FS_TYPE $SHARED_DEVICE $MOUNTPOINT $MOUNT_OPTS
    die_if_not_ok $? "Error mounting $SHARED_DEVICE --> $MOUNTPOINT!"
    success
    echo
}

umount_shared_device() {
    is_device_mounted $SHARED_DEVICE
    MOUNTED=$?

    if [ $MOUNTED -eq 0 ]; then
	# TODO: kick everybody off
	# fuser -muk $MOUNTPOINT

	echo -n "Unmounting shared device $SHARED_DEVICE: "
	umount $SHARED_DEVICE
	die_if_not_ok $? "Error unmounting $SHARED_DEVICE!"
	success
	echo
    else
    	echo "WARNING: Shared device $SHARED_DEVICE was not mounted!"
    fi
}

is_device_mounted() {
    DEVICE=$1
    MOUNTED=`mount | grep -c $DEVICE`
    # don't forget shell-stlye retvals
    if [ $MOUNTED -gt 0 ]; then
    	return 0
    else
    	return 1
    fi
}
