From 1b2480001f7e48c7a656bd2010b86c9fefc6c672 Mon Sep 17 00:00:00 2001 From: cryptocode Date: Tue, 16 Mar 2021 17:17:22 +0100 Subject: [PATCH] Check open file descriptor limit, warn if low (#3107) * Check open file descriptor limit, warn if low * Add limits header * Add size_t include, std namespace to satisfy msvc * Try not running into msvc max() macro clash * One more attempt to deal with msvc max() macro clash --- nano/lib/utility.cpp | 19 +++++++++++++++++++ nano/lib/utility.hpp | 10 ++++++++++ nano/nano_node/daemon.cpp | 11 +++++++++++ 3 files changed, 40 insertions(+) diff --git a/nano/lib/utility.cpp b/nano/lib/utility.cpp index 8dfba857b..e507cc65b 100644 --- a/nano/lib/utility.cpp +++ b/nano/lib/utility.cpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include #include @@ -29,6 +31,23 @@ #endif #endif +#ifndef _WIN32 +#include +#endif + +std::size_t nano::get_filedescriptor_limit () +{ + std::size_t fd_limit = (std::numeric_limits::max) (); +#ifndef _WIN32 + struct rlimit limit; + if (getrlimit (RLIMIT_NOFILE, &limit) == 0) + { + fd_limit = static_cast (limit.rlim_cur); + } +#endif + return fd_limit; +} + nano::container_info_composite::container_info_composite (std::string const & name) : name (name) { diff --git a/nano/lib/utility.hpp b/nano/lib/utility.hpp index e0ed5943f..d175c0b93 100644 --- a/nano/lib/utility.hpp +++ b/nano/lib/utility.hpp @@ -132,6 +132,16 @@ void dump_crash_stacktrace (); */ std::string generate_stacktrace (); +/** + * Some systems, especially in virtualized environments, may have very low file descriptor limits, + * causing the node to fail. This function attempts to query the limit and returns the value. If the + * limit cannot be queried, or running on a Windows system, this returns max-value of size_t. + * Increasing the limit programatically is highly system-dependent, and the process may lack the + * required permissions; the node thus merely logs low limits as a potential problem and leaves + * the system configuration to the user. + */ +size_t get_filedescriptor_limit (); + template class observer_set final { diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index a0deb4b65..86c5c31ad 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -11,6 +11,8 @@ #include #include +#include + #include #include @@ -60,6 +62,15 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano:: std::cout << initialization_text << std::endl; logger.always_log (initialization_text); + size_t fd_limit = nano::get_filedescriptor_limit (); + constexpr size_t fd_limit_recommended_minimum = 16384; + if (fd_limit < fd_limit_recommended_minimum) + { + auto low_fd_text = boost::str (boost::format ("WARNING: The file descriptor limit on this system may be too low (%1%) and should be increased to at least %2%.") % fd_limit % fd_limit_recommended_minimum); + std::cerr << low_fd_text << std::endl; + logger.always_log (low_fd_text); + } + auto node (std::make_shared (io_ctx, data_path, config.node, opencl_work, flags)); if (!node->init_error ()) {