When running multiple nfsd processes, there is one master process and several slave processes. As soon as the master process receives a SIGUSR1 all nfsd will terminate. This results in a race condition when shutting down nfsd. The kill signal is not send to a list of PIDs, but a list of PIDs is iterated and kill(1) called for every PID. As soon as the kill-loop hits the master nfsd, all subsequent kills will go to stale PIDs eventually killing of other innocent processes. Fix: This is only a proof of concept as I'm not sure if this should be kludged into rc.subr or if we should provide a minimal override in rc.d/nfsd. You might wanna diff the two functions to see what I did. (Change _fp_args, extend the if test to if-master-and-same-jailid). --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="nfsd.diff" --h31gzZEtNLTqOjlF----xdBw7WMWkCOf9pUgybsEZmZW6KRcfIwIVRGQHAZ69zrkDTRv Content-Type: text/plain; name="nfsd.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="nfsd.diff" --- nfsd 2006-10-18 11:15:50.000000000 +0200 +++ nfsd.new 2006-10-18 11:15:47.000000000 +0200 @@ -44,4 +44,42 @@ return 0 } +# Overwrite the _find_processes() function. We are only interested in the +# nfsd master process. Only this one should get the kill signal. + +_find_processes() +{ + if [ $# -ne 3 ]; then + err 3 'USAGE: _find_processes procname interpreter psargs' + fi + _procname=$1 + _interpreter=$2 + _psargs=$3 + + _pref= + _procnamebn=${_procname##*/} + _fp_args='_arg0 _argv _x' + _fp_match='case "$_arg0" in + $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})"|"[${_procnamebn}]")' + + _proccheck=' + ps 2>/dev/null -o "pid,jid,command" '"$_psargs"' | + while read _npid _jid '"$_fp_args"'; do + case "$_npid" in + PID) + continue;; + esac; '"$_fp_match"' + if [ "$_argv" = "master" -a "$JID" -eq "$_jid" ]; + then echo -n "$_pref$_npid"; + _pref=" "; + fi + ;; + esac + done' + +# debug "in _find_processes: proccheck is ($_proccheck)." + eval $_proccheck +} + + run_rc_command "$1" How-To-Repeat: Crank up the number of processes to make it more obvious: nfs_server_enable="YES" nfs_server_flags="-u -t -n 64" run /etc/rc.d/nfsd start and /etc/rc.d/nfsd stop. You will most probably see several errors from kill. Check $?
Responsible Changed From-To: freebsd-bugs->freebsd-rc Over to maintainer(s).
State Changed From-To: open->feedback I think that using a pidfile for the nfsd master sprocess would be cleaner. I'm reluctant to rewrite start_cmd for that purpose though... perhaps we should make a generic macro for rc to echo $$ > $pidfile; it seems commonly required.
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
Keyword: patch or patch-ready – in lieu of summary line prefix: [patch] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>