#!/bin/ksh -
#
# @(#)mk-afs-rc	1.28 (hursley) 10/9/97
# /afs/hursley.ibm.com/common/src/afs/@cell/asys/usr/local/sbin/mk-afs-rc/SCCS/s.mk-afs-rc
#
# NAME		mk-afs-rc
# AUTHOR	Paul Blackburn    http://acm.org/~mpb
# WRITTEN	April 1995
# PURPOSE	Create an /etc/rc.afs with the following attributes:
#		a) checks for server reachability (useful on mobiles)
#		b) works on both client and server
#		c) does "package" processing
# NOTES
#		1) Preserves old /etc/rc.afs file before installing new one.
#		2) /etc/rc.afs is a Bourne shell (no ksh constructs)
#		3) idempotent
#
# USAGE		Invoked	in mk-afs-srv(++) or mk-afs-cli	at install time.
#
# SOURCE
#		ftp://ftp.transarc.com/pub/afs-contrib/tools/afs_install/
#		/afs/transarc.com/public/afs-contrib/tools/afs_install/

X=${afs_install_base}/usr/local/sbin/mk-afs-cf

if [[ ! -f ${X} ]]; then
	echo "fatal error: ${X}	not found" >&2
	exit 1
fi

# source global	config for AFS installation

. ${X}

tstamp "version 1.28 commenced on $(date '+%a %d %h %y')"

if [[ -z "${afsdoptions}" ]]; then
	warning	"afsdoptions not defined for ${HOST}"
	afsdoptions="-stat 2000 -dcache 800 -daemons 3 -volumes 70"
	warning	"defaulting to: ${afsdoptions}"
fi

if [[ -z "${afscachename}" ]]; then
        warning "afscachename not defined for ${HOST}"
        afscachename="/usr/vice/cache"
        warning "defaulting to: ${afscachename}"
fi

F=/etc/rc.afs

if [[ -s ${F} ]]; then
	suffix=$(date '+%y''%m''%d'_'%H''%M'':%S')
	newname=${F}.${suffix}
	warning	"${F} already exists. Renaming to ${newname}"
	doit "mv ${F} ${newname}"
fi

tstamp "Creating ${F}"
tstamp "AFS Installation Guide page 5-16"
tstamp "Setup ${F}"

cat <<eeooff >${F}
#!/bin/sh -
#
# ${F} created using "${CMD}" on $(date)
#
# PURPOSE
#	Start AFS in the following manner:
#           a) Check for server ping reachability (useful on mobiles).
#              Fail gracefully if cell's first database server is unpingable.
#           b) Run on either client or server.
#           c) Does AFS "package" processing.
#           d) Logs stdout and stderr to /var/log/rc.afs (for later analysis).
#
#	A check is made using "crash" to see if AFS kernel extensions
#	have already been loaded. The AFS KEs must only be loaded once.
#	This makes this script almost idempotent except for "package"
#	processing (which could force a reboot).
#
# SOURCE
#       ftp://ftp.transarc.com/pub/afs-contrib/tools/afs_install/
#       /afs/transarc.com/public/afs-contrib/tools/afs_install/

PATH=/usr/bin:/etc:/usr/sbin:/usr/ucb:/sbin

LOGDIR=/var/log
LOG=\${LOGDIR}/rc.afs
CMD=/etc/rc.afs

# functions

fatal() {
	error "\${1} - fatal error"
	exit 1
}

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
}

kecheck() {

#
# Check if we already have AFS Kernel Extensions loaded
#
eeooff

if [ "${sysname}" = "rs_aix32" ]; then
	cat <<eeooff >>${F}

# the rs_aix32 version based on:
#   /usr/vice/etc/dkload/cfgexport -a /usr/vice/etc/dkload/export.ext.nonfs
#   /usr/vice/etc/dkload/cfgafs    -a /usr/vice/etc/dkload/afs.ext

	KE=export.ext
	echo "le\\nq\\n" | crash | grep \${KE}
	if [ \$? -eq 0 ]; then
		warning "AFS Kernel Extensions \${KE} already loaded"
	else
		echo "Load kernel extension \${KE} for AFS \${MTYPE}"
		doit "\${D}/cfgexport -a \${D}/\${KE}"
	fi
	KE=afs.ext
	echo "le\\nq\\n" | crash | grep \${KE}
	if [ \$? -eq 0 ]; then
		warning "AFS Kernel Extensions \${KE} already loaded"
	else
		echo "Load kernel extension \${KE} for AFS \${MTYPE}"
		doit "\${D}/cfgafs -a \${D}/\${KE}"
	fi

eeooff
else
	cat <<eeooff >>${F}

# the rs_aix4[12] version uses "cfgexport" to load both KEs

	for KE in export.ext afs.ext; do
		echo "le\\nq\\n" | crash | grep \${KE}
		if [ \$? -eq 0 ]; then
			warning "AFS Kernel Extensions \${KE} already loaded"
		else
			echo "Load kernel extension \${KE} for AFS \${MTYPE}"
			doit "\${D}/cfgexport -a \${D}/\${KE}"
		fi
	done

eeooff
fi
	cat <<eeooff >>${F}
}

# main 

# First, check we can ping our cell's first AFS DB server listed in CellServDB.
# No point in starting Cache Manager if not connected...

csdb=/usr/vice/etc/CellServDB
if [ ! -s \${csdb} ]; then
        fatal "missing file: \${csdb}"
fi
thiscell=/usr/vice/etc/ThisCell
if [ ! -s \${thiscell} ]; then
        fatal "missing file: \${thiscell}"
