#!/bin/bash
#------------------------------------------------------------------------------
# /etc/init.d/xen - init script for xen
#
# Creation:     20.05.05  fw
# Last Update:  $Id$
#
# Copyright (c) 2005 Fabian Wolter <fabian@eisfair.org>
# Copyright (c) 2005 Keir Fraser <keir.fraser@cl.cam.ac.uk>
#
# 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.
#------------------------------------------------------------------------------

. /var/install/include/eislib
. /etc/config.d/xen

vmsconfig=/etc/xen/xm
netsave=/etc/xen/netsave

mkdir -p $netsave

if xend status >/dev/null >&2
then
    xendRunning="yes"
else
    xendRunning="no"
fi

if ifconfig 2>/dev/null | grep -q xen
then
    netRunning="yes"
else
    netRunning="no"
fi

# doesn't work reliably
# if xm list 2>/dev/null | grep -q -- '-b-'
# then
#     domainUp="yes"
# else
#     domainUp="no"
# fi

await_daemons_up() {
    idx=1
    rets=10
    ps ax | grep xend | grep -v -q grep
    while [ $? -ne 0 -a $idx -lt $rets ]; do
        sleep 1
        mecho -n -info "."
        idx=`expr $idx + 1`
        ps ax | grep xend | grep -v -q grep
    done
}

start_vms() {
    mecho -info "Starting Xen domains ..."

    idx=1
    while [ $idx -le $XEN_VM_N ]
    do
        eval name='$XEN_VM_'$idx'_NAME'
        eval auto='$XEN_VM_'$idx'_AUTO_START'

        if [ "$auto" = "yes" ]
        then
            xm create $vmsconfig$name
            if [ $? -ne 0 ]
            then
                mecho -error "Domain '`basename $name`' failed to boot"
            fi
        fi
        idx=`expr $idx + 1`
    done
    echo
}

stop_vms() {
    # NB. this shuts down ALL Xen domains (politely), not just the ones in
    # AUTODIR/*
    # This is because it's easier to do ;-) but arguably if this script is run
    # on system shutdown then it's also the right thing to do.

    mecho -info "Shutting down all Xen domains ..."

    xm shutdown --all --wait --halt
}

networking() {
    if [ "$1" = "start" ]
    then
        idx=1
        while [ $idx -le $XEN_BRIDGE_N ]
        do
            eval netdev='$XEN_BRIDGE_'$idx'_BIND_DEVS'

            bridge=xenbr`expr $idx - 1`
            vifnum=`expr $idx - 1`

            if [ "$netdev" = "" -a "$1" = "start" ]
            then
                if ! lsmod | grep -q dummy
                then
                    modprobe dummy numdummies=10
                fi

                if [ "$1" = "start" ]
                then
                    devid=0
                    while ifconfig | grep -q dummy$devid && ifconfig | grep -q pdummy$devid
                    do
                        devid=`expr $devid + 1`
                    done

                    netdev=dummy$devid

                    ifconfig $netdev up
                fi
            fi

            echo $vifnum $netdev >$netsave/$bridge

            set -x
            /etc/xen/scripts/network-bridge "$@" vifnum=$vifnum netdev=$netdev bridge=$bridge
            set +x

            idx=`expr $idx + 1`
        done
    else
        devid=0
        while ifconfig | grep -q xenbr$devid
        do
            read vifnum netdev < $netsave/xenbr$devid
            rm $netsave/xenbr$devid

            set -x
            /etc/xen/scripts/network-bridge "$@" vifnum=$vifnum netdev=$netdev bridge=xenbr$devid
            set +x

            devid=`expr $devid + 1`
        done
    fi
}

