diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md index 2fcba4355..e15bbc30f 100644 --- a/doc/RELEASE-NOTES.md +++ b/doc/RELEASE-NOTES.md @@ -11,6 +11,9 @@ in progress and may not always be a stable version. * TODO ### Fixes: +* If your shell only allowed very few file descriptors (eg: `ulimit -n` + returned `150`), then UnrealIRCd would fail to boot. This, because due to + reserved file descriptors you would have 0 left, or even a negative number. * +I ~operclass was not working properly. ### Developers and protocol: diff --git a/include/config.h b/include/config.h index 2ec569ad0..d7339704a 100644 --- a/include/config.h +++ b/include/config.h @@ -173,21 +173,6 @@ #endif #endif -/* Number of file descriptors reserved for non-incoming-clients. - * One of which may be used by auth, the rest are really reserved. - * They can be used for outgoing server links, listeners, logging, - * DNS lookups, HTTPS callbacks, etc. - */ -#if MAXCONNECTIONS >= 10000 - #define CLIENTS_RESERVE 250 -#elif MAXCONNECTIONS >= 2048 - #define CLIENTS_RESERVE 32 -#elif MAXCONNECTIONS >= 1024 - #define CLIENTS_RESERVE 16 -#else - #define CLIENTS_RESERVE 8 -#endif - /* * this defines the length of the nickname history. each time a user changes * nickname or signs off, their old nickname is added to the top of the list. diff --git a/include/h.h b/include/h.h index c1f45dbdf..bb6e2f542 100644 --- a/include/h.h +++ b/include/h.h @@ -1135,6 +1135,7 @@ extern void concat_params(char *buf, int len, int parc, const char *parv[]); extern void charsys_check_for_changes(void); extern void dns_check_for_changes(void); extern MODVAR int maxclients; +extern MODVAR int reserved_fds; extern int fast_badword_match(ConfigItem_badword *badword, const char *line); extern int fast_badword_replace(ConfigItem_badword *badword, const char *line, char *buf, int max); extern const char *stripbadwords(const char *str, ConfigItem_badword *start_bw, int *blocked); diff --git a/src/ircd.c b/src/ircd.c index 94e07f811..a0ee243d8 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -801,7 +801,7 @@ int InitUnrealIRCd(int argc, char *argv[]) #ifndef _WIN32 fprintf(stderr, "\n"); fprintf(stderr, "This server can handle %d concurrent sockets (%d clients + %d reserve)\n\n", - maxclients+CLIENTS_RESERVE, maxclients, CLIENTS_RESERVE); + maxclients+reserved_fds, maxclients, reserved_fds); #endif init_CommandHash(); initwhowas(); diff --git a/src/modules/stats.c b/src/modules/stats.c index 1e2d785bb..2f9fa6b77 100644 --- a/src/modules/stats.c +++ b/src/modules/stats.c @@ -900,7 +900,7 @@ int stats_set(Client *client, const char *para) RunHook(HOOKTYPE_STATS, client, "S"); #ifndef _WIN32 sendtxtnumeric(client, "This server can handle %d concurrent sockets (%d clients + %d reserve)", - maxclients+CLIENTS_RESERVE, maxclients, CLIENTS_RESERVE); + maxclients+reserved_fds, maxclients, reserved_fds); #endif return 1; } diff --git a/src/socket.c b/src/socket.c index deca8c29e..8d28bc9f3 100644 --- a/src/socket.c +++ b/src/socket.c @@ -135,7 +135,7 @@ static int listener_accept_wrapper(ConfigItem_listen *listener) if (listener->options & LISTENER_CONTROL) { /* ... but not unlimited ;) */ - if ((++OpenFiles >= maxclients+(CLIENTS_RESERVE/2)) || (cli_fd >= maxclients+(CLIENTS_RESERVE/2))) + if ((++OpenFiles >= maxclients+(reserved_fds/2)) || (cli_fd >= maxclients+(reserved_fds/2))) { ircstats.is_ref++; if (last_allinuse < TStime() - 15) @@ -430,7 +430,15 @@ void close_all_listeners(void) close_listener(aconf); } -int maxclients = 1024 - CLIENTS_RESERVE; +/* First, set these up for maxclients 1024 with a reserve of 16, + * this is adjusted at boot time, though, it is just for an + * initial value! + */ + +/** Number of file descriptors reserved */ +int reserved_fds = 16; +/** Maximum number of regular clients */ +int maxclients = 1024 - 16; /** Check the maximum number of sockets (users) that we can handle - called on startup. */ @@ -473,7 +481,7 @@ void check_user_limit(void) m); exit(-1); } - maxclients = m - CLIENTS_RESERVE; + maxclients = m; } #endif // RLIMIT_FD_MAX @@ -489,8 +497,20 @@ void check_user_limit(void) #endif #endif #ifdef _WIN32 - maxclients = MAXCONNECTIONS - CLIENTS_RESERVE; + maxclients = MAXCONNECTIONS; #endif + + /* Now adjust the 'reserve', this was previously in config.h */ + if (maxclients >= 10000) + reserved_fds = 250; + else if (maxclients >= 2048) + reserved_fds = 32; + else if (maxclients >= 1024) + reserved_fds = 16; + else + reserved_fds = 8; + + maxclients -= reserved_fds; } /** Initialize some systems - called on startup */