[OpenAFS-port-darwin] afsdb problems

Phil Holland hollandp@umich.edu
Tue, 27 Jul 2004 15:46:47 -0400


--Apple-Mail-1-981257667
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed

	The current release version of OpenAFS (1.2.11) has a couple of 
problems associated with using the -afsdb option on Mac OS X (possibly 
on other systems as well, but I haven't tested others).  The first 
problem occurs at reboot/shutdown - the machine hangs for an additional 
60 seconds if AFS is left running.  The second occurs only if a kill is 
sent to the afsd process running the afsdb handler - any subsequent 
attempts to resolve a cell leave afsd threads hung indefinitely.
	The source of these problems appears to be the behavior of the afsdb 
handler - unlike the other afsd processes, which enter kernel space and 
do not leave until shutdown (if (!fork()) { syscall(); exit(1);}), the 
afsdb handler loops through kernel space and back into user space on 
every resolution.  While sleeping inside of kernel space, any signal 
sent to the process is ignored, but serviced immediately upon return to 
user space.  Since no special handlers are installed, the afsd instance 
running the afsdb handler terminates, and afsdb_handler_running is left 
asserted.
	I've included a patch which causes correct behavior in both these 
instances, as well as a replacement for the startup script 
(/Library/StartupItems/OpenAFS/OpenAFS) which accepts stop and restart 
requests from the SystemStarter app.  These are relatively untested, 
and I do not know whether they will work with newer kernel sources 
(though there should be no reason for them not to).
	Let me know if these work for you, or if you encounter any issues.  
(You should only have to replace afsd and afs.kext)
		--Phil


--Apple-Mail-1-981257667
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0775;
	name="OpenAFS"
Content-Disposition: attachment;
	filename=OpenAFS

#!/bin/sh
# Copyright 2000, International Business Machines Corporation and others.
# All Rights Reserved.
# 
# This software has been released under the terms of the IBM Public
# License.  For details, see the LICENSE file in the top-level source
# directory or online at http://www.openafs.org/dl/license10.html
#
# Portions Copyright (c) 2003 Apple Computer, Inc.
#
# Updated to match standard service scripts
# Phil Holland <hollandp@umich.edu> 6/11/04

. /etc/rc.common

#
# Variable Definition Section
#
CheckForNetwork

VICEETC=/usr/vice/etc
AFSD=$VICEETC/afsd
if [ -r /var/db/openafs ]; then
    VICEETC=/var/db/openafs/etc
    AFSD=/usr/sbin/afsd
fi

CONFIG=$VICEETC/config
AFSDOPT=$CONFIG/afsd.options
PACKAGE=$CONFIG/package.options

LARGE="-stat 2800 -dcache 2400 -daemons 5 -volumes 128"
MEDIUM="-stat 2000 -dcache 800 -daemons 3 -volumes 70"
SMALL="-stat 300 -dcache 100 -daemons 2 -volumes 50"

if [ -x /usr/sbin/kextstat ]; then KMODSTAT=/usr/sbin/kextstat; fi
if [ -x /usr/sbin/kmodstat ]; then KMODSTAT=/usr/sbin/kmodstat; fi


StartService()
{
    echo "Starting OpenAFS"

    if [ "${NETWORKUP}" = "-NO-" ]; then exit; fi

    if [ -f $AFSDOPT ]; then
	OPTIONS=`cat $AFSDOPT`
    else
	OPTIONS="$MEDIUM -fakestat"
    fi

# Need the commands ps, awk, kill, sleep
    PATH=${PATH}${PATH:+:}/sbin:/bin:/usr/bin

    if [ -d $VICEETC/afs.kext ]; then
	echo "Loading AFS kernel extensions"
	kextload $VICEETC/afs.kext
    else
	echo "$VICEETC/afs.kext does not exist. Skipping AFS startup."
	exit 1
    fi

    if $KMODSTAT | perl -e 'exit not grep /openafs/, <>' ; then
	:
    else
	echo  "AFS kernel extensions failed to initialize. Skipping AFS startup."
	exit 1
    fi

#
# Start the AFS server processes if a bosserver exists
#

    if [ -x /usr/afs/bin/bosserver ]; then
	echo "Starting AFS Server processes"
	/usr/afs/bin/bosserver
	OPTIONS="$OPTIONS -nosettime"
	sleep 30
    fi

#
# Check that all of the client configuration files exist
#

    for file in $AFSD $VICEETC/cacheinfo \
	$VICEETC/ThisCell $VICEETC/CellServDB
      do
      if [ ! -f ${file} ]; then
	  echo "${file} does not exist. Not starting AFS client."
	  exit 1
      fi
    done

#
# Check that the root directory for AFS (/afs) 
# and the cache directory (/usr/vice/cache) both exist
#

    for dir in `awk -F: '{print $1, $2}' $VICEETC/cacheinfo`
      do
      if [ ! -d ${dir} ]; then
	  echo "${dir} does not exist. Not starting AFS client."
	  exit 2
      fi
    done

    echo "Starting afsd"
    $AFSD $OPTIONS

#
# Call afssettings (if it exists) to set customizable parameters
#
    if [ -x $CONFIG/afssettings ]; then
	sleep 2
	$CONFIG/afssettings
    fi

#
# Run package to update the disk
#
    if [ -f /usr/afsws/etc/package -a -f $PACKAGE ]; then
	/usr/afsws/etc/package -v -o `cat $PACKAGE` > /dev/console 2>&1
	case $? in
	    0)
                (echo "Package completed successfully") > /dev/console 2>&1
                date > /dev/console 2>&1
	    ;;
	    4)
	        (echo "Rebooting to restart system") > /dev/console 2>&1
		sync
		/sbin/reboot
	    ;;
	    *)
	        (echo "Package update failed; continuing") > /dev/console 2>&1
	    ;;
	esac
     fi

