Warning: Undefined array key "REMOTE_USER" in /usr/home/www/www.seirios.org/seirios/dokuwiki/lib/plugins/googleanalytics/action.php on line 55
#! /bin/sh
#
# carp-hast-switch: shell script for change hast role when carp
# status is changed.
#
# Original script by Freddie Cash
# Modified by Michael W. Lucas
# and Viktor Petersson
# and HEO SeonMeyong
# Last modified 2015/11/10 HEO SeonMeyong
# ***WARNINGS***
# Need net.inet.carp.preempt=1 and same of advskew on carp.
# Currently HAST device must formatted by UFS
# ZFS code is impremented but not checked.
# This script is assumed to match the ZFS pool name and HAST resource name
##############################################################################
# Setting Variables and parse Arguments.
#DEBUG=1
SYSLOG_FACILITY="user.notice"
SYSLOG_TAG="carp-hast"
IF=${1%@*}
VHID=${1#*@}
ACTION=$2
# Work around for boot time. devd execute this script before start hastd.
[ ! `/bin/pgrep hastd` ] && exit
case "${ACTION}" in
MASTER|BACKUP|INIT)
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"State Changed. I/F: ${IF} VHID: ${VHID} state: ${ACTION}"
;;
*)
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: ${ACTION} is not yet implemented"
exit 1
;;
esac
##############################################################################
# Get resources.
HASTDEV=`/sbin/hastctl dump all | /usr/bin/grep resource | /usr/bin/sed -e 's/^.*:\ *//'`
[ "x"$DEBUG != "x" ] && echo "HASTDEV = ${HASTDEV}"
[ -z "${HASTDEV}" ] && exit 0 # no hast device.
# get all carp interfaces
ifs=`/sbin/ifconfig -l`
for i in ${ifs}; do
no_of_carp=`/sbin/ifconfig $i | /usr/bin/grep -c carp`
[ "x"$DEBUG != "x" ] && echo "Interface $i has ${no_of_carp} CARP configuration"
[ ${no_of_carp} != "0" ] && carps="${carps} $i"
done
[ "x"$DEBUG != "x" ] && echo "CARP I/F = ${carps}"
[ -z "${carps}" ] && exit 0 # no carp I/F.
PREEMPTION=`/sbin/sysctl net.inet.carp.preempt | /usr/bin/awk '{print $2}'`
[ "x"$DEBUG != "x" ] && echo "CARP preemption = ${PREEMPTION}"
[ ${PREEMPTION} != "1" ] && exit 0 # No carp preemption. May cause failure.
##############################################################################
# Main.
case "${ACTION}" in
"MASTER")
# make sure all carp is master.
if [ -n "${carps}" ]; then
for if in ${carps}; do
vhid=`/sbin/ifconfig ${if} | /usr/bin/grep carp | /usr/bin/awk '{print $3 " " $4}'`
/sbin/ifconfig ${if} ${vhid} state master
done
fi
for disk in ${HASTDEV}; do
# If there is secondary worker process, it means that remote primary process is
# still running. We have to wait for it to terminate.
for i in `jot 30`; do
/bin/pgrep -f "hastd: ${disk} \(secondary\)" >/dev/null 2>&1 || break
sleep 1
done
if pgrep -f "hastd: ${disk} \(secondary\)" >/dev/null 2>&1; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: Secondary process for resource ${disk} is still running after 30 seconds."
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"Role for HAST resources ${disk} switched to primary."
/sbin/hastctl role primary ${disk}
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: Unable to change role to primary for resource ${disk}."
exit 1
fi
done
# Wait for the /dev/hast/* devices to appear
for disk in ${HASTDEV}; do
for loop in $( jot 120 ); do
[ -c "/dev/hast/${disk}" ] && break
sleep 0.5
done
if [ ! -c "/dev/hast/${disk}" ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: GEOM provider /dev/hast/${disk} did not appear."
exit 1
fi
FSFMT=`file -bs /dev/hast/${disk}`
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: /dev/hast/${disk} cannot define FS format."
exit 1
fi
FSFMT=`echo ${FSFMT} | /usr/bin/awk '{print $1 " " $2}'`
case ${FSFMT} in
"Unix Fast")
/sbin/fsck -y -t ufs /dev/hast/${disk} >/dev/null 2>&1
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: UFS fsck /dev/hast/${disk} failed."
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"fsck /dev/hast/${disk} finished."
e_code=`/sbin/mount /dev/hast/${disk} /hast/${disk} 2>&1`
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: UFS mount for resource ${disk} failed: ${e_code}."
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"UFS /dev/hast/${disk} is mounted."
;;
*)
# If not UFS, Assume that filesystem is ZFS.
e_code=`/sbin/zpool import -f ${disk} 2>&1`
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: ZFS import for resource ${disk} failed: ${e_code}."
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"ZFS ${disk} is imported."
;;
esac
done
# NFS Service ( run nfsd and mountd. )
/usr/sbin/service rpcbind restart
/usr/sbin/service statd restart
/usr/sbin/service lockd restart
/usr/sbin/service nfsd restart
/usr/sbin/service mountd restart
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"NFS started."
# iSCSI service
# /etc/rc.d/iscsi_target start
;;
"BACKUP"|"INIT")
# make sure all carp is backup
if [ -n "${carps}" ]; then
for if in ${carps}; do
vhid=`/sbin/ifconfig ${if} | /usr/bin/grep carp | /usr/bin/awk '{print $3 " " $4}'`
/sbin/ifconfig ${if} ${vhid} state backup
done
fi
# stop iSCSI service
# /etc/rc.d/iscsi_target forcestop
# NFS Service ( stop nfsd and mountd. )
/usr/sbin/service mountd forcestop
/usr/sbin/service nfsd forcestop
/usr/sbin/service lockd forcestop
/usr/sbin/service statd forcestop
/usr/sbin/service rpcbind forcestop
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"NFS stoped."
# Switch roles for the HAST resources
for disk in ${HASTDEV}; do
sleep 1
# First of all, set hast status to secondary.
# Do not touch device before hast status become secondary.
# This work protects to become split-brain status.
/sbin/hastctl role secondary ${disk} 2>&1
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: Unable to switch role to secondary for resource ${disk}."
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"Role switched to secondary for resource ${disk}."
# Unmount UFS
for i in `/sbin/mount | /usr/bin/awk '{print $1 ":" substr($4,2)}' | /usr/bin/grep hast`; do
if [ ${i%:*} = "/dev/hast/${disk}" ]; then
if [ ${i#*:} = "ufs," ]; then
e_code=`/sbin/umount /hast/${disk} 2>&1`
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: UFS unmount of resource ${disk} failed: ${e_code}"
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"UFS /dev/hast/${disk} is unmounted"
fi
fi
done
# Export ZFS
zpool list | egrep -q "^${disk} "
if [ $? -eq 0 ]; then
# Force export ZFS pool.
e_code=`/sbin/zpool export -f ${disk} 2>&1`
if [ $? -ne 0 ]; then
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"FATAL: ZFS export of resource ${disk} failed: ${e_code}."
exit 1
fi
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"ZFS ${disk} is exported."
fi
done
;;
*)
/usr/bin/logger -p ${SYSLOG_FACILITY} -t ${SYSLOG_TAG} \
"Unknown CARP state. ${STATE}"
;;
esac
exit 0
##############################################################################
# Local Variables:
# coding: utf-8
# mode: sh
# sh-basic-offset: 4
# sh-indentation: 4
# End: