Hi,
I would like to submit a libvirt based stonith plugin for review and
possible inclusion to glue.
The plugin uses the client of libvirtd (i.e. virsh) _in the virtual
machines_ and connects remotely to libvirtd on the hypervisor.
Therefore is works with whatever transport or hypervisor that libvirt
supports or will support.

Thanx
Holger



#!/bin/sh
#
# External STONITH module for a libvirt managed hypervisor (kvm/Xen).
# Uses libvirt as a STONITH device to control guest.
#
# Copyright (c) 2010 Holger Teutsch <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like.  Any license provided herein, whether implied or
# otherwise, applies only to this software file.  Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

# start a domain
libvirt_start() {
    out=$($VIRSH -c $hypervisor_uri start $domain_id 2>&1)
    if [ $? -eq 0 ]
    then
        ha_log.sh notice "Domain $domain_id was started"
        return 0
    fi

    if echo "$out" | grep -i 'Domain is already active' > /dev/null 2>&1
    then
        ha_log.sh notice "Domain $domain_id is already active"
        return 0
    fi

    ha_log.sh err "Failed to start domain $domain_id"
    ha_log.sh err "$out"
    return 1
}

# stop a domain
# return
#   0: success
#   1: error
#   2: was already stopped
libvirt_stop() {
    out=$($VIRSH -c $hypervisor_uri destroy $domain_id 2>&1)
    if [ $? -eq 0 ]
    then
        ha_log.sh notice "Domain $domain_id was stopped"
        return 0
    fi

    if echo "$out" | grep -i 'domain is not running' > /dev/null 2>&1
    then
        ha_log.sh notice "Domain $domain_id is already stopped"
        return 2
    fi

    ha_log.sh err "Failed to stop domain $domain_id"
    ha_log.sh err "$out"
    return 1
}

# get status of stonith device (*NOT* of the domain).
# If we can retrieve the status of the domain at issue from the hypervisor
# the stonith device is OK.
libvirt_status() {
    out=$($VIRSH -c $hypervisor_uri domstate $domain_id 2>&1)
    if [ $? -eq 0 ]
    then
        ha_log.sh notice "$hypervisor_uri/$domain_id: $out"
        return 0
    fi

    ha_log.sh err "Failed to get status for $domain_id"
    ha_log.sh err "$out"
    return 1
}

# check config and set variables
# does not return on error
libvirt_check_config() {
    VIRSH=`which virsh 2>/dev/null`

    if [ ! -x "$VIRSH" ]
    then
        ha_log.sh err "virsh not installed"
        exit 1
    fi

    if [ -z "$hostname" -o -z "$hypervisor_uri" ]
    then
        ha_log.sh err "hostname or hypervisor_uri missing; check configuration"
        exit 1
    fi

    # default domain_id to hostname
    : ${domain_id:=$hostname}
}

libvirt_info() {
cat << LVIRTXML
<parameters>
<parameter name="hostname" unique="1" required="1">
<content type="string" />
<shortdesc lang="en">
Hostname
</shortdesc>
<longdesc lang="en">
Name of the controlled node.
</longdesc>
</parameter>

<parameter name="domain_id" unique="1">
<content type="string" />
<shortdesc lang="en">
Domain-id if the of the host.
</shortdesc>
<longdesc lang="en">
Domain-id of the host's virtual machine. Defaults to parameter hostname.
</longdesc>
</parameter>

<parameter name="hypervisor_uri" required="1">
<content type="string" />
<shortdesc lang="en">
Hypervisor URI
</shortdesc>
<longdesc lang="en">
URI for connection to the hypervisor.
driver[+transport]://[usern...@][hostname][:port]/[path][?extraparameters]
e.g.
qemu+ssh://my_kvm_server.mydomain.my/system   (uses ssh for root)
xen://my_kvm_server.mydomain.my/              (uses TLS for client)

virsh must be installed (e.g. libvir-client package) and access control must
be configured for your selected URI.
</longdesc>
</parameter>
</parameters>
LVIRTXML
exit 0
}

#############
# Main code #
#############

# don't fool yourself when testing with stonith(8)
# and transport ssh
unset SSH_AUTH_SOCK

case $1 in
    gethosts)
    echo $hostname
    exit 0
    ;;

    on)
    libvirt_check_config
    libvirt_start
    exit $?
    ;;

    off)
    libvirt_check_config
    libvirt_stop
    [ $? = 1 ] && exit 1
    exit 0
    ;;

    reset)
    # libvirt has no reset so we do power down
    # and power on (but only if it was before)
    libvirt_check_config
    libvirt_stop
    rc=$?
    [ $rc = 1 ] && exit 1
    [ $rc = 2 ] && exit 0

    sleep 2
    libvirt_start
    exit $?
    ;;

    status)
    libvirt_check_config
    libvirt_status
    exit $?
    ;;

    getconfignames)
    echo "hostname hypervisor_uri"
    exit 0
    ;;

    getinfo-devid)
    echo "libvirt STONITH device"
    exit 0
    ;;

    getinfo-devname)
    echo "libvirt STONITH external device"
    exit 0
    ;;

    getinfo-devdescr)
    echo "libvirt-based Linux host reset for Xen/KVM guest domain through 
hypervisor"
    exit 0
    ;;

    getinfo-devurl)
    echo "ihttp://libvirt.org/uri.html http://linux-ha.org/wiki";
    exit 0
    ;;

    getinfo-xml)
    libvirt_info
    echo 0;
    ;;

    *)
    exit 1
    ;;
esac



_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to