Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: OS specific setting of file limits
Fintan Halpenny committed 2 years ago
commit 8bff6c9405eb8dee1699feb437ea29c4dfeed18d
parent 6ab3bfcba0577fabdcb84498441c6605391290f4
2 files changed +51 -2
modified radicle-node/src/main.rs
@@ -120,7 +120,7 @@ fn execute() -> anyhow::Result<()> {
        config.node.listen.clone()
    };

-
    if let Err(e) = radicle::io::set_file_limit(config.node.limits.max_open_files as u64) {
+
    if let Err(e) = radicle::io::set_file_limit(config.node.limits.max_open_files) {
        log::warn!(target: "node", "Unable to set process open file limit: {e}");
    }

modified radicle/src/io.rs
@@ -1,9 +1,58 @@
+
use std::fmt;
use std::io;

use libc::{getrlimit, rlimit, setrlimit, RLIMIT_NOFILE};

+
#[cfg(target_family = "unix")]
/// Sets the open file limit to the given value, or the maximum allowed value.
-
pub fn set_file_limit(n: u64) -> io::Result<u64> {
+
pub fn set_file_limit<N>(n: N) -> io::Result<u64>
+
where
+
    N: Copy + fmt::Display,
+
    u64: TryFrom<N>,
+
{
+
    let Ok(n) = u64::try_from(n) else {
+
        return Err(io::Error::new(
+
            io::ErrorKind::InvalidInput,
+
            format!("expected value that fits into u64, found: {n}"),
+
        ));
+
    };
+
    let mut rlim = rlimit {
+
        rlim_cur: 0, // Initial soft limit value
+
        rlim_max: 0, // Initial hard limit value
+
    };
+
    // Get the current limits.
+
    unsafe {
+
        if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
+
            return Err(io::Error::last_os_error());
+
        }
+
    }
+
    if rlim.rlim_cur >= n {
+
        return Ok(rlim.rlim_cur);
+
    }
+
    // Set the soft limit to the given value, up to the hard limit.
+
    rlim.rlim_cur = n.min(rlim.rlim_max);
+
    unsafe {
+
        if setrlimit(RLIMIT_NOFILE, &rlim as *const rlimit) != 0 {
+
            return Err(io::Error::last_os_error());
+
        }
+
    }
+
    Ok(rlim.rlim_cur)
+
}
+

+
// N.b. windows uses i64 instead of u64
+
#[cfg(target_family = "windows")]
+
/// Sets the open file limit to the given value, or the maximum allowed value.
+
pub fn set_file_limit<N>(n: N) -> io::Result<i64>
+
where
+
    N: Copy + fmt::Display,
+
    i64: TryFrom<N>,
+
{
+
    let Ok(n) = u64::try_from(n) else {
+
        return Err(io::Error::new(
+
            io::ErrorKind::InvalidInput,
+
            format!("expected value that fits into i64, found: {n}"),
+
        ));
+
    };
    let mut rlim = rlimit {
        rlim_cur: 0, // Initial soft limit value
        rlim_max: 0, // Initial hard limit value