summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/linux.46
-rw-r--r--sys/compat/linux/linux_emul.c30
-rw-r--r--sys/compat/linux/linux_mib.c5
-rw-r--r--sys/compat/linux/linux_mib.h1
4 files changed, 41 insertions, 1 deletions
diff --git a/share/man/man4/linux.4 b/share/man/man4/linux.4
index 997dc16d7692..4703bdd3a21e 100644
--- a/share/man/man4/linux.4
+++ b/share/man/man4/linux.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 16, 2019
+.Dd June 10, 2020
.Dt LINUX 4
.Os
.Sh NAME
@@ -95,6 +95,10 @@ variables and
.Xr loader 8
tunables:
.Bl -tag -width indent
+.It Va compat.linux.default_openfiles
+Default soft openfiles resource limit for Linux applications.
+Set to -1 to disable the limit.
+Defaults to 1024.
.It Va compat.linux.emul_path
Path to the Linux run-time environment.
Defaults to
diff --git a/sys/compat/linux/linux_emul.c b/sys/compat/linux/linux_emul.c
index e88eb554aed1..7a92e0651c12 100644
--- a/sys/compat/linux/linux_emul.c
+++ b/sys/compat/linux/linux_emul.c
@@ -42,10 +42,12 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/sx.h>
#include <sys/proc.h>
+#include <sys/resourcevar.h>
#include <sys/syscallsubr.h>
#include <sys/sysent.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_persona.h>
#include <compat/linux/linux_util.h>
@@ -87,6 +89,32 @@ pem_find(struct proc *p)
return (pem);
}
+/*
+ * Linux apps generally expect the soft open file limit to be set
+ * to 1024, often iterating over all the file descriptors up to that
+ * limit instead of using closefrom(2). Give them what they want,
+ * unless there already is a resource limit in place.
+ */
+static void
+linux_set_default_openfiles(struct thread *td, struct proc *p)
+{
+ struct rlimit rlim;
+ int error;
+
+ if (linux_default_openfiles < 0)
+ return;
+
+ PROC_LOCK(p);
+ lim_rlimit_proc(p, RLIMIT_NOFILE, &rlim);
+ PROC_UNLOCK(p);
+ if (rlim.rlim_cur != rlim.rlim_max ||
+ rlim.rlim_cur <= linux_default_openfiles)
+ return;
+ rlim.rlim_cur = linux_default_openfiles;
+ error = kern_proc_setrlimit(td, p, RLIMIT_NOFILE, &rlim);
+ KASSERT(error == 0, ("kern_proc_setrlimit failed"));
+}
+
void
linux_proc_init(struct thread *td, struct thread *newtd, int flags)
{
@@ -115,6 +143,8 @@ linux_proc_init(struct thread *td, struct thread *newtd, int flags)
p->p_emuldata = pem;
}
newtd->td_emuldata = em;
+
+ linux_set_default_openfiles(td, p);
} else {
p = td->td_proc;
diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c
index d1838595d2eb..65ca97461b62 100644
--- a/sys/compat/linux/linux_mib.c
+++ b/sys/compat/linux/linux_mib.c
@@ -63,6 +63,11 @@ static unsigned linux_osd_jail_slot;
SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"Linux mode");
+int linux_default_openfiles = 1024;
+SYSCTL_INT(_compat_linux, OID_AUTO, default_openfiles, CTLFLAG_RWTUN,
+ &linux_default_openfiles, 0,
+ "Default soft openfiles resource limit, or -1 for unlimited");
+
int linux_ignore_ip_recverr = 1;
SYSCTL_INT(_compat_linux, OID_AUTO, ignore_ip_recverr, CTLFLAG_RWTUN,
&linux_ignore_ip_recverr, 0, "Ignore enabling IP_RECVERR");
diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h
index 129676673397..d7a13a456125 100644
--- a/sys/compat/linux/linux_mib.h
+++ b/sys/compat/linux/linux_mib.h
@@ -62,6 +62,7 @@ int linux_kernver(struct thread *td);
#define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000)
+extern int linux_default_openfiles;
extern int linux_ignore_ip_recverr;
extern int linux_preserve_vstatus;
extern bool linux_map_sched_prio;