Skip to content

Commit cc678e4

Browse files
d-e-s-oinsearchoflosttime
authored andcommitted
libbpf-rs: Introduce with_ringbuffer helper function
Recently added tests have repeatedly required the instantiation of a ring buffer to which some value is written from a BPF kernel program, which is then read from user space and reported back for verification purposes. This change factors out a function that takes care of precisely that. Signed-off-by: Daniel Müller <deso@posteo.net>
1 parent 33dc305 commit cc678e4

File tree

1 file changed

+48
-84
lines changed

1 file changed

+48
-84
lines changed

libbpf-rs/tests/test.rs

Lines changed: 48 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ pub fn bump_rlimit_mlock() {
5959
);
6060
}
6161

62+
/// A helper function for instantiating a `RingBuffer` with a callback meant to
63+
/// be invoked when `action` is executed and that is intended to trigger a write
64+
/// to said `RingBuffer` from kernel space, which then reads a single `i32` from
65+
/// this buffer from user space and returns it.
66+
fn with_ringbuffer<F>(map: &Map, action: F) -> i32
67+
where
68+
F: FnOnce(),
69+
{
70+
let mut value = 0i32;
71+
{
72+
let callback = |data: &[u8]| {
73+
plain::copy_from_bytes(&mut value, data).expect("Wrong size");
74+
0
75+
};
76+
77+
let mut builder = libbpf_rs::RingBufferBuilder::new();
78+
builder.add(map, callback).expect("Failed to add ringbuf");
79+
let mgr = builder.build().expect("Failed to build");
80+
81+
action();
82+
mgr.consume().expect("Failed to consume ringbuf");
83+
}
84+
85+
value
86+
}
87+
6288
#[test]
6389
fn test_object_build_and_load() {
6490
bump_rlimit_mlock();
@@ -751,30 +777,14 @@ fn test_object_usdt() {
751777
)
752778
.expect("Failed to attach prog");
753779

754-
let mut builder = libbpf_rs::RingBufferBuilder::new();
755780
let map = obj.map("ringbuf").expect("Failed to get ringbuf map");
781+
let action = || {
782+
// Define a USDT probe point and exercise it as we are attaching to self.
783+
probe!(test_provider, test_function, 1);
784+
};
785+
let result = with_ringbuffer(map, action);
756786

757-
static mut V: i32 = 0;
758-
fn callback(data: &[u8]) -> i32 {
759-
let mut value: i32 = 0;
760-
plain::copy_from_bytes(&mut value, data).expect("Wrong size");
761-
762-
unsafe {
763-
V = value;
764-
}
765-
766-
0
767-
}
768-
769-
builder.add(map, callback).expect("Failed to add ringbuf");
770-
let mgr = builder.build().expect("Failed to build");
771-
772-
// Define a USDT probe point and exercise it as we are attaching to self.
773-
probe!(test_provider, test_function, 1);
774-
775-
mgr.consume().expect("Failed to consume ringbuf");
776-
777-
unsafe { assert_eq!(V, 1) };
787+
assert_eq!(result, 1);
778788
}
779789

780790
#[test]
@@ -801,30 +811,14 @@ fn test_object_usdt_cookie() {
801811
)
802812
.expect("Failed to attach prog");
803813

804-
let mut builder = libbpf_rs::RingBufferBuilder::new();
805814
let map = obj.map("ringbuf").expect("Failed to get ringbuf map");
815+
let action = || {
816+
// Define a USDT probe point and exercise it as we are attaching to self.
817+
probe!(test_provider, test_function, 1);
818+
};
819+
let result = with_ringbuffer(map, action);
806820

807-
static mut V: i32 = 0;
808-
fn callback(data: &[u8]) -> i32 {
809-
let mut value: i32 = 0;
810-
plain::copy_from_bytes(&mut value, data).expect("Wrong size");
811-
812-
unsafe {
813-
V = value;
814-
}
815-
816-
0
817-
}
818-
819-
builder.add(map, callback).expect("Failed to add ringbuf");
820-
let mgr = builder.build().expect("Failed to build");
821-
822-
// Define a USDT probe point and exercise it as we are attaching to self.
823-
probe!(test_provider, test_function, 1);
824-
825-
mgr.consume().expect("Failed to consume ringbuf");
826-
827-
unsafe { assert_eq!(V, cookie_val.into()) };
821+
assert_eq!(result, cookie_val.into());
828822
}
829823

830824
#[test]
@@ -906,28 +900,13 @@ fn test_object_tracepoint() {
906900
.attach_tracepoint("syscalls", "sys_enter_getpid")
907901
.expect("Failed to attach prog");
908902

909-
let mut builder = libbpf_rs::RingBufferBuilder::new();
910903
let map = obj.map("ringbuf").expect("Failed to get ringbuf map");
904+
let action = || {
905+
let _pid = unsafe { libc::getpid() };
906+
};
907+
let result = with_ringbuffer(map, action);
911908

912-
static mut V: i32 = 0;
913-
fn callback(data: &[u8]) -> i32 {
914-
let mut value: i32 = 0;
915-
plain::copy_from_bytes(&mut value, data).expect("Wrong size");
916-
917-
unsafe {
918-
V = value;
919-
}
920-
921-
0
922-
}
923-
924-
builder.add(map, callback).expect("Failed to add ringbuf");
925-
let mgr = builder.build().expect("Failed to build");
926-
927-
let _pid = unsafe { libc::getpid() };
928-
mgr.consume().expect("Failed to consume ringbuf");
929-
930-
unsafe { assert_eq!(V, 1) };
909+
assert_eq!(result, 1);
931910
}
932911

933912
/// Check that we can attach a BPF program to a kernel tracepoint, providing
@@ -950,26 +929,11 @@ fn test_object_tracepoint_with_opts() {
950929
.attach_tracepoint_with_opts("syscalls", "sys_enter_getpid", opts)
951930
.expect("Failed to attach prog");
952931

953-
let mut builder = libbpf_rs::RingBufferBuilder::new();
954932
let map = obj.map("ringbuf").expect("Failed to get ringbuf map");
933+
let action = || {
934+
let _pid = unsafe { libc::getpid() };
935+
};
936+
let result = with_ringbuffer(map, action);
955937

956-
static mut V: i32 = 0;
957-
fn callback(data: &[u8]) -> i32 {
958-
let mut value: i32 = 0;
959-
plain::copy_from_bytes(&mut value, data).expect("Wrong size");
960-
961-
unsafe {
962-
V = value;
963-
}
964-
965-
0
966-
}
967-
968-
builder.add(map, callback).expect("Failed to add ringbuf");
969-
let mgr = builder.build().expect("Failed to build");
970-
971-
let _pid = unsafe { libc::getpid() };
972-
mgr.consume().expect("Failed to consume ringbuf");
973-
974-
unsafe { assert_eq!(V, cookie_val.into()) };
938+
assert_eq!(result, cookie_val.into());
975939
}

0 commit comments

Comments
 (0)