]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Try to set file descriptor limit to its maximum and show info on startup
authorAlexander Barton <alex@barton.de>
Thu, 28 Mar 2024 09:16:44 +0000 (10:16 +0100)
committerAlexander Barton <alex@barton.de>
Sun, 31 Mar 2024 09:19:48 +0000 (11:19 +0200)
The number of possible parallel connections is limited by the process
file descriptor limit (among other things). Therefore try to upgrade the
current "soft" limit to its "hard" maximum (but limit it to 100000), and
show an information or even warning, wenn still less than the configured
"MaxConnections" setting.

Please note that ngIRCd and its linked libraries (like PAM) need file
descriptors not only for incoming and outgoing IRC connections, but for
reading files and inter-process communication, too! Therefore the actual
connection limit is _less_ than the file descriptor limit!

This introduces the new MAX_FD_LIMIT (100000) #define.

configure.ng
contrib/ngircd.logcheck
src/ngircd/conf.c
src/ngircd/defines.h

index f6c70e5ded5ec595791debee445bee28a847bec9..ec7b6c356032bf321059fc65d198fb79d0b0675c 100644 (file)
@@ -192,6 +192,7 @@ AC_CHECK_HEADERS_ONCE([ \
        stdbool.h \
        stddef.h \
        stdint.h \
+       sys/resource.h \
        varargs.h \
 ])
 
@@ -274,6 +275,7 @@ AC_CHECK_FUNCS_ONCE([
        getnameinfo \
        inet_aton \
        setgroups \
+       setrlimit \
        sigaction \
        sigprocmask \
        snprintf \
index 1224551fde05ea9dd5bd70d3b39e52cd07269644..905162d651b2178ea5c7d6d3cc93e519e30d6ee7 100644 (file)
@@ -12,6 +12,7 @@
 ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Deleted ".*" \(".*"\) from G-Line list \(expired\)\.$
 ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Enabled link compression \(zlib\) on connection [0-9]+\.$
 ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Establishing connection for ".*" to ".*:[0-9]+" \(.*\), socket [0-9]+ \.\.\.$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: File descriptor limit is [0-9]+; "MaxConnections" is (not set|set to [0-9]+)\.$
 ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Got (valid server|unchecked peer) certificate: .*\.$
 ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Got signal "(Hangup|Terminated)" \.\.\.$
 ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Got valid OPER for ".*" from ".*", user is an IRC operator now\.$
index 441b8f6786f6780451e3fec9f62052792d533eaf..e4cd8963f3072e4bbcee1c6e062fe660c1fe49e9 100644 (file)
 #include <dirent.h>
 #include <netdb.h>
 
+#ifdef HAVE_SYS_RESOURCE_H
+#      include <sys/resource.h>
+#endif
+
 #include "ngircd.h"
 #include "conn.h"
 #include "channel.h"
@@ -2108,6 +2112,10 @@ Validate_Config(bool Configtest, bool Rehash)
        struct hostent *h;
        bool config_valid = true;
        char *ptr;
+#ifdef HAVE_SETRLIMIT
+       struct rlimit rlim;
+       long fd_lim_old;
+#endif
 
        /* Emit a warning when the config file is not a full path name */
        if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
@@ -2197,6 +2205,48 @@ Validate_Config(bool Configtest, bool Rehash)
                             "Maximum penalty increase ('MaxPenaltyTime') is set to %ld, this is not recommended!",
                             Conf_MaxPenaltyTime);
 
+#ifdef HAVE_SETRLIMIT
+       if(getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
+               LogDebug("Current file descriptor limit is %ld, maximum %ld. \"MaxConnections\" is %ld.",
+                        (long)rlim.rlim_cur, (long)rlim.rlim_max,
+                        Conf_MaxConnections);
+               fd_lim_old = rlim.rlim_cur;
+               /* Don't request "infinite" file descriptors, use a limit! */
+               if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < MAX_FD_LIMIT)
+                       rlim.rlim_cur = rlim.rlim_max;
+               else
+                       rlim.rlim_cur = MAX_FD_LIMIT;
+               if ((long)rlim.rlim_cur != fd_lim_old) {
+                       /* Try to adjust the current file descriptor limit: */
+                       LogDebug("Trying to upgrade \"soft\" file descriptor limit: %ld -> %ld ...",
+                                fd_lim_old, (long)rlim.rlim_cur);
+                       if(setrlimit(RLIMIT_NOFILE, &rlim) != 0)
+                               Config_Error(LOG_ERR, "Failed to adjust file descriptor limit from %ld to %ld: %s",
+                                            fd_lim_old, (long)rlim.rlim_cur,
+                                            strerror(errno));
+               }
+               /* Check the (updated?) file descriptor limit: */
+               getrlimit(RLIMIT_NOFILE, &rlim);
+               if (rlim.rlim_cur != RLIM_INFINITY
+                   && (long)rlim.rlim_cur <= (long)Conf_MaxConnections) {
+                       Config_Error(LOG_WARNING,
+                                    "Current file descriptor limit (%ld) is not higher than configured \"MaxConnections\" (%ld)!",
+                                    (long)rlim.rlim_cur, Conf_MaxConnections);
+               } else if (!Configtest) {
+                       if (Conf_MaxConnections > 0)
+                               Log(LOG_INFO,
+                                   "File descriptor limit is %ld; \"MaxConnections\" is set to %ld.",
+                                   (long)rlim.rlim_cur, Conf_MaxConnections);
+                       else
+                               Log(LOG_INFO,
+                                   "File descriptor limit is %ld; \"MaxConnections\" is not set.",
+                                   (long)rlim.rlim_cur);
+               }
+       } else
+               Config_Error(LOG_ERR, "Failed to get file descriptor limit: %s",
+                            strerror(errno));
+#endif
+
        servers = servers_once = 0;
        for (i = 0; i < MAX_SERVERS; i++) {
                if (Conf_Server[i].name[0]) {
index 0b44a5b4f03e14d9cc2df5cb3ed334fe6bf4a782..e3df44b9fc36de1fe6b3dffd7cd077ad98c4c896 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -64,6 +64,9 @@
 /** Size of buffer for PAM service name. */
 #define MAX_PAM_SERVICE_NAME_LEN 64
 
+/** Maximum number of file descriptors to request. */
+#define MAX_FD_LIMIT 100000
+
 
 /* Hard-coded (default) options */