DAFS: large volume support - fileserver crash after "addled bitmap"
[openafs.git] / src / afsd / afs.rc.linux
1 #! /bin/bash
2 # Copyright 2000, International Business Machines Corporation and others.
3 # All Rights Reserved.
4
5 # This software has been released under the terms of the IBM Public
6 # License.  For details, see the LICENSE file in the top-level source
7 # directory or online at http://www.openafs.org/dl/license10.html
8
9 # AFS   Start and stop AFS components
10
11
12 # chkconfig: 35 60 20
13 # description:  AFS is a distributed file system which provides location
14 #               transparency, caching and secure authentication.
15 #               Additional configuration can be done in the /etc/sysconfig/afs
16 #               file. Read the documentation in that file for more information.
17 #
18 # The following section is used at least by SuSE insserv(8)
19 ### BEGIN INIT INFO
20 # Provides: afs
21 # Required-Start: $network
22 # Required-Stop: $network
23 # Default-Start: 3 5
24 # Default-Stop: 0 1 2 6
25 # Description:  AFS is a distributed file system which provides location
26 #              transparency, caching and secure authentication.
27 #              Additional configuration can be done in the /etc/sysconfig/afs
28 #              file. Read the documentation in that file for more information.
29 ### END INIT INFO
30 #
31 # Note that AFS does not use a pid file in /var/run. It is turned off by
32 # unmounting /afs.
33
34
35 # check for special bootup functions
36 if [ -f /etc/rc.d/init.d/functions ] ; then
37         . /etc/rc.d/init.d/functions
38         afs_rh=1
39 else
40         # special (RedHat) functions not available...
41         # so I provide neccessary replacements (e.g. for SuSE)
42
43         function echo_failure () { echo -n " - failed." ; }
44
45         function echo_success () { echo -n " - successful." ; }
46
47         # these are hopefully all functions I use...
48 fi
49
50 runcmd() {
51    echo -n "$1 "
52    shift
53    if [ "$BOOTUP" = "color" ]; then
54       $* && echo_success || echo_failure
55    else
56       $*
57    fi
58    echo
59 }
60
61 SYSCNF=${SYSCNF:-/etc/sysconfig/afs}
62 KERNEL_VERSION=`uname -r`
63
64 # Gather up options and post startup script name, if present
65 if [ -f $SYSCNF ] ; then
66         . $SYSCNF
67 fi
68
69 CACHEINFO=${CACHEINFO:-/usr/vice/etc/cacheinfo}
70 CACHE=${CACHEDIR:-/usr/vice/cache}
71 AFS=${AFSDIR:-/afs}
72 AFSD=${AFSD:-/usr/vice/etc/afsd}
73 BOSSERVER=${BOSSERVER:-/usr/afs/bin/bosserver}
74 BOS=${BOS:-/usr/bin/bos}
75 KILLAFS=${KILLAFS:-/usr/vice/etc/killafs}
76
77 # is_on returns 1 if value of arg is "on"
78 is_on() {
79         if  test "$1" = "on" ; then return 0
80         else return 1
81         fi
82 }
83
84 on_network() {
85     ADDRS=`LANG=C ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | wc -l`
86     if [ "$ADDRS" = "" ]; then
87        echo afs: No interfaces with IP address 1>&2
88        return 1
89     elif [ $ADDRS = 0 ]; then
90        echo afs: No interfaces with IP address 1>&2
91        return 1
92     fi
93     return 0
94 }
95
96 # If choose_client can't correctly determine which client to use, set
97 # LIBAFS manually.
98 choose_client() {
99
100         # Use the second field of the uname -v output instead of just
101         # doing a match on the whole thing to protect against matching
102         # a timezone named SMP -- I don't know of one, but let's be
103         # paranoid.
104
105         set X `uname -v`; shift
106         case $2 in
107         SMP) MP=.mp ;;  # MP system
108         *)   MP= ;;     # SP system
109         esac
110
111         # For now, just use uname -r to get the module version. 
112         case $KERNEL_VERSION in
113           [1-2].[0-5].*)
114                 LIBAFS=libafs-$KERNEL_VERSION$MP.o
115                 ;;
116           *)
117                 LIBAFS=libafs-$KERNEL_VERSION$MP.ko
118                 ;;
119         esac
120 }
121
122 #
123 # Find prefix symbol to use with insmod.  We find the unregister_filesystem
124 # string from /proc/ksyms since we know it's there.  If /proc/ksyms does not
125 # exist, we print that info to the console and use the uname -v output to
126 # decide on a prefix.
127 # unregister_filesystem_Rsmp_b240cad8 is a typcial SMP version string from
128 # a kernel built from ftp.kernel.org
129 #
130 case $KERNEL_VERSION in
131   [1-2].[0-5].*)
132         KSYMS_FILE=/proc/ksyms
133         ;;
134   *)
135         KSYMS_FILE=/proc/kallsyms
136         ;;
137 esac
138 SEARCH_STR="unregister_filesystem"
139 DEFAULT_SMP_PREFIX="smp_" # Redhat kernels need "smp" instead
140 PREFIX="" # none needed for UP with <= 1Gig memory
141
142 set_prefix()
143 {
144         h='[0-9a-fA-F]'
145         h8="$h$h$h$h$h$h$h$h"
146         prefix_set=0
147
148         set X `egrep "\<$SEARCH_STR" $KSYMS_FILE 2> /dev/null`; shift
149         
150         case $KERNEL_VERSION in
151           [1-2].[0-5].*)
152                 str=$2
153                 ;;
154           *)
155                 str=$3
156                 ;;
157         esac
158         case $str in
159         ${SEARCH_STR}_R$h8)
160                 # No prefix required
161                 ;;
162         $SEARCH_STR)
163                 # No versioning in kernel symbols
164                 ;;
165         ${SEARCH_STR}_R*$h8)
166                 suffix=${str#${SEARCH_STR}_R}
167                 PREFIX=${suffix%$h8}
168                 ;;
169         *)
170                 case $str in
171                 '')
172                         echo afsd: Cannot find \"$SEARCH_STR\" in file $KSYMS_FILE
173                         ;;
174                 *)
175                         echo afsd: Malformed kernel version symbol \"$str\"
176                         ;;
177                 esac
178
179                 echo Guessing prefix from output of uname -v
180                 set X `uname -v`; shift
181                 case $2 in
182                 SMP)
183                         PREFIX=$DEFAULT_SMP_PREFIX
184                         ;;
185                 esac
186                 ;;
187         esac
188 }
189
190 MODLOADDIR=${MODLOADDIR:-/usr/vice/etc/modload}
191 # load_client loads the AFS client module if it's not already loaded. 
192 load_client() {
193         # If LIBAFS is set, use it.
194         if [ -z "$LIBAFS" ] ; then
195                 # Try to determine the right client.
196                 choose_client
197         fi
198     
199         if [ ! -f "$MODLOADDIR/$LIBAFS" ] ; then
200                 echo AFS module $MODLOADDIR/$LIBAFS does not exist. Not starting AFS.
201                 exit 1
202         fi
203
204         # We need exportfs in order to access the cache files. Load it, but
205         # ignore errors as on some machines it may be built in to the kernel,
206         # not a module
207         /sbin/modprobe exportfs >/dev/null 2>&1
208
209         if [ -f $KSYMS_FILE ]; then
210                 # use the prefix command if required
211                 case $KERNEL_VERSION in
212                   [1-2].[0-5].*)
213                         set_prefix
214                         /sbin/insmod ${PREFIX:+-P $PREFIX} -f -m $MODLOADDIR/$LIBAFS > $MODLOADDIR/libafs.map 2>&1
215                         ;;
216                   *)
217                         /sbin/insmod $MODLOADDIR/$LIBAFS > $MODLOADDIR/libafs.map 2>&1
218                         ;;
219                 esac
220         else
221                 /sbin/insmod $MODLOADDIR/$LIBAFS > $MODLOADDIR/libafs.map 2>&1
222         fi
223 }
224
225 generate_cacheinfo() {
226     if [ "$CACHESIZE" = "AUTOMATIC" ]; then
227         LINE=`df -k $CACHE | tail -1`
228         PART=`echo $LINE | awk '{ if ( ($NF != "/usr")  && ($NF != "/") ) print $NF; else print "NONE";}'`
229         if [ "$PART" = "NONE" ]; then
230             echo "$CACHE or /usr/vice is not a separate partition"
231             echo "you have to change the cachesize in $SYSCNF by hand"
232             echo "AFS will be started with a VERY small cache of 8Mb."
233             CACHESIZE=8000
234         else
235             # Check to see if df has pretty-printed for long dev (i.e. LVM)
236             FCHAR=`echo $LINE | cut -c 1`
237             if [ "$FCHAR" = "/" ]; then
238                 PARTSIZE=`echo $LINE | awk '{print $2}'`
239             else
240                 PARTSIZE=`echo $LINE | awk '{print $1}'`
241             fi
242             CACHESIZE=`echo $PARTSIZE | awk '{printf "%d",int(($1*.8)/1000)*1000}'`
243         fi
244     fi
245     if [ "x$CACHESIZE" != "x" ]; then
246         echo $AFS:$CACHE:$CACHESIZE >$CACHEINFO
247         chmod 0644 $CACHEINFO
248     else
249         CACHESIZE=`awk -F: '{print $3}' < $CACHEINFO`
250     fi
251 }
252
253 choose_afsdoptions() {
254         if [ -z "$OPTIONS" -o "$OPTIONS" = "AUTOMATIC" ]; then
255                 if [ $CACHESIZE -lt 131072 ]; then
256                         OPTIONS=$SMALL
257                 elif [ $CACHESIZE -lt 524288 ]; then
258                         OPTIONS=$MEDIUM
259                 elif [ $CACHESIZE -lt 1048576 ]; then
260                         OPTIONS=$LARGE
261                 elif [ $CACHESIZE -lt 2097152 ]; then
262                         OPTIONS=$XLARGE
263                 else
264                         OPTIONS=$XXLARGE
265                 fi
266         fi
267         AFSD_OPTIONS="$OPTIONS $VERBOSE"
268         if is_on $ENABLE_AFSDB; then
269                 AFSD_OPTIONS="$AFSD_OPTIONS -afsdb"
270         fi
271         if is_on $ENABLE_DYNROOT; then
272                 AFSD_OPTIONS="$AFSD_OPTIONS -dynroot"
273         fi
274 }
275
276 case "$1" in 
277   start)
278     if [ ! "$afs_rh" -o ! -f /var/lock/subsys/afs ]; then
279         if [ `echo "$OPTIONS" | grep -c dynroot` = 0 ]; then
280             on_network || exit 1
281         fi
282         # Load kernel extensions
283         if  load_client  ; then :
284         else
285                 echo Failed to load AFS client, not starting AFS services.
286                 exit 1
287         fi
288
289         echo "Starting AFS services..... "
290         # Start bosserver, it if exists
291         if  is_on $AFS_SERVER && test -x $BOSSERVER  ; then
292                 $BOSSERVER 
293                 test "$afs_rh" && touch /var/lock/subsys/afs
294                 if is_on $WAIT_FOR_SALVAGE; then
295                         # wait for fileserver to finish salvaging
296                         sleep 10
297                         while $BOS status localhost fs 2>&1 | grep 'Auxiliary.*salvaging'; do
298                                 echo "Waiting for salvager to finish..... "
299                                 sleep 10
300                         done
301                 fi
302         fi
303
304         # Start AFS client
305         if  is_on $AFS_CLIENT && test -x $AFSD  ; then
306                 generate_cacheinfo
307                 choose_afsdoptions
308                 $AFSD ${AFSD_OPTIONS}
309                 test "$afs_rh" && touch /var/lock/subsys/afs
310                 $AFS_POST_INIT
311         fi
312     fi
313         ;;
314
315   stop)
316     if [ ! "$afs_rh" -o -f /var/lock/subsys/afs ]; then
317         # Stop AFS
318         echo "Stopping AFS services..... "
319
320         if  is_on $AFS_CLIENT  ; then
321                 if [ -x $KILLAFS ] ; then
322                         runcmd "Sending all processes using /afs the TERM signal ..." $KILLAFS TERM
323                         runcmd "Sending all processes using /afs the KILL signal ..." $KILLAFS KILL
324                 fi
325                 umount /afs
326         fi
327
328         if  is_on $AFS_SERVER && test -x $BOS ; then
329                 echo "Stopping AFS bosserver"
330                 $BOS shutdown localhost -localauth -wait
331                 killall -HUP bosserver
332         fi
333
334         LIBAFS=`/sbin/lsmod | fgrep libafs`
335         if [ -n "$LIBAFS" ] ; then
336                 LIBAFS=`echo $LIBAFS | awk 'BEGIN { FS = " " } { print $1 }'`
337                 /sbin/rmmod $LIBAFS
338         fi
339
340         rm -f /var/lock/subsys/afs
341     fi
342         ;;
343
344   restart)
345         # Restart AFS
346         $0 stop
347         $0 start
348         ;;
349
350   *)
351         echo Usage: 'afs <start|stop|restart>'
352
353 esac
354
355 exit 0
356
357 action fool the Red Hat initscripts