Subject: bin/18391: nfsd glitch for poll() conversion
To: None <gnats-bugs@gnats.netbsd.org>
From: Geoff C.Wing <gcw@primenet.com.au>
List: netbsd-bugs
Date: 09/24/2002 12:10:46
>Number:         18391
>Category:       bin
>Synopsis:       nfsd (master) has a high CPU usage loop and poll failure
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Sep 23 19:11:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Geoff C. Wing
>Release:        NetBSD 1.6H (2002/09/23)
>Organization:
>Environment:
System: NetBSD sparkles.primenet.com.au 1.6H NetBSD 1.6H (SPARKLES) #0: Mon Sep 23 14:45:01 EST 2002 gcw@sparkles.primenet.com.au:/usr/netbsd/src/sys/arch/i386/compile/SPARKLES i386
Architecture: i386
Machine: i386
>Description:
	nfsd goes into a high CPU usage loop after conversion to poll()

	With the old code (1.36) the FD_ISSET(..., &ready)) calls were
	always true for only one connection because select() was not
	called to modify "ready" var, so it waited on the accept() call.
	Now, poll() may not be called and the accept() call is never made.
	So we get stuck in a for(;;) { 0; } loop

>How-To-Repeat:
	
>Fix:

--- nfsd.c.org	Mon Sep 23 16:37:39 2002
+++ nfsd.c	Tue Sep 24 11:59:38 2002
@@ -728,11 +728,9 @@
 	 * into the kernel for the mounts.
 	 */
 	for (;;) {
-		if (connect_type_cnt > 1) {
-			if (poll(set, 4, INFTIM) < 1) {
-				syslog(LOG_ERR, "select failed: %m");
-				exit(1);
-			}
+		if (poll(set, 4, INFTIM) < 1) {
+			syslog(LOG_ERR, "poll failed: %m");
+			exit(1);
 		}
 
 		if (set[0].revents & POLLIN) {
@@ -795,7 +793,7 @@
 			len = sizeof(inetpeer);
 			if ((msgsock = accept(tpipsock,
 			    (struct sockaddr *)&inetpeer, &len)) < 0) {
-				syslog(LOG_ERR, "Accept failed: %m");
+				syslog(LOG_ERR, "accept failed: %m");
 				exit(1);
 			}
 			if (setsockopt(msgsock, SOL_SOCKET,

>Release-Note:
>Audit-Trail:
>Unformatted: