Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize FD limits on MacOS and Linux platforms at startup #333

Merged
merged 8 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions kaspad/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ use kaspa_perf_monitor::builder::Builder as PerfMonitorBuilder;
use kaspa_utxoindex::{api::UtxoIndexProxy, UtxoIndex};
use kaspa_wrpc_server::service::{Options as WrpcServerOptions, ServerCounters as WrpcServerCounters, WrpcEncoding, WrpcService};

/// Desired soft FD limit that needs to be configured
/// for the kaspad process.
pub const DESIRED_DAEMON_SOFT_FD_LIMIT: u64 = 16 * 1024;
/// Minimum acceptable soft FD limit for the kaspad
/// process. (Rusty Kaspa will operate with the minimal
/// acceptable limit of `4096`, but a setting below
/// this value may impact the database performance).
pub const MINIMUM_DAEMON_SOFT_FD_LIMIT: u64 = 4 * 1024;

use crate::args::Args;

const DEFAULT_DATA_DIR: &str = "datadir";
Expand Down
21 changes: 20 additions & 1 deletion kaspad/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::sync::Arc;

use kaspa_core::{info, signals::Signals};
use kaspa_utils::fd_budget;
use kaspad_lib::{args::parse_args, daemon::create_core};
use kaspad_lib::{
args::parse_args,
daemon::{create_core, DESIRED_DAEMON_SOFT_FD_LIMIT, MINIMUM_DAEMON_SOFT_FD_LIMIT},
};

#[cfg(feature = "heap")]
#[global_allocator]
Expand All @@ -17,6 +20,22 @@ pub fn main() {
let _profiler = dhat::Profiler::builder().file_name("kaspad-heap.json").build();

let args = parse_args();

match fd_budget::try_set_fd_limit(DESIRED_DAEMON_SOFT_FD_LIMIT) {
Ok(limit) => {
if limit < MINIMUM_DAEMON_SOFT_FD_LIMIT {
println!("Current OS file descriptor limit (soft FD limit) is set to {limit}");
println!("The kaspad node requires a setting of at least {DESIRED_DAEMON_SOFT_FD_LIMIT} to operate properly.");
println!("Please increase the limits using the following command:");
println!("ulimit -n {DESIRED_DAEMON_SOFT_FD_LIMIT}");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth making a recommendation in README.md so that this can be done intentionally before the user uses kaspad?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps. I don't want to touch the readme right now because of another outstanding PR that needs a review. Now that we have discovered that this works I am much less concerned about this as it appears that rusty will now self-configure in most cases and will only fail to do this in some unusual circumstances, which I am currently not sure what they are... I think the upcoming T11 should show if there are any issues with any types of exotic hardware/setups.

}
}
Err(err) => {
println!("Unable to initialize the necessary OS file descriptor limit (soft FD limit) to: {}", err);
println!("The kaspad node requires a setting of at least {DESIRED_DAEMON_SOFT_FD_LIMIT} to operate properly.");
}
}

let fd_total_budget = fd_budget::limit() - args.rpc_max_clients as i32 - args.inbound_limit as i32 - args.outbound_target as i32;
let (core, _) = create_core(args, fd_total_budget);

Expand Down
13 changes: 12 additions & 1 deletion utils/src/fd_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ pub fn acquire_guard(value: i32) -> Result<FDGuard, Error> {
}
}

#[cfg(not(target_arch = "wasm32"))]
pub fn try_set_fd_limit(limit: u64) -> std::io::Result<u64> {
cfg_if::cfg_if! {
if #[cfg(target_os = "windows")] {
Ok(rlimit::setmaxstdio(limit as u32)?.map(|v| v as u64))
} else if #[cfg(unix)] {
rlimit::increase_nofile_limit(limit)
}
}
}

pub fn limit() -> i32 {
cfg_if::cfg_if! {
if #[cfg(test)] {
Expand All @@ -58,7 +69,7 @@ pub fn limit() -> i32 {
else if #[cfg(target_os = "windows")] {
rlimit::getmaxstdio() as i32
}
else if #[cfg(any(target_os = "macos", target_os = "linux"))] {
else if #[cfg(unix)] {
rlimit::getrlimit(rlimit::Resource::NOFILE).unwrap().0 as i32
}
else {
Expand Down