From f2fe6c7a2def488633cbb67e28ac00279d6e8de4 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 27 Feb 2024 11:17:39 +0100 Subject: [PATCH 1/2] qemu_init: increase NOFILE soft limit on POSIX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Cornelia Huck RH-MergeRequest: 226: qemu_init: increase NOFILE soft limit on POSIX RH-Jira: RHEL-26049 RH-Acked-by: Gavin Shan RH-Acked-by: Ani Sinha RH-Acked-by: Shaoqin Huang RH-Commit: [1/1] cee5404aef3f6437d45a1c43bdee73a57a528bee (cohuck/qemu-kvm-c9s) Jira: https://issues.redhat.com/browse/RHEL-26049 In many configurations, e.g. multiple vNICs with multiple queues or with many Ceph OSDs, the default soft limit of 1024 is not enough. QEMU is supposed to work fine with file descriptors >= 1024 and does not use select() on POSIX. Bump the soft limit to the allowed hard limit to avoid issues with the aforementioned configurations. Of course the limit could be raised from the outside, but the man page of systemd.exec states about 'LimitNOFILE=': > Don't use. > [...] > Typically applications should increase their soft limit to the hard > limit on their own, if they are OK with working with file > descriptors above 1023, If the soft limit is already the same as the hard limit, avoid the superfluous setrlimit call. This can avoid a warning with a strict seccomp filter blocking setrlimit if NOFILE was already raised before executing QEMU. Buglink: https://bugzilla.proxmox.com/show_bug.cgi?id=4507 Reviewed-by: Daniel P. Berrangé Signed-off-by: Fiona Ebner Signed-off-by: Daniel P. Berrangé (cherry picked from commit 03e471c41d8b1b6eb16c9714f387449f52fe5c1d) Signed-off-by: Cornelia Huck --- include/sysemu/os-posix.h | 1 + include/sysemu/os-win32.h | 5 +++++ os-posix.c | 22 ++++++++++++++++++++++ system/vl.c | 2 ++ 4 files changed, 30 insertions(+) diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h index dff32ae185..b881ac6c6f 100644 --- a/include/sysemu/os-posix.h +++ b/include/sysemu/os-posix.h @@ -51,6 +51,7 @@ bool is_daemonized(void); void os_daemonize(void); bool os_set_runas(const char *user_id); void os_set_chroot(const char *path); +void os_setup_limits(void); void os_setup_post(void); int os_mlock(void); diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h index 1047d260cb..b82a5d3ad9 100644 --- a/include/sysemu/os-win32.h +++ b/include/sysemu/os-win32.h @@ -128,6 +128,11 @@ static inline int os_mlock(void) return -ENOSYS; } +static inline void os_setup_limits(void) +{ + return; +} + #define fsync _commit #if !defined(lseek) diff --git a/os-posix.c b/os-posix.c index 52ef6990ff..a4284e2c07 100644 --- a/os-posix.c +++ b/os-posix.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include #include #include #include @@ -256,6 +257,27 @@ void os_daemonize(void) } } +void os_setup_limits(void) +{ + struct rlimit nofile; + + if (getrlimit(RLIMIT_NOFILE, &nofile) < 0) { + warn_report("unable to query NOFILE limit: %s", strerror(errno)); + return; + } + + if (nofile.rlim_cur == nofile.rlim_max) { + return; + } + + nofile.rlim_cur = nofile.rlim_max; + + if (setrlimit(RLIMIT_NOFILE, &nofile) < 0) { + warn_report("unable to set NOFILE limit: %s", strerror(errno)); + return; + } +} + void os_setup_post(void) { int fd = 0; diff --git a/system/vl.c b/system/vl.c index 93635ffc5b..6443b6e469 100644 --- a/system/vl.c +++ b/system/vl.c @@ -2783,6 +2783,8 @@ void qemu_init(int argc, char **argv) error_init(argv[0]); qemu_init_exec_dir(argv[0]); + os_setup_limits(); + qemu_init_arch_modules(); qemu_init_subsystems(); -- 2.39.3