| From 555ec3463b3dbfd6e08eac7840419d176f113e46 Mon Sep 17 00:00:00 2001 |
| From: "Dr. David Alan Gilbert" <dgilbert@redhat.com> |
| Date: Tue, 5 May 2020 16:35:55 +0100 |
| Subject: [PATCH 4/9] virtiofsd: add --rlimit-nofile=NUM option |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com> |
| Message-id: <20200505163600.22956-3-dgilbert@redhat.com> |
| Patchwork-id: 96270 |
| O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/7] virtiofsd: add --rlimit-nofile=NUM option |
| Bugzilla: 1817445 |
| RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> |
| RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
| RH-Acked-by: Max Reitz <mreitz@redhat.com> |
| RH-Acked-by: Michael S. Tsirkin <mst@redhat.com> |
| |
| From: Stefan Hajnoczi <stefanha@redhat.com> |
| |
| Make it possible to specify the RLIMIT_NOFILE on the command-line. |
| Users running multiple virtiofsd processes should allocate a certain |
| number to each process so that the system-wide limit can never be |
| exhausted. |
| |
| When this option is set to 0 the rlimit is left at its current value. |
| This is useful when a management tool wants to configure the rlimit |
| itself. |
| |
| The default behavior remains unchanged: try to set the limit to |
| 1,000,000 file descriptors if the current rlimit is lower. |
| |
| Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
| Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> |
| Message-Id: <20200501140644.220940-2-stefanha@redhat.com> |
| Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> |
| (cherry picked from commit 6dbb716877728ce4eb51619885ef6ef4ada9565f) |
| Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com> |
| |
| tools/virtiofsd/fuse_lowlevel.h | 1 + |
| tools/virtiofsd/helper.c | 23 +++++++++++++++++++++++ |
| tools/virtiofsd/passthrough_ll.c | 22 ++++++++-------------- |
| 3 files changed, 32 insertions(+), 14 deletions(-) |
| |
| diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h |
| index 8f6d705..562fd52 100644 |
| |
| |
| @@ -1777,6 +1777,7 @@ struct fuse_cmdline_opts { |
| int syslog; |
| int log_level; |
| unsigned int max_idle_threads; |
| + unsigned long rlimit_nofile; |
| }; |
| |
| /** |
| diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c |
| index 0801cf7..9b3eddc 100644 |
| |
| |
| @@ -23,6 +23,8 @@ |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/param.h> |
| +#include <sys/time.h> |
| +#include <sys/resource.h> |
| #include <unistd.h> |
| |
| #define FUSE_HELPER_OPT(t, p) \ |
| @@ -53,6 +55,7 @@ static const struct fuse_opt fuse_helper_opts[] = { |
| FUSE_HELPER_OPT("subtype=", nodefault_subtype), |
| FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP), |
| FUSE_HELPER_OPT("max_idle_threads=%u", max_idle_threads), |
| + FUSE_HELPER_OPT("--rlimit-nofile=%lu", rlimit_nofile), |
| FUSE_HELPER_OPT("--syslog", syslog), |
| FUSE_HELPER_OPT_VALUE("log_level=debug", log_level, FUSE_LOG_DEBUG), |
| FUSE_HELPER_OPT_VALUE("log_level=info", log_level, FUSE_LOG_INFO), |
| @@ -171,6 +174,9 @@ void fuse_cmdline_help(void) |
| " default: no_writeback\n" |
| " -o xattr|no_xattr enable/disable xattr\n" |
| " default: no_xattr\n" |
| + " --rlimit-nofile=<num> set maximum number of file descriptors\n" |
| + " (0 leaves rlimit unchanged)\n" |
| + " default: 1,000,000 if the current rlimit is lower\n" |
| ); |
| } |
| |
| @@ -191,11 +197,28 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key, |
| } |
| } |
| |
| +static unsigned long get_default_rlimit_nofile(void) |
| +{ |
| + rlim_t max_fds = 1000000; /* our default RLIMIT_NOFILE target */ |
| + struct rlimit rlim; |
| + |
| + if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { |
| + fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n"); |
| + exit(1); |
| + } |
| + |
| + if (rlim.rlim_cur >= max_fds) { |
| + return 0; /* we have more fds available than required! */ |
| + } |
| + return max_fds; |
| +} |
| + |
| int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts) |
| { |
| memset(opts, 0, sizeof(struct fuse_cmdline_opts)); |
| |
| opts->max_idle_threads = 10; |
| + opts->rlimit_nofile = get_default_rlimit_nofile(); |
| opts->foreground = 1; |
| |
| if (fuse_opt_parse(args, opts, fuse_helper_opts, fuse_helper_opt_proc) == |
| diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c |
| index 50ff672..184ad0f 100644 |
| |
| |
| @@ -2711,24 +2711,18 @@ static void setup_sandbox(struct lo_data *lo, struct fuse_session *se, |
| setup_seccomp(enable_syslog); |
| } |
| |
| -/* Raise the maximum number of open file descriptors */ |
| -static void setup_nofile_rlimit(void) |
| +/* Set the maximum number of open file descriptors */ |
| +static void setup_nofile_rlimit(unsigned long rlimit_nofile) |
| { |
| - const rlim_t max_fds = 1000000; |
| - struct rlimit rlim; |
| - |
| - if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { |
| - fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n"); |
| - exit(1); |
| - } |
| + struct rlimit rlim = { |
| + .rlim_cur = rlimit_nofile, |
| + .rlim_max = rlimit_nofile, |
| + }; |
| |
| - if (rlim.rlim_cur >= max_fds) { |
| + if (rlimit_nofile == 0) { |
| return; /* nothing to do */ |
| } |
| |
| - rlim.rlim_cur = max_fds; |
| - rlim.rlim_max = max_fds; |
| - |
| if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { |
| /* Ignore SELinux denials */ |
| if (errno == EPERM) { |
| @@ -2981,7 +2975,7 @@ int main(int argc, char *argv[]) |
| |
| fuse_daemonize(opts.foreground); |
| |
| - setup_nofile_rlimit(); |
| + setup_nofile_rlimit(opts.rlimit_nofile); |
| |
| /* Must be before sandbox since it wants /proc */ |
| setup_capng(); |
| -- |
| 1.8.3.1 |
| |