else
        cellname=\`cat \${thiscell}\`
fi

csdb_numbered=/tmp/numbered_CellServDB_\$\$
< \${csdb} awk '{printf(" %d %s\\n",NR, \$0)}' > \${csdb_numbered}
line=\`grep "\\>\${cellname}" \${csdb_numbered} | awk '{print \$1}'\`
next_line=\`expr \${line} + 1\`
srvr=\`grep " \${next_line} " \${csdb_numbered} | awk '{print \$2}'\`
rm \${csdb_numbered}

tstamp "checking we can ping AFS database server: \${srvr}"
ping \${srvr} 56 1 2>&1 > /dev/null
if [ \$? = 0 ]; then
        tstamp "pinged \${srvr} OK"
else
        warning "ping \${srvr} failed. AFS not started"
	echo "    Do not panic." >&2
	echo "    First, fix your network connection." >&2
	echo "    Next, as root, run: \${CMD}" >&2
        exit 1
fi

# If we reached this far, then ping check was OK. Proceed as normal.

echo "\${CMD}: stdout and stderr now being written to \${LOG}"
exec 4>&2
exec 3>&1
exec 1>\${LOG}
exec 2>&1

tstamp "commenced"

eeooff

if [ "${sysname}" = "rs_aix32" ]; then
	cat <<eeooff >>${F}

echo "Installing NFS kernel extensions (for AFS+NFS on rs_aix32)"

doit "/etc/gfsinstall -a /usr/lib/drivers/nfs.ext"
eeooff
fi

cat <<eeooff >>${F}

D=/usr/afs/bin/dkload
if [ -d \${D} ]; then
	MTYPE="server"
else
	MTYPE="client"
	D=/usr/vice/etc/dkload
fi

if [ "\${MTYPE}" = "server" ]; then
#
# Check if we already have a bosserver running (ie at AFS install time)
#
	BOSPID=\`ps -ef | fgrep bosserver | grep -v grep | awk '{print \$2'}\`
	if [ -z "\${BOSPID}" ]; then
		kecheck
		X=/usr/afs/bin/bosserver
		if [ -x "\${X}" ]; then
			doit "\${X} &"
		else
			warning	"\${X} not executable"
		fi
	else
		warning "Enough already! We have a bosserver running:"
		doit "ps -ef | fgrep bosserver | grep -v grep"
		warning "This is normal during afs_install mk-afs-srv++."
	fi
else
	kecheck
fi

doit "mount ${afscachename} 2> /dev/null    # make sure AFS cache is mounted"

# Check if we already have afsds running (ie at AFS install time)

AFSDPIDS=\`ps -ef | fgrep afsd | grep -v grep | awk '{print \$2}'\`
if [ -z "\${AFSDPIDS}" ]; then
	doit "/usr/vice/etc/afsd ${afsdoptions}"
else
	warning "afsd already running, PIDs are: \\n\${AFSDPIDS}"
	warning "This is normal during afs_install mk-afs-srv++."
fi

X=/usr/local/sbin/mk-afs-inetd
if [ -x \${X} ]; then
	doit "\${X}"
else
	warning "\${X} not executable."
	warning "Trying alternative AFS inetd startup"
	F=/etc/inetd.conf.afs
	if [ -s \${F} ]; then
		X=/usr/etc/inetd.afs
		if [ -x \${X} ]; then
			doit "(sleep 20;\${X} \${F} && echo \${X} started)"
		fi
	fi
fi

# Now AFS has started, we can do AFS "package" processing.
# see also page 5-1 of:
#  "AFS Commands Reference Manual", Transarc Corporation, FS-D200-00.11.3
x=/usr/afsws/etc/package
if [ -x \${x} ]; then
	f=/.package              # look for local copy first
	if [ ! -s \${f} ]; then  # otherwise, try sitewide copy
		f=/afs/@cell/wsadmin/etc/.package
	fi
	if [ -s \${f} ]; then
		tstamp "AFS package processing"
		doit "\${x} -config \`cat \${f}\` -verbose"
		case \${retcode} in
		0)	tstamp "AFS package completed with no errors"
			;;
		4)	
			tstamp "AFS package completed. Now rebooting..." 
			sync; sleep 1; sync; sleep 1; sync; # flush RAM to disk
# Switch stdout and stderr back to tty to display on console (not logfile)
			exec 1>&3
			exec 2>&4
			tstamp "AFS package completed, return code is 4."
			warning "Changes need a reboot, now rebooting." 
			doit "sync; sleep 1; sync; sleep 1; sync; shutdown -Fr"
			;;
		*)	warning "AFS package failed, continuing regardless"
			;;
		esac
	else
		warning "missing file: \${f}"
	fi
else
	warning "missing executable: \${x}"
fi

# Confirm (in logfile) that AFS has been started
df | grep -q AFS
if [ \$? = 0 ]; then
	tstamp "AFS Cache Manager successfully started"
else
	warning "AFS Cache Manager failed to start"
fi

tstamp "completed"

# Confirm (on console) that AFS has been started
# Switch stdout and stderr back to tty to display on console (not logfile)

exec 1>&3
exec 2>&4
df | grep -q AFS
if [ \$? = 0 ]; then
	tstamp "AFS Cache Manager successfully started"
else
	warning "AFS Cache Manager failed to start"
fi
eeooff

doit "chmod 755 ${F}"
doit "cat ${F}"

T=/tmp/${CMD}.mail.$$
cat <<eeooff >${T}

Greetings,
The AFS run command file (${F}) has been created on ${HOST}.
You will find a log of this process in:

        ${LOG}
--
Sincerely,
${CMD} program
eeooff
doit "mail -s \"${HOST}: ${CMD} completed\" ${NOTIFY} <${T}"
cat ${T}
rm ${T}

tstamp "completed"
