From 9264cc39ce9da6f6cdf675a7b3bb3ef9e8f97cbb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Jun 2018 15:21:47 +0200 Subject: [PATCH] main: split out reading of /proc/sys/fs/nr_open into its own function This doesn't really reduce the code size over all, but it does make main.c shorter and more readable, and that's always a good thing. --- src/basic/fd-util.c | 24 ++++++++++++++++++++++++ src/basic/fd-util.h | 2 ++ src/core/main.c | 19 ++++--------------- src/test/test-fd-util.c | 8 ++++++++ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index e54881ca3c..e1bea94c90 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -930,3 +930,27 @@ int fd_reopen(int fd, int flags) { return new_fd; } + +int read_nr_open(void) { + _cleanup_free_ char *nr_open = NULL; + int r; + + /* Returns the kernel's current fd limit, either by reading it of /proc/sys if that works, or using the + * hard-coded default compiled-in value of current kernels (1M) if not. This call will never fail. */ + + r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open); + if (r < 0) + log_debug_errno(r, "Failed to read /proc/sys/fs/nr_open, ignoring: %m"); + else { + int v; + + r = safe_atoi(nr_open, &v); + if (r < 0) + log_debug_errno(r, "Failed to parse /proc/sys/fs/nr_open value '%s', ignoring: %m", nr_open); + else + return v; + } + + /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */ + return 1024 * 1024; +} diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 2ae4e67ed0..b94944972c 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -108,3 +108,5 @@ static inline int make_null_stdio(void) { }) int fd_reopen(int fd, int flags); + +int read_nr_open(void); diff --git a/src/core/main.c b/src/core/main.c index 8c04d41c0c..4158424dcf 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1136,10 +1136,7 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching } static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { - struct rlimit nl; - int r; - int min_max; - _cleanup_free_ char *nr_open = NULL; + int r, nr; assert(saved_rlimit); @@ -1160,17 +1157,9 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { arg_default_rlimit[RLIMIT_NOFILE] = rl; } - /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */ - r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open); - if (r >= 0) - r = safe_atoi(nr_open, &min_max); - /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */ - if (r < 0) - min_max = 1024 * 1024; - - /* Bump up the resource limit for ourselves substantially */ - nl.rlim_cur = nl.rlim_max = min_max; - r = setrlimit_closest(RLIMIT_NOFILE, &nl); + /* Bump up the resource limit for ourselves substantially, all the way to the maximum the kernel allows */ + nr = read_nr_open(); + r = setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(nr)); if (r < 0) return log_warning_errno(r, "Setting RLIMIT_NOFILE failed, ignoring: %m"); diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index fc3c463385..b1de8aca5c 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -315,7 +315,14 @@ static void test_fd_duplicate_data_fd(void) { assert_se(read(fd2, &j, sizeof(j)) == 0); } +static void test_read_nr_open(void) { + log_info("nr-open: %i", read_nr_open()); +} + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); + test_close_many(); test_close_nointr(); test_same_fd(); @@ -324,6 +331,7 @@ int main(int argc, char *argv[]) { test_fd_move_above_stdio(); test_rearrange_stdio(); test_fd_duplicate_data_fd(); + test_read_nr_open(); return 0; }