From 9add9f95c334f68769e17b6814abe0b781d83082 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 4 Mar 2009 09:12:49 +0000
Subject: [PATCH] Don't actively violate the system limit of maximum open files
 (RLIMIT_NOFILE). This avoids irritating kernel logs (if system overstep
 violations are enabled) and also the grsecurity alert when starting
 PostgreSQL.

original patch by Jacek Drobiecki

References:
http://archives.postgresql.org/pgsql-bugs/2004-05/msg00103.php
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=248967
---
 src/backend/storage/file/fd.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index b91946a0350..7749d5a4052 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.147 2009/01/12 05:10:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.148 2009/03/04 09:12:49 petere Exp $
  *
  * NOTES:
  *
@@ -45,6 +45,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>		/* for getrlimit */
+#endif
 
 #include "miscadmin.h"
 #include "access/xact.h"
@@ -361,15 +364,35 @@ count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
 	int			used = 0;
 	int			highestfd = 0;
 	int			j;
+#ifdef HAVE_GETRLIMIT
+	struct rlimit rlim;
+	int			getrlimit_status;
+#endif
 
 	size = 1024;
 	fd = (int *) palloc(size * sizeof(int));
 
+#ifdef HAVE_GETRLIMIT
+# ifdef RLIMIT_NOFILE            /* most platforms use RLIMIT_NOFILE */
+	getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
+# else                           /* but BSD doesn't ... */
+	getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
+# endif /* RLIMIT_NOFILE */
+	if (getrlimit_status != 0)
+		ereport(WARNING, (errmsg("getrlimit failed: %m")));
+#endif /* HAVE_GETRLIMIT */
+
 	/* dup until failure or probe limit reached */
 	for (;;)
 	{
 		int			thisfd;
 
+#ifdef HAVE_GETRLIMIT
+		/* don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on some platforms */
+		if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
+			break;
+#endif
+
 		thisfd = dup(0);
 		if (thisfd < 0)
 		{
-- 
GitLab