#!/bin/bash
#
# Description: Stonith Plugin Wrapper
# Version: 1.0
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# Version:      1.00    (2009/09/01)
# Copyright (c) 2009 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
#
#######################################################################

command_name=${0##*/}
command_args=("$@")
real_plugin=${real_plugin=ibmrsa-telnet}
admins_direction=/var/run/heartbeat/rsctmp/${command_args[1]}_stopped

savelog()
{
    typeset level=$1
    shift

    msg=$(echo "$command_name[$$]:"; 
	date '+%Y/%m/%d_%H:%M:%S'; echo "$level:" "$@")
    echo $msg >> /var/log/ha-debug
    if [[ "$level" != "debug" ]] &&  [[ "$level" != "DEBUG" ]]; then
	echo $msg >> /var/log/ha-log
    fi
}

kill_and_exit()
{
    typeset status=$1
    kill %1
    shift
    savelog debug "Leave: exitcd=$status : ${command_args[@]} : $@"
    exit $status
}

ok_if_admin_judges_so()
{
    if [[ -f $admins_direction ]]; then
	savelog info "admins decision is accepted"
	rm -f $admins_direction
	kill_and_exit 0 $FUNCNAME $LINENO
    fi
}

quit_if_timed_out()
{
    typeset waitsec=$1
    typeset pgid=$2
    exec -a quit_if_timed_out perl -e "sleep $waitsec; kill -9, $pgid;" &
    if [[ $? != 0 ]]; then
	savelog err "exec quit_if_timed_out failed"
	exit 1
    fi
}

ok_if_target_died()
{
    typeset ip_of_target
    typeset vname

    for vname in ${!nodeip*}; do
	eval ip_of_target=\$$vname
	if ping -w3 -c1 "$ip_of_target" >/dev/null 2>&1; then
	    savelog info "$ip_of_target" responded
	    return
	else
	    savelog info "$ip_of_target" do not responded
	fi
    done

    kill_and_exit 0 $FUNCNAME $LINENO
}

check_sby_using_mount()
{
    if grep -q "$device" /proc/mounts; then
	savelog info "this node is active"
	return 1
    else
	savelog info "this node is standby"
	return 0
    fi
}


check_sby_using_sfex()
{
    typeset SFEX_STAT
    typeset status

    if   [[ -x /usr/lib64/heartbeat/sfex_stat ]]; then
	SFEX_STAT=/usr/lib64/heartbeat/sfex_stat
    elif [[ -x /usr/lib/heartbeat/sfex_stat ]]; then
	SFEX_STAT=/usr/lib/heartbeat/sfex_stat
    else
	savelog err "Unable to use sfex_stat"
	return 1
    fi
    $SFEX_STAT -i "$index" "$device" >/dev/null 2>&1
    status=$?
    savelog info "sfex_stat: status=$status"

    if [[ "$status" = 0 ]]; then
	return 1
    else
	return 0
    fi
}

check_if_sby()
{
    if [[ "$no_sfex" = "true" ]]; then
	check_sby_using_mount
	return $?
    else
	check_sby_using_sfex
	return $?
    fi
}

become_leader()
{
    exec perl -e 'setpgrp; exec @ARGV' "$@"
    if [[ "$?" != 0 ]]; then
	savelog exec "Unable to become leader"
	exit 1
    fi
}

is_this_leader()
{
    typeset mypgid
    mypgid=$(ps --no-headers -o '%r' $$)
    mypgid=${mypgid##* }
    if [[ "$mypgid" == $$ ]]; then
	return 0
    fi
    return 1
}

check_parameters()
{
    if [[ -z "$start_timeout" ]]; then
	savelog err "start_timeout is not defined:'$start_timeout'"
	exit 1
    fi

    if [[ -z "$status_timeout" ]]; then
	savelog err "status_timeout is not defined:'$status_timeout'"
	exit 1
    fi

    if [[ -z "$control_timeout" ]]; then
	savelog err "control_timeout is not defined:'$control_timeout'"
	exit 1
    fi

    if [[ -z "$sby_wait" ]]; then
	savelog err "sby_wait is not defined:'$sby_wait'"
	exit 1
    fi
}

if ! is_this_leader; then
    become_leader $0 "$@"
fi

savelog debug "Enter: $@"


case "$1" in
    gethosts)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    on)
	check_parameters
	quit_if_timed_out $control_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    off|reset)
	check_parameters
	quit_if_timed_out $control_timeout $$
	ok_if_admin_judges_so
	ok_if_target_died

	if check_if_sby; then
	    savelog info "sby_wait($sby_wait)"
	    sleep $sby_wait
	fi

	${0%/*}/$real_plugin "$@"

	while true; do
	    ok_if_admin_judges_so
	    ok_if_target_died
	    sleep 1
	done
	;;
    status)
	check_parameters
	quit_if_timed_out $status_timeout $$
	if ! ${0%/*}/$real_plugin "$@"; then
	    savelog err "$real_plugin failed to do status action"
	fi
	kill_and_exit 0
	;;
    getconfignames)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    getinfo-devid)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    getinfo-devname)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    getinfo-devdescr)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    getinfo-devurl)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    getinfo-xml)
	quit_if_timed_out $start_timeout $$
	${0%/*}/$real_plugin "$@"
	kill_and_exit $?
	;;
    *)
	exit 1
	;;
esac

# vim: set ai ts=8 sw=4:
