# # 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 <&$wfd cat >&$wfd <&${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: