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
This commit is contained in:
cryptocode 2021-03-16 17:17:22 +01:00 committed by GitHub
commit 1b2480001f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 0 deletions

View file

@ -3,7 +3,9 @@
#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/filesystem.hpp>
#include <cstddef>
#include <iostream>
#include <limits>
#include <sstream>
#include <string_view>
#include <thread>
@ -29,6 +31,23 @@
#endif
#endif
#ifndef _WIN32
#include <sys/resource.h>
#endif
std::size_t nano::get_filedescriptor_limit ()
{
std::size_t fd_limit = (std::numeric_limits<std::size_t>::max) ();
#ifndef _WIN32
struct rlimit limit;
if (getrlimit (RLIMIT_NOFILE, &limit) == 0)
{
fd_limit = static_cast<std::size_t> (limit.rlim_cur);
}
#endif
return fd_limit;
}
nano::container_info_composite::container_info_composite (std::string const & name) :
name (name)
{

View file

@ -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 <typename... T>
class observer_set final
{

View file

@ -11,6 +11,8 @@
#include <nano/rpc/rpc.hpp>
#include <nano/secure/working.hpp>
#include <boost/format.hpp>
#include <csignal>
#include <iostream>
@ -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<nano::node> (io_ctx, data_path, config.node, opencl_work, flags));
if (!node->init_error ())
{