Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ jobs:
uses: libbpf/github-actions/.github/workflows/build-linux.yml@bd7fc70260c9ab81801001fcd86ba94070b34e5d
secrets: inherit
with:
rev: v6.18
# TODO: Use v6.19 tag once available.
rev: ea0714d61dea6e00b853a0116d0afe2b2fe70ef3
config: 'var/config'

test:
Expand Down
61 changes: 3 additions & 58 deletions libbpf-rs/tests/bin/src/stream.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,14 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

/* Definition of can_loop taken from bpf_experimental.h. */
#ifdef __BPF_FEATURE_MAY_GOTO
#define can_loop \
({ \
__label__ l_break, l_continue; \
bool ret = true; \
asm volatile goto("may_goto %l[l_break]" :: ::l_break); \
goto l_continue; \
l_break: \
ret = false; \
l_continue:; \
ret; \
})
#else
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define can_loop \
({ \
__label__ l_break, l_continue; \
bool ret = true; \
asm volatile goto("1:.byte 0xe5; \
.byte 0; \
.long ((%l[l_break] - 1b - 8) / 8) & 0xffff; \
.short 0" :: ::l_break); \
goto l_continue; \
l_break: \
ret = false; \
l_continue:; \
ret; \
})
#else
#define can_loop \
({ \
__label__ l_break, l_continue; \
bool ret = true; \
asm volatile goto("1:.byte 0xe5; \
.byte 0; \
.long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16; \
.short 0" :: ::l_break); \
goto l_continue; \
l_break: \
ret = false; \
l_continue:; \
ret; \
})
#endif
#endif

volatile u64 i;

/*
* Trigger a may_goto timeout to emit a streams error. As of 6.19 the only way
* to trigger streams output is by causing an error condition in the program.
* One of these is a loop timeout: The may_goto macro allows for loops that
* cannot be verified by embedding a timer that is guaranteed to expire in the
* condition, simplifying verification. When the timer expires, the kernel
* writes an error message to the stderr stream of the BPF program. This is the
* case below.
* Trigger writing of some messages to stdout & stderr streams.
*/
SEC("syscall")
int trigger_streams(void *ctx)
{
while (i == 0 && can_loop)
;
bpf_stream_printk(1, "stdout");
bpf_stream_printk(2, "stderr");
return 0;
}

Expand Down
21 changes: 4 additions & 17 deletions libbpf-rs/tests/test_streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,9 @@ fn test_stream_stdout_read() {
let mut stdout = prog.stdout();
let mut buf = [0u8; 1024];

// The read itself should succeed and return 0 bytes
let result = stdout.read(&mut buf);
assert!(
result.is_ok(),
"Failed to read from stdout stream: {:?}",
result.err()
);

let len = result.unwrap();
assert!(len == 0, "Found {len} characters in stdout stream");
let cnt = result.unwrap();
assert_eq!(&buf[..cnt], b"stdout");
}

#[tag(root)]
Expand All @@ -50,13 +43,7 @@ fn test_stream_stderr_read() {
let mut stderr = prog.stderr();
let mut buf = [0u8; 1024];

// The read should successfully read a non-zero amount of bytes
let result = stderr.read(&mut buf);
assert!(
result.is_ok(),
"Failed to read from stderr stream: {:?}",
result.err()
);

assert!(result.unwrap() != 0, "No output from stderr stream");
let cnt = result.unwrap();
assert_eq!(&buf[..cnt], b"stderr");
}