From root@illicit12.candidhosting.com  Fri May 28 18:55:29 2004
Return-Path: <root@illicit12.candidhosting.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id AAFEF16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 28 May 2004 18:55:29 -0700 (PDT)
Received: from illicit12.candidhosting.com (illicit10.candidhosting.com [65.59.189.1])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 3ABF143D2F
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 28 May 2004 18:55:29 -0700 (PDT)
	(envelope-from root@illicit12.candidhosting.com)
Received: from illicit12.candidhosting.com (localhost [127.0.0.1])
	by illicit12.candidhosting.com (8.12.10/8.12.10) with ESMTP id i4T1t2r6007537
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 28 May 2004 21:55:02 -0400 (EDT)
	(envelope-from root@illicit12.candidhosting.com)
Received: (from root@localhost)
	by illicit12.candidhosting.com (8.12.10/8.12.10/Submit) id i4T1t1Nd007536;
	Fri, 28 May 2004 21:55:02 -0400 (EDT)
	(envelope-from root)
Message-Id: <200405290155.i4T1t1Nd007536@illicit12.candidhosting.com>
Date: Fri, 28 May 2004 21:55:02 -0400 (EDT)
From: Michael Conlen <meconlen@obfuscated.net>
Reply-To: Michael Conlen <meconlen@obfuscated.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: patch to nfsd.c to make it slightly more dynamic
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         67317
>Category:       bin
>Synopsis:       [patch] to nfsd.c to make it slightly more dynamic
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bms
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 28 19:00:43 PDT 2004
>Closed-Date:    Wed Aug 02 11:15:10 GMT 2006
>Last-Modified:  Wed Aug 02 11:15:10 GMT 2006
>Originator:     Michael Conlen
>Release:        FreeBSD 5.2.1-RELEASE-p8 i386
>Organization:
Obfuscated Networking
>Environment:
System: FreeBSD host 5.2.1-RELEASE-p8 FreeBSD 5.2.1-RELEASE-p8 #0: Thu May 27 04:36:03 EDT 2004 meconlen@obfuscated.net:/usr/obj/usr/src/sys/NFS i386


>Description:
	nfsd.c defines a static number of max proceses and creates an 
	array at that size at compile time so that signal handlers can
	access it easily. Problme is, if you need more procs you need
	to edit the source and rebuild. I hacked it up so that the 
	variables are not global and the array is not static so 
	you can create as many processes as you want. 

>How-To-Repeat:
to repeat: 
	nfsd -n 21

>Fix:

Apply the following patch rebuild and voila nfsd -n <very large number like 512)

7a8,9
>  * Modified by Michael Conlen May 28, 2004
>  *
75a78,80
> 
> #include <stdarg.h>
> 
84d88
< #define	MAXNFSDCNT	20
86,87d89
< pid_t	children[MAXNFSDCNT];	/* PIDs of children */
< int	nfsdcnt;		/* number of children */
91c93
< void	killchildren(void);
---
> void	killchildren(int, ...);
94c96
< void	reapchild(int);
---
> void	reapchild(int, ...);
139a142,143
> 	pid_t	*children;
> 	int	nfsdcnt;
159,163d162
< 			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
< 				warnx("nfsd count %d; reset to %d", nfsdcnt,
< 				    DEFNFSDCNT);
< 				nfsdcnt = DEFNFSDCNT;
< 			}
203,207d201
< 		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
< 			warnx("nfsd count %d; reset to %d", nfsdcnt,
< 			    DEFNFSDCNT);
< 			nfsdcnt = DEFNFSDCNT;
< 		}
335a330,339
> 
> 	/* allocate children */
> 	children = calloc(nfsdcnt, sizeof(pid_t));
> 	if(children == NULL ) {
> 		syslog(LOG_ERR, "malloc: %m");
> 		nfsd_exit(1);
> 	}
> 	reapchild(0, children, nfsdcnt);
> 	killchildren(0, children, nfsdcnt);
> 
770,771c774
< reapchild(signo)
< 	int signo;
---
> reapchild(int signo, ...)
775a779,791
> 	va_list argp;
> 	pid_t *children;
> 	int nfsdcnt;
> 
> 	if(signo == 0) {
> 		va_start(argp, signo);
> 		children = va_arg(argp, pid_t *);
> 		nfsdcnt = va_arg(argp, int);	
> 		va_end(argp);
> 		return;
> 	}	
> 
> 
791,792c807,809
< void
< killchildren()
---
> /* we need something before the ..., better hack than globals */
> 
> void killchildren(int signo, ...)
795a813,826
> 
> 	va_list argp;
> 	pid_t *children;
> 	int nfsdcnt;
> 
> 	if(signo == 0) {
> 		va_start(argp, signo);
> 		children = va_arg(argp, pid_t *);
> 		nfsdcnt = va_arg(argp, int);	
> 		va_end(argp);
> 		return;
> 	}	
> 
> 
823c854
< 	killchildren();
---
> 	killchildren(0);
842a874
> 

