1d442bb
From: Stefan Hajnoczi <stefanha@redhat.com>
1d442bb
Date: Mon, 27 Jan 2020 19:01:34 +0000
1d442bb
Subject: [PATCH] virtiofsd: set maximum RLIMIT_NOFILE limit
1d442bb
MIME-Version: 1.0
1d442bb
Content-Type: text/plain; charset=UTF-8
1d442bb
Content-Transfer-Encoding: 8bit
1d442bb
1d442bb
virtiofsd can exceed the default open file descriptor limit easily on
1d442bb
most systems.  Take advantage of the fact that it runs as root to raise
1d442bb
the limit.
1d442bb
1d442bb
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1d442bb
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
1d442bb
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
1d442bb
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
1d442bb
(cherry picked from commit 01a6dc95ec7f71eeff9963fe3cb03d85225fba3e)
1d442bb
---
1d442bb
 tools/virtiofsd/passthrough_ll.c | 32 ++++++++++++++++++++++++++++++++
1d442bb
 1 file changed, 32 insertions(+)
1d442bb
1d442bb
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
1d442bb
index d53cb1e005..c281d817af 100644
1d442bb
--- a/tools/virtiofsd/passthrough_ll.c
1d442bb
+++ b/tools/virtiofsd/passthrough_ll.c
1d442bb
@@ -53,6 +53,7 @@
1d442bb
 #include <sys/file.h>
1d442bb
 #include <sys/mount.h>
1d442bb
 #include <sys/prctl.h>
1d442bb
+#include <sys/resource.h>
1d442bb
 #include <sys/syscall.h>
1d442bb
 #include <sys/types.h>
1d442bb
 #include <sys/wait.h>
1d442bb
@@ -2268,6 +2269,35 @@ static void setup_sandbox(struct lo_data *lo, struct fuse_session *se)
1d442bb
     setup_seccomp();
1d442bb
 }
1d442bb
 
1d442bb
+/* Raise the maximum number of open file descriptors */
1d442bb
+static void setup_nofile_rlimit(void)
1d442bb
+{
1d442bb
+    const rlim_t max_fds = 1000000;
1d442bb
+    struct rlimit rlim;
1d442bb
+
1d442bb
+    if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
1d442bb
+        fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
1d442bb
+        exit(1);
1d442bb
+    }
1d442bb
+
1d442bb
+    if (rlim.rlim_cur >= max_fds) {
1d442bb
+        return; /* nothing to do */
1d442bb
+    }
1d442bb
+
1d442bb
+    rlim.rlim_cur = max_fds;
1d442bb
+    rlim.rlim_max = max_fds;
1d442bb
+
1d442bb
+    if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
1d442bb
+        /* Ignore SELinux denials */
1d442bb
+        if (errno == EPERM) {
1d442bb
+            return;
1d442bb
+        }
1d442bb
+
1d442bb
+        fuse_log(FUSE_LOG_ERR, "setrlimit(RLIMIT_NOFILE): %m\n");
1d442bb
+        exit(1);
1d442bb
+    }
1d442bb
+}
1d442bb
+
1d442bb
 int main(int argc, char *argv[])
1d442bb
 {
1d442bb
     struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
1d442bb
@@ -2389,6 +2419,8 @@ int main(int argc, char *argv[])
1d442bb
 
1d442bb
     fuse_daemonize(opts.foreground);
1d442bb
 
1d442bb
+    setup_nofile_rlimit();
1d442bb
+
1d442bb
     /* Must be before sandbox since it wants /proc */
1d442bb
     setup_capng();
1d442bb