Increase nofile rlimit, restore for spawned processes

This commit is contained in:
Ottatop 2024-06-04 19:48:46 -05:00
parent 8eff64e1bc
commit 5871a2758e
4 changed files with 63 additions and 16 deletions

View file

@ -60,6 +60,7 @@ use crate::{
render::util::snapshot::capture_snapshots_on_output,
state::{State, WithState},
tag::{Tag, TagId},
util::restore_nofile_rlimit,
};
type ResponseStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send>>;
@ -587,8 +588,9 @@ impl process_service_server::ProcessService for ProcessService {
}
}
let Ok(mut child) = tokio::process::Command::new(OsString::from(arg0.clone()))
.stdin(match has_callback {
let mut cmd = tokio::process::Command::new(OsString::from(arg0.clone()));
cmd.stdin(match has_callback {
true => Stdio::piped(),
false => Stdio::null(),
})
@ -600,9 +602,16 @@ impl process_service_server::ProcessService for ProcessService {
true => Stdio::piped(),
false => Stdio::null(),
})
.args(command)
.spawn()
else {
.args(command);
unsafe {
cmd.pre_exec(|| {
restore_nofile_rlimit();
Ok(())
});
}
let Ok(mut child) = cmd.spawn() else {
warn!("Tried to run {arg0}, but it doesn't exist",);
return;
};

View file

@ -13,4 +13,5 @@ pub mod protocol;
pub mod render;
pub mod state;
pub mod tag;
pub mod util;
pub mod window;

View file

@ -18,6 +18,7 @@ use pinnacle::{
cli::{self, Cli},
config::{get_config_dir, parse_metaconfig, Metaconfig},
state::State,
util::increase_nofile_rlimit,
};
use smithay::reexports::{calloop::EventLoop, rustix::process::geteuid};
use tracing::{error, info, warn};
@ -63,6 +64,8 @@ async fn main() -> anyhow::Result<()> {
info!("Starting Pinnacle (commit {})", env!("VERGEN_GIT_SHA"));
increase_nofile_rlimit();
set_log_panic_hook();
let Some(cli) = Cli::parse_and_prompt() else {

34
src/util.rs Normal file
View file

@ -0,0 +1,34 @@
use std::sync::atomic::{AtomicU64, Ordering};
use smithay::reexports::rustix::process::{getrlimit, setrlimit, Resource, Rlimit};
use tracing::warn;
static NOFILE_RLIMIT_CURRENT: AtomicU64 = AtomicU64::new(0);
static NOFILE_RLIMIT_MAXIMUM: AtomicU64 = AtomicU64::new(0);
pub fn increase_nofile_rlimit() {
let mut limits = getrlimit(Resource::Nofile);
NOFILE_RLIMIT_CURRENT.store(limits.current.unwrap_or(0), Ordering::SeqCst);
NOFILE_RLIMIT_MAXIMUM.store(limits.maximum.unwrap_or(0), Ordering::SeqCst);
limits.current = limits.maximum;
if let Err(err) = setrlimit(Resource::Nofile, limits) {
warn!("Failed to raise nofile limit: {err}");
}
}
pub fn restore_nofile_rlimit() {
let current = NOFILE_RLIMIT_CURRENT.load(Ordering::SeqCst);
let maximum = NOFILE_RLIMIT_MAXIMUM.load(Ordering::SeqCst);
let limits = Rlimit {
current: (current > 0).then_some(current),
maximum: (maximum > 0).then_some(maximum),
};
if let Err(err) = setrlimit(Resource::Nofile, limits) {
warn!("Failed to restore nofile limit: {err}");
}
}