>Release-Note:
>Audit-Trail:

From: Michael Conlen <meconlen@obfuscated.net>
To: freebsd-gnats-submit@FreeBSD.org, meconlen@obfuscated.net
Cc:  
Subject: Re: bin/67317: patch to nfsd.c to make it slightly more dynamic
Date: Sat, 29 May 2004 03:01:13 -0400

 Proper diffs. Forgot that the variables in the functions should be 
 static, not sure how to test that properly, but I'd suspect a system 
 might act funny when you tried to kill nfsd with the previous patch, 
 until it segfaulted. This is the first C code I've done in six months, 
 so look over it, though it seems to work fine on a system doing lots of 
 volume.
 
 Cheers.
 
 
 7a8,9
  >  * Modified by Michael Conlen May 28, 2004
  >  *
 75a78,80
  >
  > #include <stdarg.h>
  >
 84d88
 < #define	MAXNFSDCNT	20
 86,87d89
 < pid_t	children[MAXNFSDCNT];	/* PIDs of children */
 < int	nfsdcnt;		/* number of children */
 91c93
 < void	killchildren(void);
 ---
  > void	killchildren(int, ...);
 94c96
 < void	reapchild(int);
 ---
  > void	reapchild(int, ...);
 139a142,143
  > 	pid_t	*children;
  > 	int	nfsdcnt;
 159,163d162
 < 			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
 < 				warnx("nfsd count %d; reset to %d", nfsdcnt,
 < 				    DEFNFSDCNT);
 < 				nfsdcnt = DEFNFSDCNT;
 < 			}
 203,207d201
 < 		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
 < 			warnx("nfsd count %d; reset to %d", nfsdcnt,
 < 			    DEFNFSDCNT);
 < 			nfsdcnt = DEFNFSDCNT;
 < 		}
 335a330,339
  >
  > 	/* allocate children */
  > 	children = calloc(nfsdcnt, sizeof(pid_t));
  > 	if(children == NULL ) {
  > 		syslog(LOG_ERR, "malloc: %m");
  > 		nfsd_exit(1);
  > 	}
  > 	reapchild(0, children, nfsdcnt);
  > 	killchildren(0, children, nfsdcnt);
  >
 770,771c774
 < reapchild(signo)
 < 	int signo;
 ---
  > reapchild(int signo, ...)
 775a779,791
  > 	va_list argp;
  > 	pid_t *children;
  > 	int nfsdcnt;
  >
  > 	if(signo == 0) {
  > 		va_start(argp, signo);
  > 		children = va_arg(argp, pid_t *);
  > 		nfsdcnt = va_arg(argp, int);	
  > 		va_end(argp);
  > 		return;
  > 	}	
  >
  >
 791,792c807,809
 < void
 < killchildren()
 ---
  > /* we need something before the ..., better hack than globals */
  >
  > void killchildren(int signo, ...)
 795a813,826
  >
  > 	va_list argp;
  > 	pid_t *children;
  > 	int nfsdcnt;
  >
  > 	if(signo == 0) {
  > 		va_start(argp, signo);
  > 		children = va_arg(argp, pid_t *);
  > 		nfsdcnt = va_arg(argp, int);	
  > 		va_end(argp);
  > 		return;
  > 	}	
  >
  >
 823c854
 < 	killchildren();
 ---
  > 	killchildren(0);
 842a874
  >
 
State-Changed-From-To: open->analyzed 
State-Changed-By: bms 
State-Changed-When: Tue Jun 15 23:46:11 GMT 2004 
State-Changed-Why:  
Revised patch provided to submitter for testing/evaluation 


Responsible-Changed-From-To: freebsd-bugs->bms 
Responsible-Changed-By: bms 
Responsible-Changed-When: Tue Jun 15 23:46:11 GMT 2004 
Responsible-Changed-Why:  
I'll take this 

http://www.freebsd.org/cgi/query-pr.cgi?pr=67317 

