--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Mon, 18 Dec 2023 11:13:40 +0100
+Subject: [PATCH] qemu_init: increase NOFILE soft limit on POSIX
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+---
+ include/sysemu/os-posix.h | 1 +
+ include/sysemu/os-win32.h | 5 +++++
+ os-posix.c | 22 ++++++++++++++++++++++
+ softmmu/vl.c | 2 ++
+ 4 files changed, 30 insertions(+)
+
+diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
+index 1030d39904..edc415aff5 100644
+--- a/include/sysemu/os-posix.h
++++ b/include/sysemu/os-posix.h
+@@ -48,6 +48,7 @@ void os_setup_early_signal_handling(void);
+ void os_set_proc_name(const char *s);
+ void os_setup_signal_handling(void);
+ void os_daemonize(void);
++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 91aa0d7ec0..f6e23fe01e 100644
+--- a/include/sysemu/os-win32.h
++++ b/include/sysemu/os-win32.h
+@@ -129,6 +129,11 @@ static inline int os_mlock(void)
+ return -ENOSYS;
+ }
+
++void os_setup_limits(void)
++{
++ return;
++}
++
+ #define fsync _commit
+
+ #if !defined(lseek)
+diff --git a/os-posix.c b/os-posix.c
+index cfcb96533c..0cc1d991b1 100644
+--- a/os-posix.c
++++ b/os-posix.c
+@@ -24,6 +24,7 @@
+ */
+
+ #include "qemu/osdep.h"
++#include <sys/resource.h>
+ #include <sys/wait.h>
+ #include <pwd.h>
+ #include <grp.h>
+@@ -286,6 +287,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/softmmu/vl.c b/softmmu/vl.c
+index c9e9ede237..ba6ad8a8df 100644
+--- a/softmmu/vl.c
++++ b/softmmu/vl.c
+@@ -2713,6 +2713,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();
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 3f2681aded..1a3b9cc4b8 100644
+index ddeace306e..3ee90b3b94 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2683,6 +2683,7 @@ void qemu_init(int argc, char **argv)
qemu_add_opts(&qemu_drive_opts);
qemu_add_drive_opts(&qemu_legacy_drive_opts);
-@@ -3306,6 +3307,13 @@ void qemu_init(int argc, char **argv)
+@@ -3308,6 +3309,13 @@ void qemu_init(int argc, char **argv)
machine_parse_property_opt(qemu_find_opts("smp-opts"),
"smp", optarg);
break;