Skip to content
Snippets Groups Projects
Commit 623ba816 authored by Tilghman Lesher's avatar Tilghman Lesher
Browse files

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


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@260292 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent e940ef8c
No related branches found
No related tags found
No related merge requests found
......@@ -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,14 +422,44 @@ void closefrom(int n)
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);
#else
long flags = fcntl(x, F_GETFD);
if (flags == -1 && errno == EBADF) {
continue;
}
fcntl(x, F_SETFD, flags | FD_CLOEXEC);
#endif
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment