| 639 | } |
| 640 | |
| 641 | int64_t GetFileCacheCapacity(Env* env) { |
| 642 | // Maximize this process' open file limit first, if possible. |
| 643 | static std::once_flag once; |
| 644 | std::call_once(once, [&]() { |
| 645 | env->IncreaseResourceLimit(Env::ResourceLimitType::OPEN_FILES_PER_PROCESS); |
| 646 | }); |
| 647 | |
| 648 | uint64_t rlimit = |
| 649 | env->GetResourceLimit(Env::ResourceLimitType::OPEN_FILES_PER_PROCESS); |
| 650 | // See server_max_open_files. |
| 651 | if (FLAGS_server_max_open_files == 0) { |
| 652 | // Use file-max as a possible upper bound. |
| 653 | faststring buf; |
| 654 | uint64_t buf_val; |
| 655 | if (ReadFileToString(env, "/proc/sys/fs/file-max", &buf).ok() && |
| 656 | safe_strtou64(buf.ToString(), &buf_val)) { |
| 657 | rlimit = std::min(rlimit, buf_val); |
| 658 | } |
| 659 | |
| 660 | // Callers of this function expect a signed 64-bit integer, and rlimit |
| 661 | // is an uint64_t type, so we need to avoid overflow. |
| 662 | // The percentage we currently use is 40% by default, and although in fact |
| 663 | // 40% of any value of the `uint64_t` type must be less than `kint64max`, |
| 664 | // but the percentage may be adjusted in the future, such as to 60%, so to |
| 665 | // prevent accidental overflow, we cap rlimit here. |
| 666 | return std::min((rlimit / 5) * 2, static_cast<uint64_t>(kint64max)); |
| 667 | } |
| 668 | LOG_IF(FATAL, FLAGS_server_max_open_files > rlimit) << |
| 669 | Substitute( |
| 670 | "Configured open file limit (server_max_open_files) $0 " |
| 671 | "exceeds process open file limit (ulimit) $1", |
| 672 | FLAGS_server_max_open_files, rlimit); |
| 673 | return FLAGS_server_max_open_files; |
| 674 | } |
| 675 | |
| 676 | #if defined(__linux__) |
| 677 | // See https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt |
no test coverage detected