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: