Skip to content

Commit 6feb992

Browse files
quark-zjufacebook-github-bot
authored andcommitted
Optimize close_random_fds
Summary: A high `fs.nr_open` (ex. 1073741816) can cause watchman to spend 1+ minute during startup closing fds. Let's try to use `close_range` instead. If `close_range` is not available, limit the `max_fd` to a "reasonable" configurable number (2500000) so watchman won't take too long to start. Reviewed By: muirdm Differential Revision: D74923577 fbshipit-source-id: 903e7e389572a2ea5ae93b199dea83b75d6fb9d7
1 parent ecb6fcf commit 6feb992

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ foreach(wat_func
209209
backtrace
210210
backtrace_symbols
211211
backtrace_symbols_fd
212+
close_range
212213
fdopendir
213214
getattrlistbulk
214215
inotify_init

watchman/main.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ std::optional<std::string> detect_starting_command(pid_t ppid) {
231231
// child process.
232232
static void close_random_fds() {
233233
#ifndef _WIN32
234+
#ifdef HAVE_CLOSE_RANGE
235+
close_range(STDERR_FILENO + 1, INT_MAX, 0);
236+
#else
234237
struct rlimit limit;
235238
long open_max = 0;
236239
int max_fd;
@@ -260,11 +263,17 @@ static void close_random_fds() {
260263
if (limit.rlim_cur > (rlim_t)open_max) {
261264
open_max = limit.rlim_cur;
262265
}
263-
266+
// Closing too many fds can be too slow. Limit the `open_max` to avoid slow
267+
// startup.
268+
auto reasonable_fd_max = Configuration().getInt("reasonable_fd_max", 2500000);
269+
if (open_max > reasonable_fd_max) {
270+
open_max = reasonable_fd_max;
271+
}
264272
for (max_fd = open_max; max_fd > STDERR_FILENO; --max_fd) {
265273
folly::fileops::close(max_fd);
266274
}
267-
#endif
275+
#endif // ndef HAVE_CLOSE_RANGE
276+
#endif // ndef _WIN32
268277
}
269278

270279
[[noreturn]] static void run_service_in_foreground() {

0 commit comments

Comments
 (0)