From: Bruce M Simpson <bms@spc.org>
To: Michael Conlen <meconlen@obfuscated.net>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: bin/67317: patch to nfsd.c to make it slightly more dynamic
Date: Wed, 16 Jun 2004 00:46:05 +0100

 --GV0iVqYguTV4Q9ER
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Hi,
 
 There were a number of style and coding issues with the patch:
  - Please submit patches in unified diff format (diff -u).
  - Include file ordering
  - Whitespace pass needed
  - Not sure why reapchild()/killchildren() is called so early on;
    this appears to be a no-op, the processes haven't been forked yet,
    and no state gets set up.
  - Inappropriate use of varargs.
    None of the arguments are really necessary for these functions;
    the signo can be ignored if they're declared void when treated
    as signal handlers, and the function pointer casted to sig_t.
  - 'children' has to be global, because of nfsd_exit() possibly
    being called in the context of a signal handler in the nfsd
    master process. So shifting it out of globals serves no purpose,
    although most of the globals could safely be declared 'static'
    as nfsd.c is self-contained.
 
 I've enclosed a revised patch for you to play with. I'm inclined to
 preserve MAXNFSDCNT and either bump it up, or expose it to make.conf
 tweaking in some way, which is probably more appropriate.
 
 Regards,
 BMS
 
 --GV0iVqYguTV4Q9ER
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="nfsd.patch"
 
 Index: nfsd.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/nfsd/nfsd.c,v
 retrieving revision 1.29
 diff -u -r1.29 nfsd.c
 --- nfsd.c	11 Jan 2004 01:29:03 -0000	1.29
 +++ nfsd.c	15 Jun 2004 23:40:12 -0000
 @@ -67,6 +67,7 @@
  #include <err.h>
  #include <errno.h>
  #include <signal.h>
 +#include <stdarg.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
 @@ -81,9 +82,8 @@
  int	debug = 0;
  #endif
  
 -#define	MAXNFSDCNT	20
  #define	DEFNFSDCNT	 4
 -pid_t	children[MAXNFSDCNT];	/* PIDs of children */
 +pid_t	*children;		/* PIDs of children */
  int	nfsdcnt;		/* number of children */
  
  void	cleanup(int);
 @@ -91,7 +91,7 @@
  void	killchildren(void);
  void	nfsd_exit(int);
  void	nonfs(int);
 -void	reapchild(int);
 +void	reapchild(void);
  int	setbindhost(struct addrinfo **ia, const char *bindhost,
  	    struct addrinfo hints);
  void	start_server(int);
 @@ -156,11 +156,6 @@
  			break;
  		case 'n':
  			nfsdcnt = atoi(optarg);
 -			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
 -				warnx("nfsd count %d; reset to %d", nfsdcnt,
 -				    DEFNFSDCNT);
 -				nfsdcnt = DEFNFSDCNT;
 -			}
  			break;
  		case 'h':
  			bindhostc++;
 @@ -200,11 +195,6 @@
  		usage();
  	if (argc == 1) {
  		nfsdcnt = atoi(argv[0]);
 -		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
 -			warnx("nfsd count %d; reset to %d", nfsdcnt,
 -			    DEFNFSDCNT);
 -			nfsdcnt = DEFNFSDCNT;
 -		}
  	}
  
  	ip6flag = 1;
 @@ -327,12 +317,19 @@
  		(void)signal(SIGQUIT, SIG_IGN);
  	}
  	(void)signal(SIGSYS, nonfs);
 -	(void)signal(SIGCHLD, reapchild);
 +	(void)signal(SIGCHLD, (sig_t)reapchild);
  
  	openlog("nfsd", LOG_PID, LOG_DAEMON);
  
  	/* If we use UDP only, we start the last server below. */
  	srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1;
 +
 +	children = calloc(nfsdcnt, sizeof(pid_t));
 +	if (children == NULL) {
 +		syslog(LOG_ERR, "calloc: %m");
 +		nfsd_exit(1);
 +	}
 +
  	for (i = 0; i < srvcnt; i++) {
  		switch ((pid = fork())) {
  		case -1:
 @@ -775,8 +772,7 @@
  }
  
  void
 -reapchild(signo)
 -	int signo;
 +reapchild(void)
  {
  	pid_t pid;
  	int i;
 @@ -797,7 +793,7 @@
  }
  
  void
 -killchildren()
 +killchildren(void)
  {
  	int i;
  
 
 --GV0iVqYguTV4Q9ER--
State-Changed-From-To: analyzed->closed 
State-Changed-By: bms 
State-Changed-When: Wed Aug 2 11:14:40 UTC 2006 
State-Changed-Why:  
Something like this got committed in the 5.x lifetime. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=67317 
>Unformatted:
