#!/bin/sh
#
# External STONITH module for Xen Dom0 through ssh.
#
# Description:  Uses Xen Dom0 Domain as a STONITH device
#               to control DomUs.
#
#
# Author:       Serge Dubrouski (sergeyfd@gmail.com)
#               Inspired by Lars Marowsky-Bree's external/ssh agent.
#
# Copyright 2007 Serge Dubrouski <sergeyfd@gmail.com>
# License:      GNU General Public License (GPL)
#

#echo "$(date): $*" >> /tmp/xen0.out

SSH_COMMAND="/usr/bin/ssh -q -x -n -l root"
STOP_COMMAND="xm destroy"
START_COMMAND="xm create"
DEFAULT_XEN_DIR="/etc/xen"

# Rewrite the hostlist to accept "," as a delimeter for hostnames too.
hostlist=`echo $hostlist | tr ',' ' '`

CheckIfDead() {
    for j in 1 2 3 4 5
    do
        if ! ping -w1 -c1 "$1" >/dev/null 2>&1
        then
            return 0
        fi
        sleep 1
    done
    
    return 1
}

CheckHostList() {
    if [ "x" = "x$hostlist" ]
    then
        echo "hostlist isn't set"
        exit 1
    fi
}

RunCommand() {
    CheckHostList
    
    for h in $hostlist
    do
        CIFS=$IFS
        IFS=:
        read node xen0 cfg << -!
$h
-!
        IFS=$CIFS

        if [ "x" = "x$node" -o "x" = "x$xen0" ]
        then
            echo "Syntax error in host list"
            exit 1
        fi
        
        if [ "x" = "x$cfg" ]
        then
            cfg="${DEFAULT_XEN_DIR}/${node}.cfg"
        fi
        
        if [ "$node" != "$1" ]
        then
            continue
        fi
          
        case $2 in
            stop)
                $SSH_COMMAND $xen0 "(sleep 2; $STOP_COMMAND $node) >/dev/null 2>&1 &"
                break;;
            start)
                echo $cfg
                $SSH_COMMAND $xen0 "(sleep 2; $START_COMMAND $cfg) >/dev/null 2>&1 &"
                break;;
        esac
        exit 0
    done
}


# Main code	
case $1 in
gethosts)
    CheckHostList
    
    for h in $hostlist ; do
        CIFS=$IFS
        IFS=:
        read node xen0 cfg << -!
$h
-!
        IFS=$CIFS

        echo $node
    done
    exit 0
	;;
on)
    RunCommand $2 start
	exit $?
	;;
off)
    if RunCommand $2 stop
    then
        if CheckIfDead $2
        then 
            exit 0
        fi
    fi
           
	exit 1
	;;
reset)
	RunCommand $2 stop
        
    if CheckIfDead $2
    then
        RunCommand $2 start 
        exit 0
    fi

	exit 1
	;;
status)
    CheckHostList
    
	for h in $hostlist
	do
        CIFS=$IFS
        IFS=:
        read node xen0 cfg << -!
$h
-!
        IFS=$CIFS
        
        echo $node
	    if ping -w1 -c1 "$node" 2>&1 | grep "unknown host"
        then
	        exit 1
	    fi
	done
	exit 0
	;;
getconfignames)
	echo "hostlist"
	exit 0
	;;
getinfo-devid)
	echo "xen0 STONITH device"
	exit 0
	;;
getinfo-devname)
	echo "xen0 STONITH external device"
	exit 0
	;;
getinfo-devdescr)
	echo "ssh-based Linux host reset for Xen DomU trough Dom0"
	echo "Fine for testing, but not really suitable for production!"
	exit 0
	;;
getinfo-devurl)
	echo "http://openssh.org http://www.xensource.com/"
	exit 0
	;;
getinfo-xml)
	cat << SSHXML
<parameters>
<parameter name="hostlist" unique="1" required="1">
<content type="string" />
<shortdesc lang="en">
Hostlist
</shortdesc>
<longdesc lang="en">
The list of controlled nodes in a format node:xen0[:config_file]
For example: "node1:xen01:/etc/xen/node1.cfg node2:xen02"
</longdesc>
</parameter>
</parameters>
SSHXML
	exit 0
	;;
*)
	exit 1
	;;
esac
