[svn-commits] tilghman: trunk r260292 - /trunk/main/strcompat.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Apr 30 01:19:40 CDT 2010


Author: tilghman
Date: Fri Apr 30 01:19:35 2010
New Revision: 260292

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=260292
Log:
Don't allow file descriptors to go above 64k, when we're closing them in a fork(2).

This saves time, when, even though the system allows the process limit to be
that high, the practical limit is much lower.  Also introduce an additional
optimization, in the form of using the CLOEXEC flag to close descriptors at
the right time.

(closes issue #17223)
 Reported by: dbackeberg
 Patches: 
       20100423__issue17223.diff.txt uploaded by tilghman (license 14)
 Tested by: dbackeberg

Modified:
    trunk/main/strcompat.c

Modified: trunk/main/strcompat.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/strcompat.c?view=diff&rev=260292&r1=260291&r2=260292
==============================================================================
--- trunk/main/strcompat.c (original)
+++ trunk/main/strcompat.c Fri Apr 30 01:19:35 2010
@@ -26,6 +26,8 @@
 #include <sys/resource.h>   /* for getrlimit(2) */
 #include <sys/types.h>      /* for opendir(3) */
 #include <dirent.h>         /* for opendir(3) */
+#include <unistd.h>         /* for fcntl(2) */
+#include <fcntl.h>          /* for fcntl(2) */
 
 #ifndef HAVE_STRSEP
 char *strsep(char **str, const char *delims)
@@ -420,16 +422,46 @@
 				continue;
 			}
 			if ((x = strtol(entry->d_name, &result, 10)) && x >= n) {
+#ifdef STRICT_COMPAT
 				close(x);
+#else
+				/* This isn't strictly compatible, but it's actually faster
+				 * for our purposes to set the CLOEXEC flag than to close
+				 * file descriptors.
+				 */
+				long flags = fcntl(x, F_GETFD);
+				if (flags == -1 && errno == EBADF) {
+					continue;
+				}
+				fcntl(x, F_SETFD, flags | FD_CLOEXEC);
+#endif
 			}
 		}
 		closedir(dir);
 	} else {
 		getrlimit(RLIMIT_NOFILE, &rl);
+		if (rl.rlim_cur > 65535) {
+			/* A more reasonable value.  Consider that the primary source of
+			 * file descriptors in Asterisk are UDP sockets, of which we are
+			 * limited to 65,535 per address.  We additionally limit that down
+			 * to about 10,000 sockets per protocol.  While the kernel will
+			 * allow us to set the fileno limit higher (up to 4.2 billion),
+			 * there really is no practical reason for it to be that high.
+			 */
+			rl.rlim_cur = 65535;
+		}
 		for (x = n; x < rl.rlim_cur; x++) {
+#ifdef STRICT_COMPAT
 			close(x);
-		}
-	}
-}
-#endif
-
+#else
+			long flags = fcntl(x, F_GETFD);
+			if (flags == -1 && errno == EBADF) {
+				continue;
+			}
+			fcntl(x, F_SETFD, flags | FD_CLOEXEC);
+#endif
+		}
+	}
+}
+#endif
+




More information about the svn-commits mailing list