summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-10-01 17:38:48 +0200
committerLennart Poettering <lennart@poettering.net>2018-10-16 16:33:55 +0200
commit99ab6fdf8c68bbe05a127b59ae03d2156d6ea856 (patch)
treedb8e05701daeddf7deb883c29989794451da5ef7
parentd6e069f412edc02a0f2130fa47955d02e378d5f5 (diff)
downloadsystemd-99ab6fdf8c68bbe05a127b59ae03d2156d6ea856.tar.gz
systemd-99ab6fdf8c68bbe05a127b59ae03d2156d6ea856.tar.bz2
systemd-99ab6fdf8c68bbe05a127b59ae03d2156d6ea856.zip
core: add a new call for bumping RLIMIT_NOFILE to "high" values
Following discussions with some kernel folks at All Systems Go! it appears that file descriptors are not really as expensive as they used to be (both memory and performance-wise) and it should thus be OK to allow programs (including unprivileged ones) to have more of them without ill effects. Unfortunately we can't just raise the RLIMIT_NOFILE soft limit globally for all processes, as select() and friends can't handle fds >= 1024, and thus unexpecting programs might fail if they accidently get an fd outside of that range. We can however raise the hard limit, so that programs that need a lot of fds can opt-in into getting fds beyond the 1024 boundary, simply by bumping the soft limit to the now higher hard limit. This is useful for all our client code that accesses the journal, as the journal merging logic might need a lot of fds. Let's add a unified function for bumping the limit in a robust way.
-rw-r--r--src/basic/rlimit-util.c22
-rw-r--r--src/basic/rlimit-util.h2
2 files changed, 24 insertions, 0 deletions
diff --git a/src/basic/rlimit-util.c b/src/basic/rlimit-util.c
index be1ba615ec..d63b85850c 100644
--- a/src/basic/rlimit-util.c
+++ b/src/basic/rlimit-util.c
@@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "extract-word.h"
+#include "fd-util.h"
#include "format-util.h"
#include "macro.h"
#include "missing.h"
@@ -360,3 +361,24 @@ void rlimit_free_all(struct rlimit **rl) {
for (i = 0; i < _RLIMIT_MAX; i++)
rl[i] = mfree(rl[i]);
}
+
+int rlimit_nofile_bump(int limit) {
+ int r;
+
+ /* Bumps the (soft) RLIMIT_NOFILE resource limit as close as possible to the specified limit. If a negative
+ * limit is specified, bumps it to the maximum the kernel and the hard resource limit allows. This call should
+ * be used by all our programs that might need a lot of fds, and that know how to deal with high fd numbers
+ * (i.e. do not use select() — which chokes on fds >= 1024) */
+
+ if (limit < 0)
+ limit = read_nr_open();
+
+ if (limit < 3)
+ limit = 3;
+
+ r = setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(limit));
+ if (r < 0)
+ return log_debug_errno(r, "Failed to set RLIMIT_NOFILE: %m");
+
+ return 0;
+}
diff --git a/src/basic/rlimit-util.h b/src/basic/rlimit-util.h
index c2ea6f846b..6139af3ff5 100644
--- a/src/basic/rlimit-util.h
+++ b/src/basic/rlimit-util.h
@@ -20,3 +20,5 @@ int rlimit_format(const struct rlimit *rl, char **ret);
void rlimit_free_all(struct rlimit **rl);
#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
+
+int rlimit_nofile_bump(int limit);