[OpenAFS] my afs wish list

Brandon S. Allbery KF8NH allbery@ece.cmu.edu
30 Apr 2003 08:55:09 -0400


On Wed, 2003-04-30 at 07:31, Paul Blackburn wrote:
> b) A bit more robustness in rc.afs.
>     Example: do not attempt to start afsd if the database servers
>     for {ThisCell} are not accessible via network.
> 
>     This would help avoid ugly problems on client machines
>     in some circumstances (server power failure, network outage, etc).
> 
>     example: http://www.angelfire.com/hi/plutonic/images/afs

This might be interesting along those lines.

#! /bin/sh
#
# SuSE-ified AFS startup script.
#
# LSB => chkconfig (a sane one: dependencies! woo)
### BEGIN INIT INFO
# Provides: afs
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Start the OpenAFS client cache manager
### END INIT INFO

. /etc/rc.status
. /etc/rc.config
base=${0##*/}
link=${base#*[SK][0-9][0-9]}
test $link = $base && START_AFS=yes
# test "$START_AFS" = yes || exit 0
AFS_CLIENT=yes export AFS_CLIENT

# until we get everyone retrofitted
if test -f /etc/afs.rc && [ "$AFS_OPTIONS" = "" ]; then
    . /etc/afs.rc
    AFS_OPTIONS="$OPTIONS"
fi

# is_on returns 1 if value of arg is "on"
is_on() {
    [ "$1" = on -o "$1" = yes ]
}

# If choose_client can't correctly determine which client to use, set
# LIBAFS manually.
choose_client() {
    # Use the second field of the uname -v output instead of just
    # doing a match on the whole thing to protect against matching
    # a timezone named SMP -- I don't know of one, but let's be
    # paranoid.

    set X `uname -v`; shift
    # (so much for paranoid...  ++bsa)
    case "$2" in
    SMP) MP=.mp ;;	# MP system
    *)   MP= ;;		# SP system
    esac

    # For now, just use uname -r to get the module version. 
    VERSION="`uname -r`"

    LIBAFS="libafs-$VERSION$MP.o"
}

MODLOADDIR=/usr/vice/etc/modload
# load_client loads the AFS client module if it's not already loaded. 
load_client() {
    # If LIBAFS is set, use it.
    if [ -z "$LIBAFS" ] ; then
	# Try to determine the right client.
	choose_client
    fi

    if [ ! -f "$MODLOADDIR/$LIBAFS" ] ; then
	echo -n "$MODLOADDIR/$LIBAFS does not exist"
	return 1
    fi
    /sbin/insmod -m "$MODLOADDIR/$LIBAFS" > "$MODLOADDIR/libafs.map" 2>&1
}

