#!/usr/bin/bash # /usr/libexec/scoutfs-fenced/run/powerman-remote-host # powerman configuration SCOUTFS_PM_CONFIG_FILE=${SCOUTFS_PM_CONFIG_FILE:-/etc/scoutfs/scoutfs-pm.conf} SCOUTFS_PM_HOSTS_FILE=${SCOUTFS_PM_HOSTS_FILE:-/etc/scoutfs/scoutfs-pm-hosts.conf} ## hosts file format ## SCOUTFS_HOST_IP POWERMAN_NODE_NAME ## ex: # 192.168.1.1 dm1 # command setup PM_CMD="/usr/bin/pm" SSH_CMD="ssh -o ConnectTimeout=3 -o BatchMode=yes -o StrictHostKeyChecking=no" LOGGER="/bin/logger -p local3.crit -t scoutfs-fenced" $LOGGER "ipmi fence script invoked: IP: $SCOUTFS_FENCED_REQ_IP RID: $SCOUTFS_FENCED_REQ_RID TEST: $IPMITEST" echo_fail() { echo "$@" >&2 $LOGGER "fence failed: $@" exit 1 } echo_log() { echo "$@" >&2 $LOGGER "fence info: $@" } echo_test_pass() { echo -e "\xE2\x9C\x94 $@" } echo_test_fail() { echo -e "\xE2\x9D\x8C $@" } test -n "$SCOUTFS_PM_CONFIG_FILE" || \ echo_fail "SCOUTFS_PM_CONFIG_FILE isn't set" test -r "$SCOUTFS_PM_CONFIG_FILE" || \ echo_fail "$SCOUTFS_PM_CONFIG_FILE isn't readable file" . "$SCOUTFS_PM_CONFIG_FILE" test -n "$SCOUTFS_PM_HOSTS_FILE" || \ echo_fail "SCOUTFS_PM_HOSTS_FILE isn't set" test -r "$SCOUTFS_PM_HOSTS_FILE" || \ echo_fail "$SCOUTFS_PM_HOSTS_FILE isn't readable file" test -x "$PM_CMD" || \ echo_fail "$PMCMD not found, need to install powerman?" export ip="$SCOUTFS_FENCED_REQ_IP" fence_rid="$SCOUTFS_FENCED_REQ_RID" getPMhost () { host=$(awk -v ip="$1" '$1 == ip {print $2}' "$SCOUTFS_PM_HOSTS_FILE") || \ echo_fail "lookup pm host failed" echo "$host" } powerOffHost() { $PM_CMD $PM_OPTS "$1" -0 || \ echo_fail "pm power off $host failed" pmoutput=$($PM_CMD $PM_OPTS "$1" -q | grep "$1") || \ echo_fail "powerman power stat $1 failed" if [[ ! "$pmoutput" =~ off ]]; then echo_fail "powerman stat $1 not off" fi $LOGGER "powerman fence power down $1 success" exit 0 } if [ -n "$PMTEST" ]; then for i in $(awk '!/^($|[[:space:]]*#)/ {print $1}' "$SCOUTFS_PM_HOSTS_FILE"); do if ! $SSH_CMD "$i" /bin/true; then echo_test_fail "ssh $i" else echo_test_pass "ssh $i" fi host=$(getPMhost "$i") if [ -z "$host" ]; then echo_test_fail "pm config $i $host" else if ! $PM_CMD $PM_OPTS "$host" -q; then echo_test_fail "pm $i" else echo_test_pass "pm $i" fi fi done exit 0 fi if [ -z "$ip" ]; then echo_fail "no IP given for fencing" fi host=$(getPMhost "$ip") if [ -z "$host" ]; then echo_fail "no host found for fence IP" fi # first check via ssh if the mount still exists # if ssh succeeds, we will only power down the node if mounted if ! output=$($SSH_CMD "$ip" "echo BEGIN; LC_ALL=C egrep -m 1 '(^0x*|^$rid$)' /sys/kernel/boot_params/version /sys/fs/scoutfs/f*r*/rid; echo END"); then # ssh not working, just power down host powerOffHost "$host" fi if [[ ! "$output" =~ BEGIN ]]; then # ssh failure echo_log "no BEGIN" powerOffHost "$host" fi if [[ ! "$output" =~ \/boot_params\/ ]]; then # ssh failure echo_log "no boot params" powerOffHost "$host" fi if [[ ! "$output" =~ END ]]; then # ssh failure echo_log "no END" powerOffHost "$host" fi if [[ "$output" =~ "rid:$rid" ]]; then # rid still mounted, power down echo_log "rid $rid still mounted" powerOffHost "$host" fi $LOGGER "powerman fence host $ip/$host success (rid $rid not mounted)" exit 0