aya: Raise the warning when RMILIT_MEMLOCK is not RLIM_INFINITY

Kernels before 5.11 don't use cgroup accounting, so they might reach the
RLIMIT_MEMLOCK when creating maps. After this change, we raise a warning
recommending to raise the RLIMIT_MEMLOCK.
pull/342/head
Michal Rostecki 2 years ago
parent 555833a79a
commit bebe98e670

@ -64,11 +64,12 @@ pub mod uprobe;
mod utils; mod utils;
pub mod xdp; pub mod xdp;
use libc::ENOSPC; use libc::{getrlimit, rlimit, ENOSPC, RLIMIT_MEMLOCK, RLIM_INFINITY};
use log::warn;
use std::{ use std::{
convert::TryFrom, convert::TryFrom,
ffi::CString, ffi::CString,
io, fmt, io,
os::unix::io::{AsRawFd, RawFd}, os::unix::io::{AsRawFd, RawFd},
path::Path, path::Path,
}; };
@ -214,6 +215,20 @@ pub enum ProgramError {
}, },
} }
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct RlimitSize(u64);
impl fmt::Display for RlimitSize {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.0 < 1024 {
write!(f, "{} bytes", self.0)
} else if self.0 < 1024 * 1024 {
write!(f, "{} KiB", self.0 / 1024)
} else {
write!(f, "{} MiB", self.0 / 1024 / 1024)
}
}
}
/// A [`Program`] file descriptor. /// A [`Program`] file descriptor.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct ProgramFd(RawFd); pub struct ProgramFd(RawFd);
@ -472,6 +487,22 @@ fn unload_program<T: Link>(data: &mut ProgramData<T>) -> Result<(), ProgramError
Ok(()) Ok(())
} }
fn check_rlimit() {
let mut limit = std::mem::MaybeUninit::<rlimit>::uninit();
let ret = unsafe { getrlimit(RLIMIT_MEMLOCK, limit.as_mut_ptr()) };
if ret == 0 {
let limit = unsafe { limit.assume_init() };
let limit: RlimitSize = RlimitSize(limit.rlim_cur);
if limit.0 == RLIM_INFINITY {
return;
}
warn!(
"RLIMIT_MEMLOCK value is {}, not RLIM_INFNITY; if experiencing problems with creating maps, try raising RMILIT_MEMLOCK to RLIM_INFINITY",
limit
);
}
}
fn load_program<T: Link>( fn load_program<T: Link>(
prog_type: bpf_prog_type, prog_type: bpf_prog_type,
data: &mut ProgramData<T>, data: &mut ProgramData<T>,
@ -502,6 +533,10 @@ fn load_program<T: Link>(
} }
_ => (*kernel_version).into(), _ => (*kernel_version).into(),
}; };
let version_5_11 = (5 << 16) + (11 << 8);
if target_kernel_version < version_5_11 {
check_rlimit();
}
let mut logger = VerifierLog::new(); let mut logger = VerifierLog::new();

Loading…
Cancel
Save