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