Skip to content

Commit

Permalink
lightningd/lightningd.c: Only impose fd limit if absolutely needed.
Browse files Browse the repository at this point in the history
Fixes: #4868
  • Loading branch information
ZmnSCPxj committed Oct 19, 2021
1 parent cd6c66c commit 99b0ce6
Showing 1 changed file with 49 additions and 4 deletions.
53 changes: 49 additions & 4 deletions lightningd/lightningd.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,15 +850,44 @@ 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 used below.
* In that case, we limit the theoretical range to just 1024, which
* can support about ~1000 channels, which should be good enough
* for anybody other than @whitslack, who actually managed to reach
* this limit.
*/
if (closefrom_may_be_slow()) {
struct rlimit nofile = {1024, 1024};
setrlimit(RLIMIT_NOFILE, &nofile);
}

/*~ What happens in strange locales should stay there. */
setup_locale();
Expand Down Expand Up @@ -1082,6 +1111,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 1024 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 1024, but that will result in a "
"'Too many open files' error if you ever reach "
">1000 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. */
Expand Down

0 comments on commit 99b0ce6

Please sign in to comment.