[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--