Skip to content

Commit e733fdf

Browse files
ZmnSCPxjcdecker
authored andcommitted
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`.
1 parent 5356267 commit e733fdf

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

lightningd/lightningd.c

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -851,15 +851,48 @@ int main(int argc, char *argv[])
851851
const char *stop_response;
852852
struct htlc_in_map *unconnected_htlcs_in;
853853
struct ext_key *bip32_base;
854-
struct rlimit nofile = {1024, 1024};
855854
int sigchld_rfd;
856855
int exit_code = 0;
857856
char **orig_argv;
858857
bool try_reexec;
859858

860-
/*~ Make sure that we limit ourselves to something reasonable. Modesty
861-
* is a virtue. */
862-
setrlimit(RLIMIT_NOFILE, &nofile);
859+
/*~ We fork out new processes very very often; every channel gets its
860+
* own process, for example, and we have `hsmd` and `gossipd` and
861+
* the plugins as well.
862+
* Now, we also keep around several file descriptors (`fd`s), including
863+
* file descriptors to communicate with `hsmd` which is a privileged
864+
* process with access to private keys and is therefore very sensitive.
865+
* Thus, we need to close all file descriptors other than what the
866+
* forked-out new process should have ASAP.
867+
*
868+
* We do this by using the `ccan/closefrom` module, which implements
869+
* an emulation for the `closefrom` syscall on BSD and Solaris.
870+
* This emulation tries to use the fastest facility available on the
871+
* system (`close_range` syscall on Linux 5.9+, snooping through
872+
* `/proc/$PID/fd` on many OSs (but requires procps to be mounted),
873+
* the actual `closefrom` call if available, etc.).
874+
* As a fallback if none of those are available on the system, however,
875+
* it just iterates over the theoretical range of possible file
876+
* descriptors.
877+
*
878+
* On some systems, that theoretical range can be very high, up to
879+
* `INT_MAX` in the worst case.
880+
* If the `closefrom` emulation has to fall back to this loop, it
881+
* can be very slow; fortunately, the emulation will also inform
882+
* us of that via the `closefrom_may_be_slow` function, and also has
883+
* `closefrom_limit` to limit the number of allowed file descriptors
884+
* *IF AND ONLY IF* `closefrom_may_be_slow()` is true.
885+
*
886+
* On systems with a fast `closefrom` then `closefrom_limit` does
887+
* nothing.
888+
*
889+
* Previously we always imposed a limit of 1024 file descriptors
890+
* (because we used to always iterate up to limit instead of using
891+
* some OS facility, because those were non-portable and needed
892+
* code for each OS), until @whitslack went and made >1000 channels
893+
* and hit the 1024 limit.
894+
*/
895+
closefrom_limit(4096);
863896

864897
/*~ What happens in strange locales should stay there. */
865898
setup_locale();
@@ -1083,6 +1116,22 @@ int main(int argc, char *argv[])
10831116
json_escape(tmpctx, (const char *)ld->alias)->s,
10841117
tal_hex(tmpctx, ld->rgb), version());
10851118

1119+
/*~ If `closefrom_may_be_slow`, we limit ourselves to 4096 file
1120+
* descriptors; tell the user about it as that limits the number
1121+
* of channels they can have.
1122+
* We do not really expect most users to ever reach that many,
1123+
* but: https://github.com/ElementsProject/lightning/issues/4868
1124+
*/
1125+
if (closefrom_may_be_slow())
1126+
log_info(ld->log,
1127+
"We have self-limited number of open file "
1128+
"descriptors to 4096, but that will result in a "
1129+
"'Too many open files' error if you ever reach "
1130+
">4000 channels. Please upgrade your OS kernel "
1131+
"(Linux 5.9+, FreeBSD 8.0+), or mount proc or "
1132+
"/dev/fd (if running in chroot) if you are "
1133+
"approaching that many channels.");
1134+
10861135
/*~ This is where we ask connectd to reconnect to any peers who have
10871136
* live channels with us, and makes sure we're watching the funding
10881137
* tx. */

0 commit comments

Comments
 (0)