#!/bin/ksh -
#
# @(#)mk-afs-boswait	1.5 (hursley) 11/6/96
# /afs/hursley.ibm.com/common/src/afs/@cell/rs_aix32/usr/local/sbin/mk-afs-boswait/SCCS/s.mk-afs-boswait
#
# NAME		mk-afs-boswait
# AUTHOR	Paul Blackburn <mpb@acm.org>
# PURPOSE	Wait for AFS bosserver processes to elect a quorum
#		and settle down. When this program completes,
#		it is safe to do "vos creates" etc.
#
# USAGE		Normally invoked during system reboot or AFS installation
#		(See usage() below)
#
# METHOD	AFS port numbers used in the udebug and rxdebug commands are:
#
#		7000 File Server
#		7001 Cache Manager
#		7002 Protection Server
#		7003 Volume Location Server
#		7004 Kerberos Server
#		7005 Volume Server
#		7007 Basic OverSeer Server
#		7021 Backup Server
#
#		We are interested in: 7002, 7003, 7004, 7021
#		Look for "Recovery state 1f" from udebug output on each port.
# SOURCE
#               ftp://ftp.transarc.com/pub/afs-contrib/tools/afs_install/

CMD=$(basename ${0})
[[ -z "${HOSTNAME}" ]] && HOSTNAME=$(hostname)
export HOSTNAME

if [[ -z "${HOST}" ]]; then
	HOST=$(localhost 2>/dev/null || (echo $HOSTNAME | awk -F. '{print $1}'))
fi
export HOST

UDEBUG=/usr/afs/bin/udebug

TF=/tmp/${CMD}.tf.$$

trap "echo interrupted; rm -f ${TF} 2>/dev/null; exit 1" 1 2 3 15

# functions

usage() {
	cat <<eeooff
Purpose:
  Wait for AFS bos processes to "settle down" and elect a quorum.
  When completed, it is "safe" to do "vos creates" etc.
Usage:
${CMD} [-?] [-v] [-V] ["port port-comment"] ["port port-comment" ... ]
Where:
	-?			# display usage (this text)
	-v			# verbose mode - display what's happening
	-V			# display ${CMD} version number
	"port port-comment"	# specify which port to wait on
				  (eg "7002 Protection Server")

If no parameters are supplied on the command line then ${CMD}
waits on the following:

7002 Protection Server
7003 Volume Location Server
7004 Kerberos Server
7021 Backup Server

Example:
\$ ${CMD} -v "7002 Protection Server" "7003 Volume Location Server"
# waits, (noisily) in verbose mode, for these two bos processes to quiesce.
eeooff
}

error() {
        echo "${CMD} error: ${1}" >&2
}

warning() {
        echo "${CMD} warning: ${1}" >&2
}

tstamp() {
        echo "$(date '+%H''%M'':%S') ${CMD}: ${1}"
}

doit() {
	tstamp "${1}"
	eval ${1}

	retcode=$?
	if [[ ${retcode} != 0 ]]; then
		error "\$?=${retcode}"
	fi
}

waitfor() {
	port=${1}
	case "${port}" in
		7002 | 7003 | 7004 | 7021 ) ;;
		*)	error "Invalid AFS port (${port}) to wait on"
			exit 1
			;;
	esac
	shift
	portname="$*"
	if [[ ! -z "${VERBOSE}" ]]; then
		tstamp "checking ${portname}"
	fi
	kip=1
	again="true"
	while [[ ${again} = "true" ]]; do
		X="${UDEBUG} ${HOSTNAME} ${port}"
		if [[ ! -z "${VERBOSE}" ]]; then
			echo "${X} | fgrep \"Recovery state 1f\""
		fi
		${X} | fgrep "Recovery state 1f" >/dev/null
		if [[ $? = 0 ]]; then
			again="false"
		else
			if [[ -z "${VERBOSE}" ]]; then
				sleep ${kip}
			else
				doit "sleep ${kip}"
			fi
			let kip=${kip}\*2
		fi
	done
	if [[ ! -z "${VERBOSE}" ]]; then
		tstamp "${portname}: OK"
	fi
}

# main

if [[ ! -x ${UDEBUG} ]]; then
	error "unable to execute ${UDEBUG}"
	exit 1
fi

while [[ ! -z "${1}" ]]; do
	case "${1}" in
		-v ) VERBOSE="true" ;;
		-V ) echo "${CMD} version 1.10"; exit ;;
		-? ) usage; exit ;;
		*  ) echo "${1}" >>${TF} ;;
	esac
	shift 2>/dev/null
done
        
if [[ ! -z "${VERBOSE}" ]]; then
	tstamp "version 1.5 commenced on ${HOST} on $(date '+%a %d %h %y')"
fi

# If we have no command line "port port-comments" then use default set

if [[ ! -s ${TF} ]]; then
	cat <<eeooff >${TF}
7002 Protection Server
7003 Volume Location Server
7004 Kerberos Server
7021 Backup Server
eeooff
fi

while read LINE; do
	waitfor ${LINE}
done <${TF}

rm ${TF}

if [[ ! -z "${VERBOSE}" ]]; then
	tstamp "completed"
fi