#
# Start AFS inetd services
# (See the AFS Command Ref. for notes on the proper configuration of inetd.afs)
#
     if [ -f /usr/sbin/inetd.afs -a -f /etc/inetd.conf.afs ]; then
	 /usr/sbin/inetd.afs /etc/inetd.conf.afs
     fi
}

StopService()
{
    echo "Stopping AFS"

    if $KMODSTAT | perl -e 'exit not grep /openafs/, <>' ; then
	echo "Unmounting /afs"
	umount -f /afs 2>&1 > /dev/console

	echo "Shutting down afsd processes"
	$AFSD -shutdown 2>&1 > /dev/console

	echo "Unloading AFS kernel extensions"
	kextunload $VICEETC/afs.kext 2>&1 > /dev/console
    fi
}

RestartService()
{
    StopService
    StartService
}

RunService "$1"
--Apple-Mail-1-981257667
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="openafs-1.2.11-afsdb.patch"
Content-Disposition: attachment;
	filename=openafs-1.2.11-afsdb.patch

diff -ruN 1.2.11.original/src/afs/DARWIN/osi_sleep.c 1.2.11/src/afs/DARWIN/osi_sleep.c
--- 1.2.11.original/src/afs/DARWIN/osi_sleep.c	2001-11-10 18:22:52.000000000 -0500
+++ 1.2.11/src/afs/DARWIN/osi_sleep.c	2004-07-27 11:12:32.000000000 -0400
@@ -211,3 +211,29 @@
     }
     relevent(evp);
 }
+
+void afs_osi_fullSigMask()
+{
+	struct uthread *user_thread = (struct uthread *)get_bsdthread_info(current_act());
+	
+	/* Protect original sigmask */
+	if (!user_thread->uu_oldmask) {
+		/* Back up current sigmask */
+		user_thread->uu_oldmask = user_thread->uu_sigmask;
+		/* Mask all signals */
+		user_thread->uu_sigmask = ~(sigset_t)0;
+	}
+}
+
+void afs_osi_fullSigRestore()
+{
+	struct uthread *user_thread = (struct uthread *)get_bsdthread_info(current_act());
+	
+	/* Protect original sigmask */
+	if (user_thread->uu_oldmask) {
+		/* Restore original sigmask */
+		user_thread->uu_sigmask = user_thread->uu_oldmask;
+		/* Clear the oldmask */
+		user_thread->uu_oldmask = (sigset_t)0;
+	}
+}
diff -ruN 1.2.11.original/src/afs/afs_call.c 1.2.11/src/afs/afs_call.c
--- 1.2.11.original/src/afs/afs_call.c	2003-05-22 11:52:58.000000000 -0400
+++ 1.2.11/src/afs/afs_call.c	2004-07-27 11:12:28.000000000 -0400
@@ -838,7 +838,7 @@
 	char *cellname = afs_osi_Alloc(cellLen);
 
 #ifndef UKERNEL
-	afs_osi_MaskSignals();
+	afs_osi_MaskUserLoop();
 #endif
 	AFS_COPYIN((afs_int32 *)parm2, cellname, cellLen, code);
 	AFS_COPYIN((afs_int32 *)parm3, kmsg, kmsgLen, code);
diff -ruN 1.2.11.original/src/afs/afs_osi.c 1.2.11/src/afs/afs_osi.c
--- 1.2.11.original/src/afs/afs_osi.c	2003-05-23 02:52:15.000000000 -0400
+++ 1.2.11/src/afs/afs_osi.c	2004-07-27 11:26:38.000000000 -0400
@@ -286,7 +286,25 @@
     osi_linux_mask();
 #endif
 }
-    
+
+
+/* Two hacks to try and fix afsdb */
+void afs_osi_MaskUserLoop(){
+#ifdef AFS_DARWIN_ENV
+	afs_osi_Invisible();
+	afs_osi_fullSigMask();
+#else
+	afs_osi_MaskSignals();
+#endif
+}
+
+void afs_osi_UnmaskUserLoop(){
+#ifdef AFS_DARWIN_ENV
+	afs_osi_fullSigRestore();
+#endif
+}
+
+
 /* unmask signals in rxk listener */
 void afs_osi_UnmaskRxkSignals(){
 }

--Apple-Mail-1-981257667--