Skip to content

Commit d035e43

Browse files
committed
Make various Program::attach_* methods work on shared receiver
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 <[email protected]>
1 parent 2c597a5 commit d035e43

File tree

4 files changed

+41
-43
lines changed

4 files changed

+41
-43
lines changed

examples/tcp_option/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn main() -> Result<()> {
106106
open.maps.rodata_data.targ_ip = u32::from_be_bytes(ip.octets()).to_be();
107107
open.maps.rodata_data.data_such_as_trace_id = opts.trace_id;
108108

109-
let mut skel = open.load()?;
109+
let skel = open.load()?;
110110

111111
let cgroup_fd = OpenOptions::new()
112112
.read(true)

libbpf-rs/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Unreleased
44
- Deprecated `Program::get_id_by_fd`
55
- Renamed `Program::get_fd_by_id` to `fd_from_id`
66
- Deprecated `Program::get_fd_by_id`
7+
- Adjusted various `Program::attach_*` methods to work on shared
8+
receivers
79
- Adjusted `PerfBufferBuilder` to work with `MapCore` objects
810

911

libbpf-rs/src/program.rs

+19-23
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ impl<'obj> ProgramMut<'obj> {
743743
}
744744

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

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

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

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

858858
/// Attach this program to the specified syscall
859-
pub fn attach_ksyscall<T: AsRef<str>>(
860-
&mut self,
861-
retprobe: bool,
862-
syscall_name: T,
863-
) -> Result<Link> {
859+
pub fn attach_ksyscall<T: AsRef<str>>(&self, retprobe: bool, syscall_name: T) -> Result<Link> {
864860
let opts = libbpf_sys::bpf_ksyscall_opts {
865861
sz: size_of::<libbpf_sys::bpf_ksyscall_opts>() as _,
866862
retprobe,
@@ -879,7 +875,7 @@ impl<'obj> ProgramMut<'obj> {
879875
}
880876

881877
fn attach_tracepoint_impl(
882-
&mut self,
878+
&self,
883879
tp_category: &str,
884880
tp_name: &str,
885881
tp_opts: Option<TracepointOpts>,
@@ -918,7 +914,7 @@ impl<'obj> ProgramMut<'obj> {
918914
/// Attach this program to a [kernel
919915
/// tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html).
920916
pub fn attach_tracepoint(
921-
&mut self,
917+
&self,
922918
tp_category: impl AsRef<str>,
923919
tp_name: impl AsRef<str>,
924920
) -> Result<Link> {
@@ -929,7 +925,7 @@ impl<'obj> ProgramMut<'obj> {
929925
/// tracepoint](https://www.kernel.org/doc/html/latest/trace/tracepoints.html),
930926
/// providing additional options.
931927
pub fn attach_tracepoint_with_opts(
932-
&mut self,
928+
&self,
933929
tp_category: impl AsRef<str>,
934930
tp_name: impl AsRef<str>,
935931
tp_opts: TracepointOpts,
@@ -939,7 +935,7 @@ impl<'obj> ProgramMut<'obj> {
939935

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

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

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

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

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

1003999
fn attach_usdt_impl(
1004-
&mut self,
1000+
&self,
10051001
pid: i32,
10061002
binary_path: &Path,
10071003
usdt_provider: &str,
@@ -1040,7 +1036,7 @@ impl<'obj> ProgramMut<'obj> {
10401036
/// point. The entry point of the program must be defined with
10411037
/// `SEC("usdt")`.
10421038
pub fn attach_usdt(
1043-
&mut self,
1039+
&self,
10441040
pid: i32,
10451041
binary_path: impl AsRef<Path>,
10461042
usdt_provider: impl AsRef<str>,
@@ -1059,7 +1055,7 @@ impl<'obj> ProgramMut<'obj> {
10591055
/// point, providing additional options. The entry point of the program must
10601056
/// be defined with `SEC("usdt")`.
10611057
pub fn attach_usdt_with_opts(
1062-
&mut self,
1058+
&self,
10631059
pid: i32,
10641060
binary_path: impl AsRef<Path>,
10651061
usdt_provider: impl AsRef<str>,
@@ -1078,7 +1074,7 @@ impl<'obj> ProgramMut<'obj> {
10781074
/// Attach this program to a
10791075
/// [BPF Iterator](https://www.kernel.org/doc/html/latest/bpf/bpf_iterators.html).
10801076
/// The entry point of the program must be defined with `SEC("iter")` or `SEC("iter.s")`.
1081-
pub fn attach_iter(&mut self, map_fd: BorrowedFd<'_>) -> Result<Link> {
1077+
pub fn attach_iter(&self, map_fd: BorrowedFd<'_>) -> Result<Link> {
10821078
let mut linkinfo = libbpf_sys::bpf_iter_link_info::default();
10831079
linkinfo.map.map_fd = map_fd.as_raw_fd() as _;
10841080
let attach_opt = libbpf_sys::bpf_iter_attach_opts {

libbpf-rs/tests/test.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ fn test_object_link_pin() {
861861
bump_rlimit_mlock();
862862

863863
let mut obj = get_test_object("runqslower.bpf.o");
864-
let mut prog = get_prog_mut(&mut obj, "handle__sched_wakeup");
864+
let prog = get_prog_mut(&mut obj, "handle__sched_wakeup");
865865
let mut link = prog.attach().expect("failed to attach prog");
866866

867867
let path = "/sys/fs/bpf/mylink";
@@ -941,7 +941,7 @@ fn test_object_ringbuf_raw() {
941941
bump_rlimit_mlock();
942942

943943
let mut obj = get_test_object("ringbuf.bpf.o");
944-
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
944+
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
945945
let _link = prog.attach().expect("failed to attach prog");
946946

947947
static mut V1: i32 = 0;
@@ -1022,7 +1022,7 @@ fn test_object_ringbuf_err_callback() {
10221022
bump_rlimit_mlock();
10231023

10241024
let mut obj = get_test_object("ringbuf.bpf.o");
1025-
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
1025+
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
10261026
let _link = prog.attach().expect("failed to attach prog");
10271027

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

10861086
let mut obj = get_test_object("ringbuf.bpf.o");
1087-
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
1087+
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
10881088
let _link = prog.attach().expect("failed to attach prog");
10891089

10901090
static mut V1: i32 = 0;
@@ -1169,7 +1169,7 @@ fn test_object_ringbuf_closure() {
11691169
bump_rlimit_mlock();
11701170

11711171
let mut obj = get_test_object("ringbuf.bpf.o");
1172-
let mut prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
1172+
let prog = get_prog_mut(&mut obj, "handle__sys_enter_getpid");
11731173
let _link = prog.attach().expect("failed to attach prog");
11741174

11751175
let (sender1, receiver1) = channel();
@@ -1243,7 +1243,7 @@ fn test_object_ringbuf_with_closed_map() {
12431243

12441244
{
12451245
let mut obj = get_test_object("tracepoint.bpf.o");
1246-
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint");
1246+
let prog = get_prog_mut(&mut obj, "handle__tracepoint");
12471247
let _link = prog
12481248
.attach_tracepoint("syscalls", "sys_enter_getpid")
12491249
.expect("failed to attach prog");
@@ -1293,7 +1293,7 @@ fn test_object_user_ringbuf() {
12931293
bump_rlimit_mlock();
12941294

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

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

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

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

@@ -1433,7 +1433,7 @@ fn test_object_map_iter() {
14331433
}
14341434

14351435
let mut obj = get_test_object("mapiter.bpf.o");
1436-
let mut prog = get_prog_mut(&mut obj, "map_iter");
1436+
let prog = get_prog_mut(&mut obj, "map_iter");
14371437
let link = prog
14381438
.attach_iter(map.as_fd())
14391439
.expect("failed to attach map iter prog");
@@ -1571,7 +1571,7 @@ fn test_object_usdt() {
15711571
bump_rlimit_mlock();
15721572

15731573
let mut obj = get_test_object("usdt.bpf.o");
1574-
let mut prog = get_prog_mut(&mut obj, "handle__usdt");
1574+
let prog = get_prog_mut(&mut obj, "handle__usdt");
15751575

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

16011601
let cookie_val = 1337u16;
16021602
let mut obj = get_test_object("usdt.bpf.o");
1603-
let mut prog = get_prog_mut(&mut obj, "handle__usdt_with_cookie");
1603+
let prog = get_prog_mut(&mut obj, "handle__usdt_with_cookie");
16041604

16051605
let path = current_exe().expect("failed to find executable name");
16061606
let _link = prog
@@ -1703,7 +1703,7 @@ fn test_object_tracepoint() {
17031703
bump_rlimit_mlock();
17041704

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

17271727
let cookie_val = 42u16;
17281728
let mut obj = get_test_object("tracepoint.bpf.o");
1729-
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie");
1729+
let prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie");
17301730

17311731
let opts = TracepointOpts {
17321732
cookie: cookie_val.into(),
@@ -1759,7 +1759,7 @@ fn test_object_uprobe_with_opts() {
17591759
bump_rlimit_mlock();
17601760

17611761
let mut obj = get_test_object("uprobe.bpf.o");
1762-
let mut prog = get_prog_mut(&mut obj, "handle__uprobe");
1762+
let prog = get_prog_mut(&mut obj, "handle__uprobe");
17631763

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

17911791
let cookie_val = 5u16;
17921792
let mut obj = get_test_object("uprobe.bpf.o");
1793-
let mut prog = get_prog_mut(&mut obj, "handle__uprobe_with_cookie");
1793+
let prog = get_prog_mut(&mut obj, "handle__uprobe_with_cookie");
17941794

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

18701870
let cookie_val = 42u16;
18711871
let mut obj = get_test_object("tracepoint.bpf.o");
1872-
let mut prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie_pb");
1872+
let prog = get_prog_mut(&mut obj, "handle__tracepoint_with_cookie_pb");
18731873

18741874
let opts = TracepointOpts {
18751875
cookie: cookie_val.into(),
@@ -2002,7 +2002,7 @@ fn test_attach_ksyscall() {
20022002
bump_rlimit_mlock();
20032003

20042004
let mut obj = get_test_object("ksyscall.bpf.o");
2005-
let mut prog = get_prog_mut(&mut obj, "handle__ksyscall");
2005+
let prog = get_prog_mut(&mut obj, "handle__ksyscall");
20062006
let _link = prog
20072007
.attach_ksyscall(false, "kill")
20082008
.expect("failed to attach prog");

0 commit comments

Comments
 (0)