From 06c962bc87aba28a3169be6a18ce8d52060b661f Mon Sep 17 00:00:00 2001
From: neilbrown <neilbrown>
Date: Fri, 12 Sep 2003 06:37:16 +0000
Subject: [PATCH] Work around RLIMIT_NOFILE-to-big problem

---
 ChangeLog             |  9 +++++++++
 utils/mountd/mountd.c | 25 ++++++++++++++-----------
 utils/statd/statd.c   | 17 +++++++++++++++++
 3 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a9f2fcf..53514b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-09-12 NeilBrown <neilb@cse.unsw.edu.au>
+	* utils/mountd/mountd.c(main): Impose FD_SETSIZE as an upper limit
+	for RLIMIT_NOFILE
+	* utils/statd/statd.c(main): Ditto.
+
+	 michael <michael@newdream.net> discovered that svc_setreqsize in
+	glibc can segfault if RLIMIT_NOFILE is bigger than FD_SETSIZE,
+	so a simple solution is to impose a hard limit.
+
 2003-09-09  Chip Salzenberg  <chip@pobox.com>
 
 	* debian/changelog: Version 1.0.5-3.
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 0b34617..0d4ddb4 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -504,18 +504,21 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
-	if (descriptors) {
-		if (getrlimit (RLIMIT_NOFILE, &rlim) != 0) {
-			fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n",
+	if (getrlimit (RLIMIT_NOFILE, &rlim) != 0)
+		fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n",
 				argv [0], strerror(errno));
-			exit(1);
-		}
-
-		rlim.rlim_cur = descriptors;
-		if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) {
-			fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n",
-				argv [0], strerror(errno));
-			exit(1);
+	else {
+		/* glibc sunrpc code dies if getdtablesize > FD_SETSIZE */
+		if (descriptors == 0 && rlim.rlim_cur > FD_SETSIZE)
+			descriptors = FD_SETSIZE;
+		if (descriptors) {
+
+			rlim.rlim_cur = descriptors;
+			if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) {
+				fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n",
+					argv [0], strerror(errno));
+				exit(1);
+			}
 		}
 	}
 	/* Initialize logging. */
diff --git a/utils/statd/statd.c b/utils/statd/statd.c
index 93c394f..b57f71b 100644
--- a/utils/statd/statd.c
+++ b/utils/statd/statd.c
@@ -18,6 +18,7 @@
 #include <rpc/rpc.h>
 #include <rpc/pmap_clnt.h>
 #include <rpcmisc.h>
+#include <sys/resource.h>
 #include <grp.h>
 #include "statd.h"
 #include "version.h"
@@ -209,6 +210,7 @@ int main (int argc, char **argv)
 	int pid;
 	int arg;
 	int port = 0, out_port = 0;
+	struct rlimit rlim;
 
 	int pipefds[2] = { -1, -1};
 	char status;
@@ -320,6 +322,21 @@ int main (int argc, char **argv)
 						   daemon mode. */
 	}
 
+	if (getrlimit (RLIMIT_NOFILE, &rlim) != 0)
+		fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n",
+				argv [0], strerror(errno));
+	else {
+		/* glibc sunrpc code dies if getdtablesize > FD_SETSIZE */
+		if (rlim.rlim_cur > FD_SETSIZE) {
+			rlim.rlim_cur = FD_SETSIZE;
+
+			if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) {
+				fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n",
+					argv [0], strerror(errno));
+			}
+		}
+	}
+
 #ifdef SIMULATIONS
 	if (argc > 1)
 		/* LH - I _really_ need to update simulator... */
-- 
2.39.5