Fix kernel version check for map loading
Before this CL, the kernel version check occurred after all maps were loaded by `open_file.load()`. This CL moves the check before `open_file.load()`. It calls `map.set_autocreate(false)` for maps incompatible with the current kernel, preventing their auto-creation by libbpf. Test: Verify the map is not loaded if the kver is out of range Bug: 410982483 Change-Id: I7a102dd2ef4b24f87c6efa5a105848fddc08d501
This commit is contained in:
parent
7f3f0f1c78
commit
91e5b0ba66
1 changed files with 33 additions and 6 deletions
|
|
@ -23,7 +23,7 @@ use libbpf_rs::{
|
|||
set_print, AsRawLibbpf, MapCore, ObjectBuilder, OpenObject, OpenProgramMut, PrintLevel,
|
||||
ProgramType,
|
||||
};
|
||||
use libbpf_sys::bpf_program__set_type;
|
||||
use libbpf_sys::{bpf_map__autocreate, bpf_program__set_type};
|
||||
use libc::{
|
||||
mode_t, uname, utsname, S_IRGRP, S_IRUSR, S_IRWXG, S_IRWXO, S_IRWXU, S_ISVTX, S_IWGRP, S_IWUSR,
|
||||
};
|
||||
|
|
@ -325,6 +325,32 @@ fn kernel_version() -> Result<u32, anyhow::Error> {
|
|||
Ok(kver(major, minor, sub))
|
||||
}
|
||||
|
||||
fn set_skip_loading(
|
||||
open_file: &mut OpenObject,
|
||||
file_desc: &BpfFileDesc,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let kvers = kernel_version()?;
|
||||
|
||||
for mut map in open_file.maps_mut() {
|
||||
let name =
|
||||
map.name().to_str().ok_or_else(|| anyhow!("Failed to parse map name into UTF-8"))?;
|
||||
for map_desc in file_desc.maps {
|
||||
if map_desc.name == name {
|
||||
if kvers < map_desc.min_kver || kvers >= map_desc.max_kver {
|
||||
info!(
|
||||
"skipping map {} min_kver:{:x} max_kver:{:x} kvers:{:x}",
|
||||
name, map_desc.min_kver, map_desc.max_kver, kvers
|
||||
);
|
||||
map.set_autocreate(false)?;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn libbpf_worker(file_desc: &BpfFileDesc) -> Result<(), anyhow::Error> {
|
||||
info!("Loading {}", file_desc.filename);
|
||||
let filepath = Path::new(file_desc.dir).join(file_desc.filename);
|
||||
|
|
@ -342,6 +368,7 @@ fn libbpf_worker(file_desc: &BpfFileDesc) -> Result<(), anyhow::Error> {
|
|||
// libbpf's open_file attempts to infer the prog type based on the section name. But, some
|
||||
// section names are not recognized, so the program type must be set explicitly for them.
|
||||
set_prog_types(&mut open_file)?;
|
||||
set_skip_loading(&mut open_file, file_desc)?;
|
||||
let mut loaded_file = open_file.load()?;
|
||||
|
||||
let bpffs_path = "/sys/fs/bpf/".to_owned() + file_desc.prefix;
|
||||
|
|
@ -361,13 +388,13 @@ fn libbpf_worker(file_desc: &BpfFileDesc) -> Result<(), anyhow::Error> {
|
|||
for map_desc in file_desc.maps {
|
||||
if map_desc.name == name {
|
||||
desc_found = true;
|
||||
if kvers < map_desc.min_kver || kvers >= map_desc.max_kver {
|
||||
info!(
|
||||
"skipping map {} min_kver:{:x} max_kver:{:x} kvers:{:x}",
|
||||
name, map_desc.min_kver, map_desc.max_kver, kvers
|
||||
);
|
||||
// SAFETY: bpf_map__autocreate just returns the field value of libbpf struct
|
||||
let autocreate = unsafe { bpf_map__autocreate(map.as_libbpf_object().as_ptr()) };
|
||||
if !autocreate {
|
||||
// This map is not loaded
|
||||
continue;
|
||||
}
|
||||
|
||||
let pinpath_str = bpffs_path.clone() + "map_" + filename + "_" + &name;
|
||||
let pinpath = Path::new(&pinpath_str);
|
||||
debug!("Pinning: {}", pinpath.display());
|
||||
|
|
|
|||
Loading…
Reference in a new issue