Skip to content

Commit 96db1de

Browse files
committed
raise max file descriptors allowed to infinity
1 parent d4e7bf4 commit 96db1de

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

lading/src/bin/lading.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ enum Error {
6767
MissingTelemetry,
6868
#[error(transparent)]
6969
Registration(#[from] lading_signal::RegisterError),
70+
#[error("Failed to raise RLIMIT_NOFILE to infinity (requires CAP_SYS_RESOURCE): {0}")]
71+
RaiseFileLimit(#[source] std::io::Error),
7072
}
7173

7274
fn default_config_path() -> String {
@@ -729,6 +731,25 @@ fn init_tracing(json_output: bool) {
729731
}
730732
}
731733

734+
/// Raise the open file descriptor limit (`RLIMIT_NOFILE`) to infinity.
735+
///
736+
/// Sets both the soft and hard limits to `RLIM_INFINITY`. Raising the hard
737+
/// limit requires the `CAP_SYS_RESOURCE` capability.
738+
fn raise_open_file_limit() -> io::Result<()> {
739+
let limit = libc::rlimit {
740+
rlim_cur: libc::RLIM_INFINITY,
741+
rlim_max: libc::RLIM_INFINITY,
742+
};
743+
// SAFETY: `limit` is a fully-initialized `rlimit`; `setrlimit` only reads
744+
// from the pointer for the duration of the call.
745+
let ret = unsafe { libc::setrlimit(libc::RLIMIT_NOFILE, &raw const limit) };
746+
if ret == 0 {
747+
Ok(())
748+
} else {
749+
Err(io::Error::last_os_error())
750+
}
751+
}
752+
732753
fn main() -> Result<(), Error> {
733754
// Two-parser fallback logic until CliFlatLegacy is removed
734755
let (json_output, args) = match CliWithSubcommands::try_parse() {
@@ -763,7 +784,12 @@ fn main() -> Result<(), Error> {
763784
limit = memory_limit.to_string()
764785
);
765786

766-
let config = get_config(&args, None);
787+
let config = get_config(&args, None)?;
788+
789+
if config.maximize_open_file_limit {
790+
raise_open_file_limit().map_err(Error::RaiseFileLimit)?;
791+
info!("Raised RLIMIT_NOFILE to infinity.");
792+
}
767793

768794
let experiment_duration = if args.experiment_duration_infinite {
769795
Duration::MAX
@@ -785,7 +811,7 @@ fn main() -> Result<(), Error> {
785811
experiment_duration,
786812
warmup_duration,
787813
disable_inspector,
788-
config?,
814+
config,
789815
));
790816
// The splunk_hec generator spawns long running tasks that are not plugged
791817
// into the shutdown mechanism we have here. This is a bug and needs to be

lading/src/config.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ pub struct Config {
118118
pub target_metrics: Option<Vec<target_metrics::Config>>,
119119
/// The target inspector sub-program
120120
pub inspector: Option<inspector::Config>,
121+
/// When true, raise the open file descriptor limit (`RLIMIT_NOFILE`) to
122+
/// infinity on startup. Raising the hard limit requires `CAP_SYS_RESOURCE`.
123+
/// Default is false.
124+
#[serde(default)]
125+
pub maximize_open_file_limit: bool,
121126
}
122127

123128
/// Partial configuration used for merging multiple config files
@@ -147,6 +152,8 @@ pub struct PartialConfig {
147152
pub target_metrics: Option<Vec<target_metrics::Config>>,
148153
/// The target inspector sub-program.
149154
pub inspector: Option<inspector::Config>,
155+
/// When true, raise `RLIMIT_NOFILE` to infinity on startup.
156+
pub maximize_open_file_limit: Option<bool>,
150157
}
151158

152159
/// Default value for [`Telemetry::Log`] expiration
@@ -280,6 +287,7 @@ impl Config {
280287
blackhole: partial.blackhole,
281288
target_metrics: partial.target_metrics,
282289
inspector: partial.inspector,
290+
maximize_open_file_limit: partial.maximize_open_file_limit.unwrap_or(false),
283291
})
284292
}
285293

@@ -334,6 +342,11 @@ impl Config {
334342
base.observer = overlay.observer;
335343
}
336344

345+
// Last writer wins for the file-descriptor limit toggle.
346+
if overlay.maximize_open_file_limit.is_some() {
347+
base.maximize_open_file_limit = overlay.maximize_open_file_limit;
348+
}
349+
337350
// Merge generators
338351
base.generator.extend(overlay.generator);
339352
check_duplicate_generator_ids(&base.generator)?;
@@ -546,6 +559,7 @@ mod tests {
546559
blackhole: vec![],
547560
target_metrics: None,
548561
inspector: None,
562+
maximize_open_file_limit: None,
549563
}
550564
}
551565

@@ -559,6 +573,7 @@ mod tests {
559573
blackhole: blackholes,
560574
target_metrics: None,
561575
inspector: None,
576+
maximize_open_file_limit: None,
562577
}
563578
}
564579

@@ -572,6 +587,7 @@ mod tests {
572587
blackhole: vec![],
573588
target_metrics: Some(metrics),
574589
inspector: None,
590+
maximize_open_file_limit: None,
575591
}
576592
}
577593

@@ -660,6 +676,7 @@ blackhole:
660676
inspector: Option::default(),
661677
target_metrics: Option::default(),
662678
sample_period_milliseconds: 1_000,
679+
maximize_open_file_limit: false,
663680
},
664681
);
665682
Ok(())

0 commit comments

Comments
 (0)