#!/bin/sh
#
#
#        Copyright (C) 2005 Horms <horms@verge.net.au>
#
# 	 License:      GNU General Public License (GPL)
# 	 Support:      linux-ha@lists.linux-ha.org
#
#        This script manages the LVS synchronisation daemon
#
#       Please note that as of 2.4.29, this is no longer needed
#       as both the master and backup daemon can run simultaneously
#
#        usage: $0 {master|backup} {interface} {start|stop|status|monitor|cleanup}
#
#        The first argument, master or backup, is the YING.
#        The YANG is internally calculated to be which ever or master and
#        backup YING is not.
#
#       e.g $0 LVSSyncDaemonSwap master start   # YING=master YANG=backup
#           $0 LVSSyncDaemonSwap backup start   # YING=backup YANG=master
#               
#
#       "start" will stop the YANG if it is running and starts the YING
#       "stop"  will stop the YING if it is running and starts the YANG
#       "cleanup" is a non-standard target stop the YING if it is running
#                 an stop the YANG if it is running 
#
#
#
unset LANG
LC_ALL=C
export LC_ALL

prefix=@prefix@
exec_prefix=@exec_prefix@
. @sysconfdir@/ha.d/shellfuncs

USAGE="usage: $0 {master|backup} {interface} {start|stop|status|monitor|cleanup}\n\nNote: $0 only works on Linux";

# This is consistent with ldirectord's behaviour
# Except that this script does not have a debug mode
if [ -x "/sbin/ipvsadm" ]; then
	IPVSADM="/sbin/ipvsadm";
elif [ -x "/usr/sbin/ipvsadm" ]; then
	IPVSADM="/usr/sbin/ipvsadm";
else
	ha_log "ERROR: Can not find ipvsadm";
	exit 1
fi

IPVSADM_VERSION=$($IPVSADM --version | cut -d " " -f 2)

get_status() {
    if echo $PS | grep " \[ipvs[ _]sync$1\]$" > /dev/null; then
        echo "running"
        return 3
    fi

    echo "stopped"
    return 0
}

status() {
    echo -n "$1 "
    get_status $1
    RC=$?

    pid=$(echo "$PS" | sed -e '/ \[ipvs[ _]syncmaster\]$/!d' -e 's/^ *//' -e 's/ .*$//')
    if [ ! -z "$pid" ]; then
        echo "(ipvs_syncmaster pid: $pid)"
    fi

    pid=$(echo "$PS" | sed -e '/ \[ipvs[ _]syncbackup\]$/!d' -e 's/^ *//' -e 's/ .*$//')
    if [ ! -z "$pid" ]; then
        echo "(ipvs_syncbackup pid: $pid)"
    fi

    return $RC
}

run_ipvsadm () {
    $IPVSADM $@
    rc=$?
    if [ $rc -ne 0 ]; then
        echo "ERROR: ipvsadm $@ failed."
        return $rc
    fi

    return 0
}

ying_yan() {
    if [ "$1" = "master" ]; then
        echo "backup"
    else 
        echo "master"
    fi
}

start_stop() {
    YING=$1
    YANG=$2

    if [ $(get_status $YING) = "running" ]; then
        return 0
    fi

    if [ $(get_status $YANG) = "running" ]; then
        if [ "$IPVSADM_VERSION" = "v1.21" ]; then
            run_ipvsadm --stop-daemon || return $?
	else
            run_ipvsadm --stop-daemon $YANG || return $?
	fi
        ha_log "info: ipvs_sync$YANG down"
    fi

    run_ipvsadm --start-daemon $YING --mcast-interface=$IFACE || return $?

    ha_log "info: ipvs_sync$YING up"
    return 0
}

start() {
    start_stop $1 $(ying_yan $1) || return $?
    ha_log "info: ipvs_sync$YING obtained"
    return 0
}

stop() {
    start_stop $(ying_yan $1) $1 || return $?
    ha_log "info: ipvs_sync$YANG released"
    return 0
}

cleanup() {
    if [ $(get_status master) = "running" ]; then
            YING=master
    elif [ $(get_status backup) = "running" ]; then
            YING=backup
    else
        return 0
    fi

    
    run_ipvsadm --stop-daemon || return $?
    if [ "$IPVSADM_VERSION" = "v1.21" ]; then
        run_ipvsadm --stop-daemon || return $?
    else
        run_ipvsadm --stop-daemon $YANG || return $?
    fi
    ha_log "info: ipvs_sync$YING down"
    return 0
}

usage() {
  echo -e $USAGE >&2
}

if
    [ $# -lt 2 -o $# -gt 3 ]
then
    usage
    exit 1
fi

PS=$(ps ax | grep " \[ipvs[ _]sync")

if [ $# -eq 3 ]
then
    CMD=$3
    IFACE=$2
else
    CMD=$2
    IFACE=eth0
fi

case $CMD in
    start)
        start $1
        ;;
    stop)
        stop $1
        ;;
    status)
        status $1
        ;;
    monitor)
        status $1
        ;;
    cleanup)
        cleanup $1
        ;;
    *)
        usage
        exit 1
        ;;
esac

exit $?

