summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorSimon Rettberg2017-11-08 23:19:59 +0100
committerSimon Rettberg2017-11-08 23:19:59 +0100
commit10ea61568a6428d20f527fafda22389a31bee3d9 (patch)
tree4a4a75c10f2ea301619493dd0bb8b51680a1ced5 /src/server
parent[SERVER] altservers: Short timeout during RTT measurement, round request range (diff)
downloaddnbd3-10ea61568a6428d20f527fafda22389a31bee3d9.tar.gz
dnbd3-10ea61568a6428d20f527fafda22389a31bee3d9.tar.xz
dnbd3-10ea61568a6428d20f527fafda22389a31bee3d9.zip
[SERVER] Check RLIMIT_NOFILE on startup and try to increase if required
Diffstat (limited to 'src/server')
-rw-r--r--src/server/globals.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/server/globals.c b/src/server/globals.c
index 854698a..b1775f0 100644
--- a/src/server/globals.c
+++ b/src/server/globals.c
@@ -5,6 +5,8 @@
#include <stdlib.h>
#include <inttypes.h>
#include <limits.h>
+#include <sys/resource.h>
+#include <errno.h>
char *_configDir = NULL;
volatile bool _shutdown = false;
@@ -107,6 +109,43 @@ void globals_loadConfig()
// Cap to hard limit
if ( _maxClients > SERVER_MAX_CLIENTS ) _maxClients = SERVER_MAX_CLIENTS;
if ( _maxImages > SERVER_MAX_IMAGES ) _maxImages = SERVER_MAX_IMAGES;
+ // Consider rlimits
+ struct rlimit limit;
+ if ( getrlimit( RLIMIT_NOFILE, &limit ) != 0 ) {
+ logadd( LOG_DEBUG1, "getrlimit failed, errno %d", errno );
+ } else {
+ const rlim_t required = (rlim_t)( _maxClients + _maxImages * ( _isProxy ? 2 : 1 ) + 50 );
+ if ( limit.rlim_cur != RLIM_INFINITY && limit.rlim_cur < required ) {
+ rlim_t current = limit.rlim_cur;
+ if ( required <= limit.rlim_max || limit.rlim_max == RLIM_INFINITY ) {
+ limit.rlim_cur = required;
+ } else {
+ limit.rlim_cur = limit.rlim_max;
+ }
+ if ( current != limit.rlim_cur && setrlimit( RLIMIT_NOFILE, &limit ) == 0 ) {
+ current = limit.rlim_cur;
+ logadd( LOG_INFO, "LIMIT_NOFILE (ulimit -n) soft limit increased to %d", (int)current );
+ }
+ if ( current < required ) {
+ logadd( LOG_WARNING, "This process can only have %d open file handles,"
+ " which is not enough for the selected maxClients and maxImages counts."
+ " Consider increasing the limit to at least %d (RLIMIT_NOFILE, ulimit -n)"
+ " to support the current configuration. maxClients and maxImages have"
+ " been lowered for this session.", (int)current, (int)required );
+ do {
+ if ( _maxClients > 500 && _maxImages > 150 ) {
+ _maxImages -= _maxImages / 20 + 1;
+ _maxClients -= _maxClients / 20 + 1;
+ } else if ( _maxImages > 100 ) {
+ _maxImages -= _maxImages / 20 + 1;
+ if ( _maxClients > 200 ) _maxClients -= _maxClients / 25 + 1;
+ } else {
+ break;
+ }
+ } while ( (rlim_t)( _maxClients + _maxImages * ( _isProxy ? 2 : 1 ) + 50 ) > current );
+ }
+ }
+ }
// Dump config as interpreted
char buffer[2000];
globals_dumpConfig( buffer, sizeof(buffer) );