diff --git a/include/lo2s/util.hpp b/include/lo2s/util.hpp index 47f8db19..3cc0f294 100644 --- a/include/lo2s/util.hpp +++ b/include/lo2s/util.hpp @@ -40,6 +40,7 @@ extern "C" { +#include #include #include #include @@ -114,6 +115,9 @@ void try_pin_to_scope(ExecutionScope scope); int get_cgroup_mountpoint_fd(std::string cgroup); +void bump_rlimit_fd(); +struct rlimit save_rlimit_fd(); + Thread gettid(); std::set parse_list(std::string list); diff --git a/src/main.cpp b/src/main.cpp index d8e2b5d0..b48ff637 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,11 +24,20 @@ #include #include #include +#include #include int main(int argc, const char** argv) { + // The resource limit for file descriptors (which lo2s uses a lot of, especially in + // system-monitoring mode) is artifically low to cope with the ancient select() systemcall. We + // do not use select(), so we can safely bump the limit, but whatever command we are running + // under lo2s might (and resource limits are preserved accross fork()) so preserve it here so + // that we can restore it later + lo2s::save_rlimit_fd(); + lo2s::bump_rlimit_fd(); + try { lo2s::parse_program_options(argc, argv); diff --git a/src/monitor/process_monitor_main.cpp b/src/monitor/process_monitor_main.cpp index c7b9c855..12238809 100644 --- a/src/monitor/process_monitor_main.cpp +++ b/src/monitor/process_monitor_main.cpp @@ -55,6 +55,9 @@ namespace monitor [[noreturn]] static void run_command(const std::vector& command_and_args) { + struct rlimit saved_rlimit = save_rlimit_fd(); + setrlimit(RLIMIT_OFILE, &saved_rlimit); + /* kill yourself if the parent dies */ prctl(PR_SET_PDEATHSIG, SIGHUP); @@ -109,6 +112,7 @@ void process_monitor_main(AbstractProcessMonitor& monitor) throw_errno(); } } + if (process == Process::invalid()) { Log::error() << "Fork failed."; diff --git a/src/util.cpp b/src/util.cpp index cb100e66..da22a1d9 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -366,4 +366,24 @@ std::string get_nec_thread_comm(Thread thread) // If no '--' is found, fall back to the complete commandline as a name return std::accumulate(args.begin(), args.end(), std::string("")); } + +struct rlimit save_rlimit_fd() +{ + static struct rlimit current; + + if (current.rlim_cur == 0) + { + getrlimit(RLIMIT_NOFILE, ¤t); + } + return current; +} + +void bump_rlimit_fd() +{ + struct rlimit highest; + getrlimit(RLIMIT_NOFILE, &highest); + + highest.rlim_cur = highest.rlim_max; + setrlimit(RLIMIT_NOFILE, &highest); +} } // namespace lo2s