diff --git a/nano/lib/utility.cpp b/nano/lib/utility.cpp index e6dd666b5a..5c26a772f6 100644 --- a/nano/lib/utility.cpp +++ b/nano/lib/utility.cpp @@ -35,11 +35,11 @@ #include #endif -std::size_t nano::get_filedescriptor_limit () +std::size_t nano::get_file_descriptor_limit () { std::size_t fd_limit = (std::numeric_limits::max) (); #ifndef _WIN32 - struct rlimit limit; + rlimit limit{}; if (getrlimit (RLIMIT_NOFILE, &limit) == 0) { fd_limit = static_cast (limit.rlim_cur); @@ -48,6 +48,30 @@ std::size_t nano::get_filedescriptor_limit () return fd_limit; } +void nano::set_file_descriptor_limit (std::size_t limit) +{ +#ifndef _WIN32 + rlimit fd_limit{}; + if (-1 == getrlimit (RLIMIT_NOFILE, &fd_limit)) + { + std::cerr << "Unable to get current limits for the number of open file descriptors: " << std::strerror (errno); + return; + } + + if (fd_limit.rlim_cur >= limit) + { + return; + } + + fd_limit.rlim_cur = std::min (limit, fd_limit.rlim_max); + if (-1 == setrlimit (RLIMIT_NOFILE, &fd_limit)) + { + std::cerr << "Unable to set limits for the number of open file descriptors: " << std::strerror (errno); + return; + } +#endif +} + 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 db8e2c35d3..c4157b2c48 100644 --- a/nano/lib/utility.hpp +++ b/nano/lib/utility.hpp @@ -135,12 +135,12 @@ 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. + * limit cannot be queried, or running on a Windows system, this returns max-value of std::size_t. + * Increasing the limit programmatically can be done only for the soft limit, the hard one requiring + * super user permissions to modify. */ -size_t get_filedescriptor_limit (); +std::size_t get_file_descriptor_limit (); +void set_file_descriptor_limit (std::size_t limit); template class observer_set final diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index 0e9ccb37b2..2c49195389 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include @@ -19,6 +18,8 @@ namespace { volatile sig_atomic_t sig_int_or_term = 0; + +constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384; } static void load_and_set_bandwidth_params (std::shared_ptr const & node, boost::filesystem::path const & data_path, nano::node_flags const & flags) @@ -71,13 +72,8 @@ 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); - logger.always_log (low_fd_text); - } + nano::set_file_descriptor_limit (OPEN_FILE_DESCRIPTORS_LIMIT); + logger.always_log (boost::format ("Open file descriptors limit is %1%") % nano::get_file_descriptor_limit ()); auto node (std::make_shared (io_ctx, data_path, config.node, opencl_work, flags)); if (!node->init_error ())