diff --git a/nano/lib/utility.cpp b/nano/lib/utility.cpp index e6dd666b5..5c26a772f 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 db8e2c35d..c4157b2c4 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 795dc084c..2c4919538 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -13,10 +13,6 @@ #include -#ifndef _WIN32 -#include -#endif - #include namespace @@ -24,29 +20,6 @@ namespace volatile sig_atomic_t sig_int_or_term = 0; constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384; - -void setOpenFileDescriptorsLimits () -{ -#ifndef _WIN32 - rlimit current_limits{}; - - if (-1 == getrlimit (RLIMIT_NOFILE, ¤t_limits)) - { - std::cerr << "Unable to get current limits for the number of open file descriptors: " << std::strerror (errno); - return; - } - - if (current_limits.rlim_cur < OPEN_FILE_DESCRIPTORS_LIMIT) - { - current_limits.rlim_cur = std::min (OPEN_FILE_DESCRIPTORS_LIMIT, current_limits.rlim_max); - if (-1 == setrlimit (RLIMIT_NOFILE, ¤t_limits)) - { - std::cerr << "Unable to set limits for the number of open file descriptors: " << std::strerror (errno); - return; - } - } -#endif -} } static void load_and_set_bandwidth_params (std::shared_ptr const & node, boost::filesystem::path const & data_path, nano::node_flags const & flags) @@ -71,8 +44,6 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano:: sigman.register_signal_handler (SIGSEGV, sigman.get_debug_files_handler (), false); sigman.register_signal_handler (SIGABRT, sigman.get_debug_files_handler (), false); - setOpenFileDescriptorsLimits (); - boost::filesystem::create_directories (data_path); boost::system::error_code error_chmod; nano::set_secure_perm_directory (data_path, error_chmod); @@ -101,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 ())