#!/bin/sh
#
# License:      GNU General Public License (GPL)
# Support:      linux-ha@lists.linux-ha.org
# 
# 
# WARNING: this script is for CTS testing only.
#
# This script support master-slave operations
# 

. /usr/lib/heartbeat/ocf-shellfuncs

AWK=gawk
GREP=grep
PS="ps -o pid= -o args= -C "

CRM_MASTER="/usr/sbin/crm_master"
#DUMMY_RESOURCE=/usr/lib/ocf/resource.d//heartbeat/OCFMSDummy
DUMMY_RESOURCE=/usr/lib/heartbeat/cts/OCFMSDummy

start_delay=1

stop_delay=1
monitor_delay=1
promote_delay=1
demote_delay=1
notify_delay=1

do_cmd() {
    local cmd="$*"
    ocf_log debug "$RESOURCE: Calling $cmd"
    local cmd_out=$($cmd 2>&1)
    ret=$?

    if [ $ret -ne 0 ]; then
            ocf_log err "$RESOURCE: Called $cmd"
            ocf_log err "$RESOURCE: Exit code $ret"
            ocf_log err "$RESOURCE: Command output: $cmd_out"
    else
            ocf_log debug "$RESOURCE: Exit code $ret"
            ocf_log debug "$RESOURCE: Command output: $cmd_out"
    fi

    echo $cmd_out
    return $ret
}


dummy_get_status() {
    instance=$1
    basename=`basename $DUMMY_RESOURCE`
    result=`$PS $basename`
    echo $result | $GREP -e "$basename.*#$instance" >/dev/null 
    running=$?

    if [ ! $running -eq 0 ]; then
         ocf_log info "status: instance #$instance not running"
         return $OCF_NOT_RUNNING
    fi
    echo $result | $GREP -e "master #$instance" >/dev/null
    state=$?


    if [ $state -eq 0 ]; then    # master
        ocf_log info "status: instance #$instance is running as master"
        return $OCF_RUNNING_MASTER
    else        # slave
        ocf_log info "status: instance #$instance is running as slave"
        return $OCF_SUCCESS
    fi 
}


do_start_resource () {
    instance=$1
    request_state=$2
    #stop resource
    do_stop_resource $instance
    #execute resource 
    $DUMMY_RESOURCE $request_state "#$instance" &
    return $OCF_SUCCESS
}

# stop, delete instance from the file
do_stop_resource () {
    tmp=`mktemp`
    instance=$1
    basename=`basename $DUMMY_RESOURCE`
    $PS $basename > $tmp 
    pids=`$GREP -e "$basename.*#$instance" $tmp | $AWK '{print $1}'`
    rm -f $tmp

    for pid in $pids; do
        ocf_log info "trying to kill pid $pid (instance #$instance)"
        kill -9 $pid
    done
    return $OCF_SUCCESS
}

do_change_state() {
    instance=$1
    request_state=$2
    ocf_log info "before state changed: "
    dummy_get_status $instance
    # not running, can't promote
    if [ $? -eq $OCF_NOT_RUNNING ] ;then
        ocf_log info "instance #$instance not running, can't change state"
        return $OCF_ERROR;
    fi
    do_stop_resource $instance
    do_start_resource $instance $request_state
    rc=$?
    ocf_log info "after state changed: "
    dummy_get_status $instance
    return $rc
}


dummy_start() {
    ocf_log info "start instance #$OCF_RESKEY_CRM_meta_clone slave"
    do_start_resource $OCF_RESKEY_CRM_meta_clone "slave"
    if [ $OCF_RESKEY_CRM_meta_clone -eq 0 ]; then
        do_cmd $CRM_MASTER -v 1000
    fi
    sleep $start_delay
    return $OCF_SUCCESS
}

dummy_stop() {
    touch $DUMMY_RESOURCE
    ocf_log info "stop instance #$OCF_RESKEY_CRM_meta_clone"
    do_stop_resource $OCF_RESKEY_CRM_meta_clone
    rc=$?
    sleep $stop_delay
    return $rc
}

dummy_monitor() {
    ocf_log info "monitor instance #$OCF_RESKEY_CRM_meta_clone"
    dummy_get_status $OCF_RESKEY_CRM_meta_clone
    rc=$?
    sleep $monitor_delay
    return $rc
}

dummy_promote() {
    ocf_log info "promote instance #$OCF_RESKEY_CRM_meta_clone"
    do_change_state $OCF_RESKEY_CRM_meta_clone "master"
    rc=$?
    sleep $promote_delay
    return $rc
}

dummy_demote() {
    ocf_log info "demote instance #$OCF_RESKEY_CRM_meta_clone"
    do_change_state $OCF_RESKEY_CRM_meta_clone "slave"
    rc=$?
    sleep $demote_delay
    return $rc
}

dummy_notify() {
    ocf_log info "notify instance #$OCF_RESKEY_CRM_meta_clone"
    touch $DUMMY_RESOURCE
    sleep $notify_delay
        local n_type="$OCF_RESKEY_CRM_meta_notify_type"
        local n_op="$OCF_RESKEY_CRM_meta_notify_operation"
        set -- $n_active_resource
        local n_active="$#"
        set -- $notify_stop_resource
        local n_stop="$#"
        set -- $notify_start_resource
        local n_start="$#"

        ocf_log debug "$RESOURCE notify: $n_type for $n_op - counts: active $n_active - starting $n_start - stopping $n_stop"
        case $n_type in
            pre)
                case $n_op in
                    promote) # TODO:
                             # Resist promotion of the other side in case we
                             # are already primary - though the CRM should
                             # not even attempt that.
                            ;;
                esac
                      ;;
            post)
                case $n_op in
                    start)
                              ;;
                      # TODO: Does "fence" actually happen?
                     stop|fence)
                              # This MUST be a notification for the other side
                              # having been stopped, because for sure we won't
                              # receive one for ourselves being stopped ;-)
                              # So to allow continuing with freeze_io, we need
                              # to explicitly disconnect.
                              ;;
                     monitor)
                              # TODO: We don't get notifications for failed
                              # monitors yet.
                              ;;
                  esac
                  ;;
       esac
       return $OCF_SUCCESS
}


dummy_resource_run_loop (){
	while [ 1 ]; do
		sleep 3
	done
}

usage ()
{
	echo "OCFMSDummy start|stop|monitor|promote|demote|notify"
}
case $__OCF_ACTION in
    start)   dummy_start   ;;
    stop)    dummy_stop    ;;
    monitor) dummy_monitor ;;
    promote) dummy_promote ;;
    demote)  dummy_demote  ;;
    notify)  dummy_notify  ;;

# not RA operations
# master and slave are resource operations. 
    master)  dummy_resource_run_loop ;;
    slave)   dummy_resource_run_loop ;;
    *) usage $__OCF_ACTION
       exit $OCF_ERR_ARGS ;;
esac
