923a60
From 4fab90faea400463fd77e4dc0be1438da59718fd Mon Sep 17 00:00:00 2001
923a60
From: Christian Brauner <christian.brauner@ubuntu.com>
923a60
Date: Wed, 26 Apr 2017 06:18:10 +0200
923a60
Subject: [PATCH] main: improve RLIMIT_NOFILE handling (#5795)
923a60
923a60
This has systemd look at /proc/sys/fs/nr_open to find the current maximum of
923a60
open files compiled into the kernel and tries to set the RLIMIT_NOFILE max to
923a60
it. This has the advantage the value chosen as limit is less arbitrary and also
923a60
improves the behavior of systemd in containers that have an rlimit set: When
923a60
systemd currently starts in a container that has RLIMIT_NOFILE set to e.g.
923a60
100000 systemd will lower it to 65536. With this patch systemd will try to set
923a60
the nofile limit to the allowed kernel maximum. If this fails, it will compute
923a60
the minimum of the current set value (the limit that is set on the container)
923a60
and the maximum value as soft limit and the currently set maximum value as the
923a60
maximum value. This way it retains the limit set on the container.
923a60
923a60
(cherry picked from commit 6385cb31ef443be3e0d6da5ea62a267a49174688)
923a60
923a60
Resolves: #1585913
923a60
---
923a60
 src/core/main.c | 12 +++++++++++-
923a60
 1 file changed, 11 insertions(+), 1 deletion(-)
923a60
923a60
diff --git a/src/core/main.c b/src/core/main.c
923a60
index 5554ef468d..2d70ed07ed 100644
923a60
--- a/src/core/main.c
923a60
+++ b/src/core/main.c
923a60
@@ -1017,6 +1017,8 @@ fail:
923a60
 static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
923a60
         struct rlimit nl;
923a60
         int r;
923a60
+        int min_max;
923a60
+        _cleanup_free_ char *nr_open = NULL;
923a60
 
923a60
         assert(saved_rlimit);
923a60
 
923a60
@@ -1037,8 +1039,16 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
923a60
                 arg_default_rlimit[RLIMIT_NOFILE] = rl;
923a60
         }
923a60
 
923a60
+        /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */
923a60
+        r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
923a60
+        if (r == 0)
923a60
+                r = safe_atoi(nr_open, &min_max);
923a60
+        /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
923a60
+        if (r < 0)
923a60
+                min_max = 1024 * 1024;
923a60
+
923a60
         /* Bump up the resource limit for ourselves substantially */
923a60
-        nl.rlim_cur = nl.rlim_max = 64*1024;
923a60
+        nl.rlim_cur = nl.rlim_max = min_max;
923a60
         r = setrlimit_closest(RLIMIT_NOFILE, &nl);
923a60
         if (r < 0)
923a60
                 return log_error_errno(r, "Setting RLIMIT_NOFILE failed: %m");