Patch from Tom Hughes: set VG_(max_fd) based on the current file
descriptor limit rather than assuming 1024.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2127 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h
index 179e41f..0ce9b13 100644
--- a/coregrind/vg_include.h
+++ b/coregrind/vg_include.h
@@ -108,14 +108,9 @@
give finer interleaving but much increased scheduling overheads. */
#define VG_SCHEDULING_QUANTUM 50000
-/* Maximum FD Valgrind can use for its internal file descriptors. */
-#define VG_MAX_SAFE_FD 1024 /* usual ulimit */
-
-/* Maximum allowed application-visible file descriptor. Valgrind's
- internal fds hide above this (starting at VG_MAX_FD+1). This is
- derived from the default fd limit (1024) minus the 2 fds per thread
- and a small number of extra fds. */
-#define VG_MAX_FD (VG_MAX_SAFE_FD - (VG_N_THREADS*2 + 4))
+/* Number of file descriptors that Valgrind tries to reserve for
+ it's own use - two per thread plues a small number of extras. */
+#define VG_N_RESERVED_FDS (VG_N_THREADS*2 + 4)
/* Stack size for a thread. We try and check that they do not go
beyond it. */
@@ -182,6 +177,9 @@
/* pgrp of process (global to all threads) */
extern Int VG_(main_pgrp);
+/* Maximum allowed application-visible file descriptor */
+extern Int VG_(max_fd);
+
/* Should we stop collecting errors if too many appear? default: YES */
extern Bool VG_(clo_error_limit);
/* Enquire about whether to attach to GDB at errors? default: NO */
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index 9222f2e..f007714 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -153,6 +153,9 @@
/* PGRP of process */
Int VG_(main_pgrp);
+/* Maximum allowed application-visible file descriptor */
+Int VG_(max_fd);
+
/* Words. */
static Int baB_off = 0;
@@ -1109,7 +1112,7 @@
}
/* Move logfile_fd into the safe range, so it doesn't conflict with any app fds */
- eventually_logfile_fd = VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_DUPFD, VG_MAX_FD+1);
+ eventually_logfile_fd = VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_DUPFD, VG_(max_fd)+1);
if (eventually_logfile_fd < 0)
VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range");
else {
@@ -1364,6 +1367,7 @@
void VG_(main) ( const KickstartParams *kp, void (*tool_init)(void), void *tool_dlhandle )
{
VgSchedReturnCode src;
+ struct vki_rlimit rl;
/* initial state */
if (0)
@@ -1414,6 +1418,25 @@
VG_(atfork)(NULL, NULL, newpid);
newpid(VG_INVALID_THREADID);
+ /* Get the current file descriptor limits. */
+ if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
+ rl.rlim_cur = 1024;
+ rl.rlim_max = 1024;
+ }
+
+ /* Work out where to move the soft limit to. */
+ if (rl.rlim_cur + VG_N_RESERVED_FDS <= rl.rlim_max) {
+ rl.rlim_cur = rl.rlim_cur + VG_N_RESERVED_FDS;
+ } else {
+ rl.rlim_cur = rl.rlim_max;
+ }
+
+ /* Reserve some file descriptors for our use. */
+ VG_(max_fd) = rl.rlim_cur - VG_N_RESERVED_FDS;
+
+ /* Update the soft limit. */
+ VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
+
/* Read /proc/self/maps into a buffer. Must be before:
- SK_(pre_clo_init)(): so that if it calls VG_(malloc)(), any mmap'd
superblocks are not erroneously identified as being owned by the
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index dbf78eb..850e178 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -1203,13 +1203,13 @@
{
Int newfd;
- newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_MAX_FD+1);
+ newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(max_fd)+1);
if (newfd != -1)
VG_(close)(oldfd);
VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
- vg_assert(newfd > VG_MAX_FD);
+ vg_assert(newfd > VG_(max_fd));
return newfd;
}
@@ -1429,6 +1429,17 @@
}
+/* Support for setrlimit. */
+Int VG_(setrlimit) (Int resource, struct vki_rlimit *rlim)
+{
+ Int res;
+ /* res = setrlimit( resource, rlim ); */
+ res = VG_(do_syscall)(__NR_setrlimit, (UInt)resource, (UInt)rlim);
+ if(VG_(is_kerror)(res)) res = -1;
+ return res;
+}
+
+
/* Support for getdents. */
Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count)
{
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index 0e5ffb0..a213adc 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -311,7 +311,7 @@
{
OpenFd *i = allocated_fds;
- if (fd > VG_MAX_FD)
+ if (fd > VG_(max_fd))
return; /* Valgrind internal */
while(i) {
@@ -344,7 +344,7 @@
{
OpenFd *i;
- if (fd > VG_MAX_FD)
+ if (fd > VG_(max_fd))
return; /* Valgrind internal */
/* Check to see if this fd is already open. */
@@ -889,7 +889,7 @@
/* Return true if we're allowed to use or create this fd */
static Bool fd_allowed(Int fd, const Char *syscall, ThreadId tid)
{
- if (fd < 0 || fd > VG_MAX_FD || fd == VG_(clo_logfile_fd)) {
+ if (fd < 0 || fd > VG_(max_fd) || fd == VG_(clo_logfile_fd)) {
VG_(message)(Vg_UserMsg,
"Warning: invalid file descriptor %d in syscall %s()",
fd, syscall);
@@ -4155,7 +4155,7 @@
switch (arg1 /* request */) {
case SYS_SOCKETPAIR:
- /* XXX TODO: check return fd against VG_MAX_FD */
+ /* XXX TODO: check return fd against VG_(max_fd) */
VG_TRACK( post_mem_write, ((UInt*)arg2)[3], 2*sizeof(int) );
if(VG_(clo_track_fds)) {
record_fd_open(tid, ((UInt*)((UInt*)arg2)[3])[0], NULL);
diff --git a/include/vg_skin.h.base b/include/vg_skin.h.base
index cfee479..e7ca38f 100644
--- a/include/vg_skin.h.base
+++ b/include/vg_skin.h.base
@@ -396,6 +396,9 @@
/* Get client resource limit*/
extern Int VG_(getrlimit) ( Int resource, struct vki_rlimit *rlim );
+/* Set client resource limit*/
+extern Int VG_(setrlimit) ( Int resource, struct vki_rlimit *rlim );
+
/* Crude stand-in for the glibc system() call. */
extern Int VG_(system) ( Char* cmd );