hide_pci_devices () {
    idx=1
    while [ $idx -le $XEN_VM_N ]
    do
        eval name='$XEN_VM_'$idx'_NAME'
        eval pci_n='$XEN_VM_'$idx'_PCI_N'

        idx2=1
        while [ $idx2 -le $pci_n ]
        do
            eval id='$XEN_VM_'$idx'_PCI_'$idx2'_ID'

            if lspci | grep -q "^$id "
            then
                echo -n $id > /sys/bus/pci/drivers/pciback/new_slot
                echo -n $id > /sys/bus/pci/drivers/pciback/bind
            else
                mecho -error "The PCI ID XEN_VM_"$idx"_PCI_"$idx2"_ID='$id' doesn't exist!"
            fi

            idx2=`expr $idx2 + 1`
        done

        if echo $name | grep -q asterisk
        then
            echo Y >/sys/module/pciback/parameters/permissive
        fi

        idx=`expr $idx + 1`
    done
}

remove_hidden_pci_devices () {
    while read id
    do
        echo -n $id > /sys/bus/pci/drivers/pciback/unbind
        echo -n $id > /sys/bus/pci/drivers/pciback/remove_slot
    done < /sys/bus/pci/drivers/pciback/slots
}

case "$1" in
  start)
    if [ "$START_XEN" = "yes" ]
    then
        if [ "$xendRunning" = "no" ]
        then
            mecho -info -n "Starting Xend ..."
            xend start
            await_daemons_up
            echo
        else
            mecho -error "Xend is already running"
        fi

        xm mem-set 0 $XEN_DOM0_MEM

        #mecho -info "Starting Xen webinterface ..."
        #xensv start

        if [ $XEN_VM_N -gt 0 ]
        then
            hide_pci_devices

            if [ "$netRunning" = "no" ]
            then
                mecho -info "Starting Xen networking ..."

                networking start
            else
                mecho -error "Networking is already started"
            fi

            #if [ "$domainUp" = "no" ]
            #then
                start_vms
            #else
            #    mecho -error "Domains already started:"
            #    xm list
            #fi
        fi
    else
        mecho -error "START_XEN is set to 'no'"
    fi
    ;;
  startxend)
    mecho -info -n "Starting Xend ..."
    xend start
    await_daemons_up
    ;;
  startnet)
    mecho -info "Starting networking ..."
    networking start
    ;;
  stop)
    if [ "$xendRunning" = "yes" ]
    then
        stop_vms
    else
        mecho -error "No domain is running"
    fi

    #mecho -info "Stopping Xen webinterface ..."
    #xensv stop

    if [ "$netRunning" = "yes" ]
    then
        mecho -info "Stopping Xen networking ..."
        networking stop
    else
        mecho -error "Networking is not running"
    fi

    remove_hidden_pci_devices

    if [ "$xendRunning" = "yes" ]
    then
        mecho -info "Stopping Xend ..."
        xend stop
    else
        mecho -error "Xend is not running"
    fi
    ;;
  status)
    if [ "$xendRunning" = "yes" ]
    then
        mecho -info "Xend is running"
        xm list

        exit 0
    else
        mecho -error "Xend is not running"

        exit 1
    fi

    if [ "$netRunning" = "yes" ]
    then
        mecho -info "Networking is running"
    else
        mecho -error "Networking is not running"
    fi
    ;;
  netstatus)
    if [ "$netRunning" = "yes" ]
    then
        mecho -info "Networking is running"
        exit 0
    else
        mecho -error "Networking is not running"
        exit 1
    fi
    ;;
  restart)
    echo "Stop and start Xen manually, to activate the new settings."
#     if [ "$xendRunning" = "yes" ]
#     then
#         mecho -info "Restarting xend ..."
#         xend restart
#         await_daemons_up
#         xm mem-set 0 $XEN_DOM0_MEM
#     else
#         mecho -error "Xend is not running"
#     fi
#
#     remove_hidden_pci_devices
#     hide_pci_devices

#     if [ "$netRunning" = "yes" ]
#     then
#         mecho -info "Restarting Xen networking ..."
#         networking stop
#         networking start
#     else
#         mecho -error "Networking is not running"
#     fi

    #mecho -info "Restarting xen webinterface (xensv) ..."
    #xensv stop
    #xensv start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
    exit 1
esac

exit $?