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