From e733fdf62e778fff7c3d4c68cfde7060461f19b4 Mon Sep 17 00:00:00 2001 From: ZmnSCPxj jxPCSnmZ Date: Tue, 19 Oct 2021 12:18:27 +0800 Subject: [PATCH] lightningd/lightningd.c: Only impose fd limit if absolutely needed. Fixes: #4868 ChangeLog-Fixed: We now no longer self-limit the number of file descriptors (which limits the number of channels) in sufficiently modern systems, or where we can access `/proc` or `/dev/fd`. We still self-limit on old systems where we cannot find the list of open files on `/proc` or `/dev/fd`, so if you need > ~4000 channels, upgrade or mount `/proc`. --- lightningd/lightningd.c | 57 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 67f35133c..1af81a790 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -851,15 +851,48 @@ int main(int argc, char *argv[]) const char *stop_response; struct htlc_in_map *unconnected_htlcs_in; struct ext_key *bip32_base; - struct rlimit nofile = {1024, 1024}; int sigchld_rfd; int exit_code = 0; char **orig_argv; bool try_reexec; - /*~ Make sure that we limit ourselves to something reasonable. Modesty - * is a virtue. */ - setrlimit(RLIMIT_NOFILE, &nofile); + /*~ We fork out new processes very very often; every channel gets its + * own process, for example, and we have `hsmd` and `gossipd` and + * the plugins as well. + * Now, we also keep around several file descriptors (`fd`s), including + * file descriptors to communicate with `hsmd` which is a privileged + * process with access to private keys and is therefore very sensitive. + * Thus, we need to close all file descriptors other than what the + * forked-out new process should have ASAP. + * + * We do this by using the `ccan/closefrom` module, which implements + * an emulation for the `closefrom` syscall on BSD and Solaris. + * This emulation tries to use the fastest facility available on the + * system (`close_range` syscall on Linux 5.9+, snooping through + * `/proc/$PID/fd` on many OSs (but requires procps to be mounted), + * the actual `closefrom` call if available, etc.). + * As a fallback if none of those are available on the system, however, + * it just iterates over the theoretical range of possible file + * descriptors. + * + * On some systems, that theoretical range can be very high, up to + * `INT_MAX` in the worst case. + * If the `closefrom` emulation has to fall back to this loop, it + * can be very slow; fortunately, the emulation will also inform + * us of that via the `closefrom_may_be_slow` function, and also has + * `closefrom_limit` to limit the number of allowed file descriptors + * *IF AND ONLY IF* `closefrom_may_be_slow()` is true. + * + * On systems with a fast `closefrom` then `closefrom_limit` does + * nothing. + * + * Previously we always imposed a limit of 1024 file descriptors + * (because we used to always iterate up to limit instead of using + * some OS facility, because those were non-portable and needed + * code for each OS), until @whitslack went and made >1000 channels + * and hit the 1024 limit. + */ + closefrom_limit(4096); /*~ What happens in strange locales should stay there. */ setup_locale(); @@ -1083,6 +1116,22 @@ int main(int argc, char *argv[]) json_escape(tmpctx, (const char *)ld->alias)->s, tal_hex(tmpctx, ld->rgb), version()); + /*~ If `closefrom_may_be_slow`, we limit ourselves to 4096 file + * descriptors; tell the user about it as that limits the number + * of channels they can have. + * We do not really expect most users to ever reach that many, + * but: https://github.com/ElementsProject/lightning/issues/4868 + */ + if (closefrom_may_be_slow()) + log_info(ld->log, + "We have self-limited number of open file " + "descriptors to 4096, but that will result in a " + "'Too many open files' error if you ever reach " + ">4000 channels. Please upgrade your OS kernel " + "(Linux 5.9+, FreeBSD 8.0+), or mount proc or " + "/dev/fd (if running in chroot) if you are " + "approaching that many channels."); + /*~ This is where we ask connectd to reconnect to any peers who have * live channels with us, and makes sure we're watching the funding * tx. */