rc="$rc_done"
case "$1" in 
start)
# Load kernel extensions
    echo -n Starting AFS...

    # wait for the network to start (?!)
    echo -n " net"
    router="`netstat -rn | awk '$1 == "0.0.0.0" {print $2}'`"
    count=0
    while [ $count -lt 130 ]; do
	ping -c 1 -i 1 -n -q -w 1 "$router" >/dev/null 2>&1 && break
	count=$(( $count + 1 ))
    done
    if [ $count = 130 ]; then
	echo -n " no network?"
	echo -e "$rc_failed"
	exit 1
    fi

    echo -n " kmod"
    if load_client; then
	:
    else
	echo -e "$rc_failed"
	exit 1
    fi

    # Start bosserver, it if exists
    if [ "$rc" = "$rc_done" ] &&
       is_on $AFS_SERVER &&
       test -x /usr/afs/bin/bosserver; then
	echo -n " bos"
	/usr/afs/bin/bosserver
	if [ $? -ne 0 ]; then
	    echo -e "$rc_failed"
	    exit 1
	fi
    fi

    # Clear out the vice cache if requested
    # if [ "$rc" = "$rc_done" ] && test -f /var/tmp/.nukeafs; then
	echo -n " cache"
	(cd "`cut -d: -f2 /usr/vice/etc/cacheinfo`"
	/bin/rm -rf * >/dev/null 2>&1)
    # fi

    # Start AFS client
    if [ "$rc" = "$rc_done" ] &&
       is_on $AFS_CLIENT &&
       test -x /usr/vice/etc/afsd; then
	echo -n " sem"
	# let us know if AFS startup times out
	lock="`/bin/mktemp /tmp/afck.XXXXXX`"
	if [ "$lock" = "" ]; then
	    echo -e "$rc_failed"
	    exit 1
	fi
	res="`/bin/mktemp /tmp/afrc.XXXXXX`"
	if [ "$res" = "" ]; then
	    echo -e "$rc_failed"
	    exit 1
	fi
	echo -e "$rc_done" >"$res"
	(sleep 180; echo no >"$lock") >/dev/null 2>&1 & cpid=$!
	disown $cpid		# else !@#$ bash is verbose about kill later
	( # background this whole mess

	# Wait for the network
	echo -n " srv"
	cnt=0
	until ping -c 1 -n -w 1 128.2.129.7 >/dev/null 2>&1; do
	    cnt=$(( $cnt + 1 ))
	    if [ $cnt = 60 ]; then
		# don't bother
		echo -e "$rc_failed" >"$res"
		kill $cpid
		echo no >"$lock"
		exit 1
	    fi
	done

	# Start AFS cache manager
	echo -n " afsd"
	/usr/vice/etc/afsd ${AFS_OPTIONS} >/dev/null 2>&1 || echo -e "$rc_failed" >"$res"

	# Set AFS sysname
	if [ "$rc" = "$rc_done" ] &&
	   test -f /usr/afsws/bin/fs &&
	   test -f /usr/vice/etc/sysname; then
	    echo -n " @sys"
	    sysname="`cat /usr/vice/etc/sysname`"
	    /usr/afsws/bin/fs sysname "$sysname" >/dev/null || echo -e "$rc_failed" >"$res"
	fi

	# Disable setuid files unless specified in config
	if [ "$rc" = "$rc_done" ] &&
	   [ "`/maint/bin/printconf setcell`" != suid ]; then
	    echo -n " suid"
	    /usr/afsws/bin/fs setcell ece.cmu.edu -nosuid >/dev/null ||
	    echo -e "$rc_failed" >"$res"
	fi

	# Start AFS version of inetd.conf if present.
	if [ "$rc" = "$rc_done" ] &&
	   test -f /usr/afsws/etc/inetd.conf &&
	   test -x /usr/afsws/etc/inetd.afs ; then
	    echo -n " inetd"
	    /usr/afsws/etc/inetd.afs /usr/afsws/etc/inetd.conf ||
	    echo -e "$rc_failed" >"$res" 
	fi

	# end of backgrounded block
	) & apid=$!
	disown $apid

	# rebuild ld.so.cache;
	# avoid losing our shlib symlinks when AFS takes a while to start
	while :; do
	    if test -s "$lock" -o -d /afs/ece.cmu.edu; then
		kill $cpid >/dev/null 2>&1
		break
	    fi
	    sleep 1
	done
	if [ "`cat \$lock`" = no ]; then
	    # schedule a recovery
	    /bin/rm -f /maint/db/support /maint/db/vendor >/dev/null 2>&1
	    echo -e "$rc_failed" >"$res"
	fi
	/bin/rm -f "$lock" >/dev/null 2>&1
	# can't defer this any longer or system may misbehave
	echo -n " ldconfig"
	/sbin/ldconfig -X >/dev/null 2>&1 || echo -e "$rc_failed" >"$res"
    fi
    cat "$res"
    /bin/rm -f "$res" >/dev/null 2>&1
    ;;

stop)
    # Stop AFS
    echo -n "Stopping AFS... "
    if is_on $AFS_CLIENT; then
	killall inetd.afs >/dev/null 2>&1
	umount /afs || rc="$rc_failed"
    fi

    if is_on $AFS_SERVER && test -x /usr/afs/bin/bos; then
	/usr/afs/bin/bos shutdown localhost -localauth -wait ||
	rc="$rc_failed"
	killall -HUP bosserver >/dev/null 2>&1
    fi

    LIBAFS="`/sbin/lsmod | grep '^libafs-'`"
    if [ -n "$LIBAFS" ] ; then
	LIBAFS="`echo \"$LIBAFS\" | awk 'BEGIN { FS = \" \" } {print $1}'`"
	/sbin/rmmod "$LIBAFS" || rc="$rc_failed"
    fi

    /bin/rm -f /var/lock/afs
    echo -e "$rc"
    ;;

*)
    echo Usage: "$0 {start|stop}" >&2
    exit 1
    ;;
esac
[ "$rc" = "$rc_done" ]

-- 
brandon s allbery [openafs/solaris/japh/freebsd] allbery@kf8nh.apk.net
system administrator [linux/heimdal/too many hats] allbery@ece.cmu.edu
electrical and computer engineering                              KF8NH
carnegie mellon university  [better check the oblivious first -ke6sls]