Hi, with a low soft limit on file descriptors, dovecot 2.2.15 warns on startup:
Warning: fd limit (ulimit -n) is lower than required under max. load (256 < 1000), because of default_client_limit It could try increasing the limit first, and only report the warning if that fails. I'm attaching a patch that does just this. Without the patch, the soft fd limit is kept at whatever it was on dovecot startup: % pfexec plimit $(pgrep dovecot) 18737: /opt/niksula/sbin/dovecot resource current maximum time(seconds) unlimited unlimited file(blocks) unlimited unlimited data(kbytes) unlimited unlimited stack(kbytes) 10240 unlimited coredump(blocks) unlimited unlimited nofiles(descriptors) 256 65536 vmemory(kbytes) unlimited unlimited and with patch applied, it's increased to max_client_limit: % pfexec plimit $(pgrep dovecot) 18775: /opt/niksula/sbin/dovecot resource current maximum time(seconds) unlimited unlimited file(blocks) unlimited unlimited data(kbytes) unlimited unlimited stack(kbytes) 10240 unlimited coredump(blocks) unlimited unlimited nofiles(descriptors) 1000 65536 vmemory(kbytes) unlimited unlimited It should probably be increased to higher than that to account for fds other than client sockets, but I don't have insights into that. -- Lauri Tirkkonen Niksula systems specialist
diff -r e30e9b2b0e37 src/master/master-settings.c --- a/src/master/master-settings.c Wed Jan 21 02:21:35 2015 +0200 +++ b/src/master/master-settings.c Thu Jan 22 13:39:41 2015 +0200 @@ -18,6 +18,7 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> +#include <sys/resource.h> static bool master_settings_verify(void *_set, pool_t pool, const char **error_r); @@ -418,7 +419,7 @@ #ifdef CONFIG_BINARY const struct service_settings *default_service; #else - rlim_t fd_limit; + struct rlimit fd_limit; const char *max_client_limit_source = "default_client_limit"; unsigned int max_client_limit = set->default_client_limit; #endif @@ -591,12 +592,18 @@ client_limit, max_anvil_client_processes); } #ifndef CONFIG_BINARY - if (restrict_get_fd_limit(&fd_limit) == 0 && - fd_limit < (rlim_t)max_client_limit) { - i_warning("fd limit (ulimit -n) is lower than required " - "under max. load (%u < %u), because of %s", - (unsigned int)fd_limit, max_client_limit, - max_client_limit_source); + if (getrlimit(RLIMIT_NOFILE, &fd_limit) == 0) { +#ifdef HAVE_SETRLIMIT + rlim_t old = fd_limit.rlim_cur; + fd_limit.rlim_cur = I_MAX(old, max_client_limit); + if (setrlimit(RLIMIT_NOFILE, &fd_limit) < 0) + fd_limit.rlim_cur = old; +#endif + if (fd_limit.rlim_cur < (rlim_t)max_client_limit) + i_warning("fd limit (ulimit -n) is lower than required " + "under max. load (%u < %u), because of %s", + (unsigned int)fd_limit.rlim_cur, max_client_limit, + max_client_limit_source); } #endif