Skip to content

Commit

Permalink
Make various Program::attach_* methods work on shared receiver
Browse files Browse the repository at this point in the history
Attaching a BPF program currently provides exclusive access to the
Program object, but it's not exactly clear why that is. Given that
libbpf work on const pointers, let's switch over to having those methods
work on a shared receiver instead, eliminating a bunch of possible
borrow conflicts.

Refs: #953

Signed-off-by: Daniel Müller <deso@posteo.net>
  • Loading branch information
d-e-s-o committed Sep 30, 2024
1 parent 2c597a5 commit d035e43
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 43 deletions.
2 changes: 1 addition & 1 deletion examples/tcp_option/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ fn main() -> Result<()> {
open.maps.rodata_data.targ_ip = u32::from_be_bytes(ip.octets()).to_be();
open.maps.rodata_data.data_such_as_trace_id = opts.trace_id;

let mut skel = open.load()?;
let skel = open.load()?;

let cgroup_fd = OpenOptions::new()
.read(true)
Expand Down
2 changes: 2 additions & 0 deletions libbpf-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Unreleased
- Deprecated `Program::get_id_by_fd`
- Renamed `Program::get_fd_by_id` to `fd_from_id`
- Deprecated `Program::get_fd_by_id`
- Adjusted various `Program::attach_*` methods to work on shared
receivers
- Adjusted `PerfBufferBuilder` to work with `MapCore` objects


Expand Down
42 changes: 19 additions & 23 deletions libbpf-rs/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Auto-attach based on prog section
pub fn attach(&mut self) -> Result<Link> {
pub fn attach(&self) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach(self.ptr.as_ptr()) };
let ptr = validate_bpf_ret(ptr).context("failed to attach BPF program")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -753,7 +753,7 @@ impl<'obj> ProgramMut<'obj> {

/// Attach this program to a
/// [cgroup](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html).
pub fn attach_cgroup(&mut self, cgroup_fd: i32) -> Result<Link> {
pub fn attach_cgroup(&self, cgroup_fd: i32) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach_cgroup(self.ptr.as_ptr(), cgroup_fd) };
let ptr = validate_bpf_ret(ptr).context("failed to attach cgroup")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -762,7 +762,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Attach this program to a [perf event](https://linux.die.net/man/2/perf_event_open).
pub fn attach_perf_event(&mut self, pfd: i32) -> Result<Link> {
pub fn attach_perf_event(&self, pfd: i32) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach_perf_event(self.ptr.as_ptr(), pfd) };
let ptr = validate_bpf_ret(ptr).context("failed to attach perf event")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -773,7 +773,7 @@ impl<'obj> ProgramMut<'obj> {
/// Attach this program to a [userspace
/// probe](https://www.kernel.org/doc/html/latest/trace/uprobetracer.html).
pub fn attach_uprobe<T: AsRef<Path>>(
&mut self,
&self,
retprobe: bool,
pid: i32,
binary_path: T,
Expand All @@ -800,7 +800,7 @@ impl<'obj> ProgramMut<'obj> {
/// probe](https://www.kernel.org/doc/html/latest/trace/uprobetracer.html),
/// providing additional options.
pub fn attach_uprobe_with_opts(
&mut self,
&self,
pid: i32,
binary_path: impl AsRef<Path>,
func_offset: usize,
Expand Down Expand Up @@ -843,7 +843,7 @@ impl<'obj> ProgramMut<'obj> {

/// Attach this program to a [kernel
/// probe](https://www.kernel.org/doc/html/latest/trace/kprobetrace.html).
pub fn attach_kprobe<T: AsRef<str>>(&mut self, retprobe: bool, func_name: T) -> Result<Link> {
pub fn attach_kprobe<T: AsRef<str>>(&self, retprobe: bool, func_name: T) -> Result<Link> {
let func_name = util::str_to_cstring(func_name.as_ref())?;
let func_name_ptr = func_name.as_ptr();
let ptr = unsafe {
Expand All @@ -856,11 +856,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Attach this program to the specified syscall
pub fn attach_ksyscall<T: AsRef<str>>(
&mut self,
retprobe: bool,
syscall_name: T,
) -> Result<Link> {
pub fn attach_ksyscall<T: AsRef<str>>(&self, retprobe: bool, syscall_name: T) -> Result<Link> {
let opts = libbpf_sys::bpf_ksyscall_opts {
sz: size_of::<libbpf_sys::bpf_ksyscall_opts>() as _,
retprobe,
Expand All @@ -879,7 +875,7 @@ impl<'obj> ProgramMut<'obj> {
}

fn attach_tracepoint_impl(
&mut self,
&self,
tp_category: &str,
tp_name: &str,
tp_opts: Option<TracepointOpts>,
Expand Down Expand Up @@ -918,7 +914,7 @@ impl<'obj> ProgramMut<'obj> {
/// Attach this program to a [kernel
/// tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html).
pub fn attach_tracepoint(
&mut self,
&self,
tp_category: impl AsRef<str>,
tp_name: impl AsRef<str>,
) -> Result<Link> {
Expand All @@ -929,7 +925,7 @@ impl<'obj> ProgramMut<'obj> {
/// tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html),
/// providing additional options.
pub fn attach_tracepoint_with_opts(
&mut self,
&self,
tp_category: impl AsRef<str>,
tp_name: impl AsRef<str>,
tp_opts: TracepointOpts,
Expand All @@ -939,7 +935,7 @@ impl<'obj> ProgramMut<'obj> {

/// Attach this program to a [raw kernel
/// tracepoint](https://lwn.net/Articles/748352/).
pub fn attach_raw_tracepoint<T: AsRef<str>>(&mut self, tp_name: T) -> Result<Link> {
pub fn attach_raw_tracepoint<T: AsRef<str>>(&self, tp_name: T) -> Result<Link> {
let tp_name = util::str_to_cstring(tp_name.as_ref())?;
let tp_name_ptr = tp_name.as_ptr();
let ptr = unsafe {
Expand All @@ -952,7 +948,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Attach to an [LSM](https://en.wikipedia.org/wiki/Linux_Security_Modules) hook
pub fn attach_lsm(&mut self) -> Result<Link> {
pub fn attach_lsm(&self) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach_lsm(self.ptr.as_ptr()) };
let ptr = validate_bpf_ret(ptr).context("failed to attach LSM")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -961,7 +957,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Attach to a [fentry/fexit kernel probe](https://lwn.net/Articles/801479/)
pub fn attach_trace(&mut self) -> Result<Link> {
pub fn attach_trace(&self) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach_trace(self.ptr.as_ptr()) };
let ptr = validate_bpf_ret(ptr).context("failed to attach fentry/fexit kernel probe")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -983,7 +979,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Attach this program to [XDP](https://lwn.net/Articles/825998/)
pub fn attach_xdp(&mut self, ifindex: i32) -> Result<Link> {
pub fn attach_xdp(&self, ifindex: i32) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach_xdp(self.ptr.as_ptr(), ifindex) };
let ptr = validate_bpf_ret(ptr).context("failed to attach XDP program")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -992,7 +988,7 @@ impl<'obj> ProgramMut<'obj> {
}

/// Attach this program to [netns-based programs](https://lwn.net/Articles/819618/)
pub fn attach_netns(&mut self, netns_fd: i32) -> Result<Link> {
pub fn attach_netns(&self, netns_fd: i32) -> Result<Link> {
let ptr = unsafe { libbpf_sys::bpf_program__attach_netns(self.ptr.as_ptr(), netns_fd) };
let ptr = validate_bpf_ret(ptr).context("failed to attach network namespace program")?;
// SAFETY: the pointer came from libbpf and has been checked for errors.
Expand All @@ -1001,7 +997,7 @@ impl<'obj> ProgramMut<'obj> {
}

fn attach_usdt_impl(
&mut self,
&self,
pid: i32,
binary_path: &Path,
usdt_provider: &str,
Expand Down Expand Up @@ -1040,7 +1036,7 @@ impl<'obj> ProgramMut<'obj> {
/// point. The entry point of the program must be defined with
/// `SEC("usdt")`.
pub fn attach_usdt(
&mut self,
&self,
pid: i32,
binary_path: impl AsRef<Path>,
usdt_provider: impl AsRef<str>,
Expand All @@ -1059,7 +1055,7 @@ impl<'obj> ProgramMut<'obj> {
/// point, providing additional options. The entry point of the program must
/// be defined with `SEC("usdt")`.
pub fn attach_usdt_with_opts(
&mut self,
&self,
pid: i32,
binary_path: impl AsRef<Path>,
usdt_provider: impl AsRef<str>,
Expand All @@ -1078,7 +1074,7 @@ impl<'obj> ProgramMut<'obj> {
/// Attach this program to a
/// [BPF Iterator](https://www.kernel.org/doc/html/latest/bpf/bpf_iterators.html).
/// The entry point of the program must be defined with `SEC("iter")` or `SEC("iter.s")`.
pub fn attach_iter(&mut self, map_fd: BorrowedFd<'_>) -> Result<Link> {
pub fn attach_iter(&self, map_fd: BorrowedFd<'_>) -> Result<Link> {
let mut linkinfo = libbpf_sys::bpf_iter_link_info::default();
linkinfo.map.map_fd = map_fd.as_raw_fd() as _;
let attach_opt = libbpf_sys::bpf_iter_attach_opts {
Expand Down
38 changes: 19 additions & 19 deletions libbpf-rs/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ fn test_object_link_pin() {
bump_rlimit_mlock();

let mut obj = get_test_object("runqslower.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sched_wakeup");
let prog = get_prog_mut(&mut obj, "handle__sched_wakeup");
let mut link = prog.attach().expect("failed to attach prog");

let path = "/sys/fs/bpf/mylink";
Expand Down Expand Up @@ -941,7 +941,7 @@ fn test_object_ringbuf_raw() {
bump_rlimit_mlock();

let mut obj = get_test_object("ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");

static mut V1: i32 = 0;
Expand Down Expand Up @@ -1022,7 +1022,7 @@ fn test_object_ringbuf_err_callback() {
bump_rlimit_mlock();

let mut obj = get_test_object("ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");

// Immediately trigger an error that should be reported back to the consume_raw() or poll_raw()
Expand Down Expand Up @@ -1084,7 +1084,7 @@ fn test_object_ringbuf() {
bump_rlimit_mlock();

let mut obj = get_test_object("ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");

static mut V1: i32 = 0;
Expand Down Expand Up @@ -1169,7 +1169,7 @@ fn test_object_ringbuf_closure() {
bump_rlimit_mlock();

let mut obj = get_test_object("ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");

let (sender1, receiver1) = channel();
Expand Down Expand Up @@ -1243,7 +1243,7 @@ fn test_object_ringbuf_with_closed_map() {

{
let mut obj = get_test_object("tracepoint.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint");
let prog = get_prog_mut(&mut obj, "handle__tracepoint");
let _link = prog
.attach_tracepoint("syscalls", "sys_enter_getpid")
.expect("failed to attach prog");
Expand Down Expand Up @@ -1293,7 +1293,7 @@ fn test_object_user_ringbuf() {
bump_rlimit_mlock();

let mut obj = get_test_object("user_ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");
let urb_map = get_map_mut(&mut obj, "user_ringbuf");
let user_ringbuf = UserRingBuffer::new(&urb_map).expect("failed to create user ringbuf");
Expand Down Expand Up @@ -1334,7 +1334,7 @@ fn test_object_user_ringbuf_reservation_too_big() {
bump_rlimit_mlock();

let mut obj = get_test_object("user_ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");
let urb_map = get_map_mut(&mut obj, "user_ringbuf");
let user_ringbuf = UserRingBuffer::new(&urb_map).expect("failed to create user ringbuf");
Expand All @@ -1351,7 +1351,7 @@ fn test_object_user_ringbuf_not_enough_space() {
bump_rlimit_mlock();

let mut obj = get_test_object("user_ringbuf.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
let _link = prog.attach().expect("failed to attach prog");
let urb_map = get_map_mut(&mut obj, "user_ringbuf");
let user_ringbuf = UserRingBuffer::new(&urb_map).expect("failed to create user ringbuf");
Expand All @@ -1372,7 +1372,7 @@ fn test_object_task_iter() {
bump_rlimit_mlock();

let mut obj = get_test_object("taskiter.bpf.o");
let mut prog = get_prog_mut(&mut obj, "dump_pid");
let prog = get_prog_mut(&mut obj, "dump_pid");
let link = prog.attach().expect("failed to attach prog");
let mut iter = Iter::new(&link).expect("failed to create iterator");

Expand Down Expand Up @@ -1433,7 +1433,7 @@ fn test_object_map_iter() {
}

let mut obj = get_test_object("mapiter.bpf.o");
let mut prog = get_prog_mut(&mut obj, "map_iter");
let prog = get_prog_mut(&mut obj, "map_iter");
let link = prog
.attach_iter(map.as_fd())
.expect("failed to attach map iter prog");
Expand Down Expand Up @@ -1571,7 +1571,7 @@ fn test_object_usdt() {
bump_rlimit_mlock();

let mut obj = get_test_object("usdt.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__usdt");
let prog = get_prog_mut(&mut obj, "handle__usdt");

let path = current_exe().expect("failed to find executable name");
let _link = prog
Expand Down Expand Up @@ -1600,7 +1600,7 @@ fn test_object_usdt_cookie() {

let cookie_val = 1337u16;
let mut obj = get_test_object("usdt.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__usdt_with_cookie");
let prog = get_prog_mut(&mut obj, "handle__usdt_with_cookie");

let path = current_exe().expect("failed to find executable name");
let _link = prog
Expand Down Expand Up @@ -1703,7 +1703,7 @@ fn test_object_tracepoint() {
bump_rlimit_mlock();

let mut obj = get_test_object("tracepoint.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint");
let prog = get_prog_mut(&mut obj, "handle__tracepoint");
let _link = prog
.attach_tracepoint("syscalls", "sys_enter_getpid")
.expect("failed to attach prog");
Expand All @@ -1726,7 +1726,7 @@ fn test_object_tracepoint_with_opts() {

let cookie_val = 42u16;
let mut obj = get_test_object("tracepoint.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie");
let prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie");

let opts = TracepointOpts {
cookie: cookie_val.into(),
Expand Down Expand Up @@ -1759,7 +1759,7 @@ fn test_object_uprobe_with_opts() {
bump_rlimit_mlock();

let mut obj = get_test_object("uprobe.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__uprobe");
let prog = get_prog_mut(&mut obj, "handle__uprobe");

let pid = unsafe { libc::getpid() };
let path = current_exe().expect("failed to find executable name");
Expand Down Expand Up @@ -1790,7 +1790,7 @@ fn test_object_uprobe_with_cookie() {

let cookie_val = 5u16;
let mut obj = get_test_object("uprobe.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__uprobe_with_cookie");
let prog = get_prog_mut(&mut obj, "handle__uprobe_with_cookie");

let pid = unsafe { libc::getpid() };
let path = current_exe().expect("failed to find executable name");
Expand Down Expand Up @@ -1869,7 +1869,7 @@ fn test_object_perf_buffer_raw() {

let cookie_val = 42u16;
let mut obj = get_test_object("tracepoint.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie_pb");
let prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie_pb");

let opts = TracepointOpts {
cookie: cookie_val.into(),
Expand Down Expand Up @@ -2002,7 +2002,7 @@ fn test_attach_ksyscall() {
bump_rlimit_mlock();

let mut obj = get_test_object("ksyscall.bpf.o");
let mut prog = get_prog_mut(&mut obj, "handle__ksyscall");
let prog = get_prog_mut(&mut obj, "handle__ksyscall");
let _link = prog
.attach_ksyscall(false, "kill")
.expect("failed to attach prog");
Expand Down

0 comments on commit d035e43

Please sign in to comment.