Bruce Dubbs wrote: > Since the real nfsd process runs in the kernel, we have to look at the > code there to see how it responds to a particular signal. I haven't > gotten there yet, but need to find out what signal(s) it wants for > proper shutdown. A quick grep in fs/nfs for SIG shows the only thing > that show up is SIGKILL.
A little more digging shows that the kernel nfsd code recognizes four signals. All others are ignored. (Including TERM) #define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT)) I cannot see how these are differentiated. My understanding was that there is a signal table for a process. For each potential signal there is an address or null. If it's null, the kernel proper takes the default action as defined in man 7 signal: SIGHUP 1 Term Hangup detected SIGINT 2 Term Interrupt from keyboard SIGQUIT 3 Core Quit from keyboard SIGKILL 9 Term Kill signal Where Term Default action is to terminate the process. Core Default action is to terminate the process and dump core. Typically in a normal user process, signals are taken over by the sigaction() call. I'm not sure about the kernel, but I saw nothing similar in the code. In any case, the signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. My recommendation is to use KILL as the signal to shut down NFS. We still need to add a delay after sending this signal. This will require updating the functions script from LFS in /etc/rc.d/init.d. Something like: --- functions.orig 2007-01-28 17:03:25.000000000 -0600 +++ functions 2007-01-28 17:07:01.000000000 -0600 @@ -506,7 +506,7 @@ } #******************************************************************************* -# Function - killproc [-p pidfile] pathname [signal] +# Function - killproc [-p pidfile] [-w waittime] pathname [signal] # # Purpose: # @@ -514,6 +514,9 @@ # pathname, pathname to the specified program # signal, send this signal to pathname # +# -w waittime, is the time to wait after all signals are +# sent to check for proper process shutdown +# # Outputs: return 0 - Success # return 2 - Invalid of excessive number of arguments, # warning in stdout @@ -530,6 +533,7 @@ { local pidfile="" local killsig="" + local waittime=0 pidlist="" # This will ensure compatibility with previous LFS Bootscripts @@ -544,6 +548,10 @@ pidfile="${2}" shift 2 ;; + -w) + waittime="${2}" + shift 2 + ;; -*) log_failure_msg "Unknown Option: ${1}" return 2 @@ -587,6 +595,8 @@ fi done + sleep $waittime + if [ -z "${killsig}" ]; then pidofproc -s "${1}" and also change int.d/nfsd as: --- nfs-server.orig 2007-01-28 17:11:51.000000000 -0600 +++ nfs-server 2007-01-28 17:12:33.000000000 -0600 @@ -48,7 +48,7 @@ boot_mesg "Stopping NFS nfsd..." # nfsd needs HUP.... - killproc nfsd HUP + killproc -w 1 nfsd KILL boot_mesg "Stopping NFS mountd..." killproc /usr/sbin/rpc.mountd an alternative to changing LFS functions would be to incorporate the new functionality in the above into a new function, called killnfsd, directly into nfs-server: killnfsd() { pidlist=`pidofproc nfsd` for pid in ${pidlist} do kill -KILL ${pid} 2>/dev/null done sleep 1 # Increase if needed pidofproc "${1}" > /dev/null evaluate_retval } And change what we have there now: # nfsd needs HUP.... killproc nfsd HUP to killnfsd -- Bruce -- http://linuxfromscratch.org/mailman/listinfo/blfs-dev FAQ: http://www.linuxfromscratch.org/blfs/faq.html Unsubscribe: See the above information page