Bug 104549 - [patch] rc.d/nfsd needs special _find_processes function
Summary: [patch] rc.d/nfsd needs special _find_processes function
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: conf (show other bugs)
Version: 6.2-PRERELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
Depends on:
Reported: 2006-10-18 21:10 UTC by Ulrich Spoerlein
Modified: 2018-01-03 05:13 UTC (History)
1 user (show)

See Also:

file.diff (1.03 KB, patch)
2006-10-18 21:10 UTC, Ulrich Spoerlein
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ulrich Spoerlein 2006-10-18 21:10:17 UTC
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).

Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="nfsd.diff"

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.
+	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_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 $?
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2006-10-18 21:26:33 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-rc

Over to maintainer(s).
Comment 2 Chris Rees freebsd_committer 2012-11-01 19:24:19 UTC
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.
Comment 3 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:39 UTC
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