Date: Wed, 18 Oct 2006 22:00:49 +0200 From: Ulrich Spoerlein <uspoerlein@gmail.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: freebsd-rc@FreeBSD.org Subject: conf/104549: rc.d/nfsd needs special _find_processes function Message-ID: <20061018200049.GA69724@coyote.q.local> Resent-Message-ID: <200610182010.k9IKAI9t045118@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 104549 >Category: conf >Synopsis: rc.d/nfsd needs special _find_processes function >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Oct 18 20:10:17 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Ulrich Spoerlein >Release: FreeBSD 6.2-PRERELEASE i386 >Organization: >Environment: >Description: 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. >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 $? >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). --- nfsd.diff begins here --- --- 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" --- nfsd.diff ends here --- --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii 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" --h31gzZEtNLTqOjlF-- >Release-Note: >Audit-Trail: >Unformatted: --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: inline
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061018200049.GA69724>