diff options
Diffstat (limited to 'tools/ocft/caselib.in')
-rw-r--r-- | tools/ocft/caselib.in | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/tools/ocft/caselib.in b/tools/ocft/caselib.in new file mode 100644 index 0000000..44165d6 --- /dev/null +++ b/tools/ocft/caselib.in @@ -0,0 +1,299 @@ +# +# Copyright (c) 2010-2011 Novell Inc, John Shi +# All Rights Reserved. +# +# 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + + +quit() +{ + local ret + ret="$1" + + while [ $__OCFT__atexit_num -gt 0 ]; do + atexit$__OCFT__atexit_num + let __OCFT__atexit_num-- + done + + rm -rf $__OCFT__fakebin + + exit $ret +} + +agent_install() +{ + local pkg + + if [ $# -eq 0 ]; then + return 0 + fi + + for pkg in "$@"; do + if [ -e /etc/SuSE-release ]; then + if ! zypper -q install -y "$pkg" >/dev/null 2>&1; then + echo + echo "${__OCFT__showhost}ERROR: Install '$pkg' failed." + quit 2 + fi + elif [ -e /etc/debian_version ]; then + if ! apt-get -y install "$pkg" >/dev/null 2>&1; then + echo + echo "${__OCFT__showhost}ERROR: Install '$pkg' failed." + quit 2 + fi + elif [ -e /etc/redhat-release ]; then + if ! yum -y install "$pkg" >/dev/null 2>&1; then + echo + echo "${__OCFT__showhost}ERROR: Install '$pkg' failed." + quit 2 + fi + else + echo "${__OCFT__showhost}ERROR: Cannot detect your OS type." + quit 2 + fi + done +} + +set_ocf_env() +{ + export OCF_RA_VERSION_MAJOR=1 + export OCF_RA_VERSION_MINOR=0 + export OCF_RESOURCE_TYPE=$1 + export OCF_RESOURCE_INSTANCE=${OCF_RESOURCE_INSTANCE:-"ocft"} +} + +agent_run() +{ + local agent cmd timeout pid i ret aroot + agent="$1" + cmd="$2" + timeout="$3" + + set_ocf_env $agent + + export OCF_RESKEY_CRM_meta_timeout + : ${OCF_RESKEY_CRM_meta_timeout:=$((timeout*1000))} + + aroot=${__OCFT__MYROOT:-$__OCFT__AGENT_ROOT} + + setsid $aroot/$agent $cmd >${HA_RSCTMP}/.ocft_runlog 2>&1 & + pid=$! + + i=0 + while [ $i -lt $timeout ]; do + if [ ! -e /proc/$pid ]; then + break + fi + sleep 1 + let i++ + done + + if [ $i -ge $timeout ]; then + kill -SIGTERM -$pid >/dev/null 2>&1 + sleep 3 + kill -SIGKILL -$pid >/dev/null 2>&1 + echo -n "${__OCFT__showhost}ERROR: The agent was hanging, killed it, " + echo "maybe you damaged the agent or system's environment, see details below:" + cat ${HA_RSCTMP}/.ocft_runlog + echo + quit 1 + fi + + wait $pid +} + +check_success() +{ + local ret msg + ret="$1" + msg="$2" + + if [ $ret -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: '${msg}' failed, the return code is ${ret}." + quit 1 + fi +} + +__maxfd() +{ + (echo 0; ls -1 /proc/$$/fd) | sort -rn | head -1 +} + +__getfd() +{ + local host rw fd file + host="$1" + rw="$2" + + for fd in /proc/$$/fd/*; do + file=$(basename "$(readlink $fd)") + if [ "$file" = "${host}_$rw" ]; then + basename $fd + break + fi + done +} + +backbash_start() +{ + local host fd rfd wfd + host="$1" + + if [ ! -d "$__OCFT__CASES_DIR" ]; then + echo "${__OCFT__showhost}ERROR: Could not found Directory: ${__OCFT__CASES_DIR}." + quit 1 + fi + + if lsof $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w >/dev/null 2>&1; then + echo "${__OCFT__showhost}ERROR: Connection exist with $host." + quit 1 + fi + if [ ! -p "$__OCFT__CASES_DIR/${host}_r" ] || [ ! -p "$__OCFT__CASES_DIR/${host}_w" ]; then + rm -f $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w + if ! mkfifo $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w >/dev/null 2>&1; then + echo "${__OCFT__showhost}ERROR: Could not create pipe file: $__OCFT__CASES_DIR/${host}_*." + quit 1 + fi + fi + + ssh root@$host '@BASH_SHELL@ 2>&1 + sed "s/00/001/g" ${HA_RSCTMP}/.backbash-log + echo 000 + echo 1' >$__OCFT__CASES_DIR/${host}_r <$__OCFT__CASES_DIR/${host}_w & + + fd=$(__maxfd) + rfd=$(expr $fd + 1) + wfd=$(expr $fd + 2) + eval "exec ${rfd}<$__OCFT__CASES_DIR/${host}_r ${wfd}>$__OCFT__CASES_DIR/${host}_w" +} + +backbash() +{ + local host rfd wfd ret + host="$1" + + rfd=$(__getfd $host r) + wfd=$(__getfd $host w) + + if [ -z "$rfd" -o -z "$wfd" ]; then + echo "${__OCFT__showhost}ERROR: Could not found connection with $host." + fi + + cat >&$wfd <<EOF +{ +true +EOF + cat >&$wfd + cat >&$wfd <<EOF + +} >&${HA_RSCTMP}/.backbash-log +sed 's/00/001/g' ${HA_RSCTMP}/.backbash-log +echo 000 +echo 0 +EOF + if [ $? -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: Broken connection with $host." + quit 1 + fi + + awk -vlive=2 '{ + if (sub(/000$/, "")) { + if ($0 != "") { + gsub("001", "00"); + printf("%s", $0); + } + getline live; + exit; + } + gsub("001", "00"); + print; + } END { + exit(live); + }' <&$rfd + case $? in + 1) + quit 1 + ;; + 2) + echo "${__OCFT__showhost}ERROR: Broken connection with $host." + quit 1 + ;; + esac +} + +backbash_stop() +{ + local host rfd wfd + host="$1" + + wfd=$(__getfd $host w) + if [ -n "$wfd" ]; then + cat >&$wfd <<<'quit 0' + fi + rm -f $__OCFT__CASES_DIR/${host}_r $__OCFT__CASES_DIR/${host}_w +} + + +export OCF_ROOT=@OCF_ROOT_DIR@ +export OCF_LIB=@OCF_LIB_DIR@/heartbeat +__OCFT__AGENT_ROOT=@OCF_RA_DIR@/heartbeat +__OCFT__CASES_DIR=/var/lib/@PACKAGE_NAME@/ocft/cases +OCFT_DIR=@datadir@/@PACKAGE_NAME@/ocft + +. $OCFT_DIR/helpers.sh + +__OCFT__atexit_num=0 + +if [ $EUID -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: '$0' needs to be run by root." + quit 3 +fi + +__OCFT__fakebin=./fakebin + +mkdir -p $__OCFT__fakebin >/dev/null 2>&1 && +ln -sf /bin/true $__OCFT__fakebin/crm_master >/dev/null 2>&1 && +ln -sf /bin/true $__OCFT__fakebin/crm_mon >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "${__OCFT__showhost}ERROR: initialize 'fakebin' failed." + quit 3 +fi +export HA_SBIN_DIR=$__OCFT__fakebin + +. $OCF_LIB/ocf-returncodes || { + echo "${__OCFT__showhost}ERROR: $OCF_LIB/ocf-returncodes not found." + quit 3 +} + +. $OCF_LIB/ocf-directories || { + echo "${__OCFT__showhost}ERROR: $OCF_LIB/ocf-directories not found." + quit 3 +} + +while read __OCFT__line; do + if [ -n "$__OCFT__line" ]; then + __OCFT__retn=${__OCFT__line%%=*} + __OCFT__reti=$(eval echo \$$__OCFT__retn) + __OCFT__retval[__OCFT__reti]=$__OCFT__retn + fi +done <<<"$(sed 's/#.*//' $OCF_LIB/ocf-returncodes)" + + +# vim:ts=2:sw=2:et: |