Skip to content

Commit f7ddb5d

Browse files
committed
bpftool: Add support for dumping streams
Add support for printing the BPF stream contents of a program in bpftool. The new bpftool prog tracelog command is extended to take stdout and stderr arguments, and then the prog specification. The bpf_prog_stream_read() API added in previous patch is simply reused to grab data and then it is dumped to the respective file. The stdout data is sent to stdout, and stderr is printed to stderr. Cc: Quentin Monnet <[email protected]> Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]>
1 parent a02f205 commit f7ddb5d

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

tools/bpf/bpftool/Documentation/bpftool-prog.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ PROG COMMANDS
3535
| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
3636
| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
3737
| **bpftool** **prog tracelog**
38+
| **bpftool** **prog tracelog** [ { **stdout** | **stderr** } *PROG* ]
3839
| **bpftool** **prog run** *PROG* **data_in** *FILE* [**data_out** *FILE* [**data_size_out** *L*]] [**ctx_in** *FILE* [**ctx_out** *FILE* [**ctx_size_out** *M*]]] [**repeat** *N*]
3940
| **bpftool** **prog profile** *PROG* [**duration** *DURATION*] *METRICs*
4041
| **bpftool** **prog help**
@@ -179,6 +180,12 @@ bpftool prog tracelog
179180
purposes. For streaming data from BPF programs to user space, one can use
180181
perf events (see also **bpftool-map**\ (8)).
181182

183+
bpftool prog tracelog { stdout | stderr } *PROG*
184+
Dump the BPF stream of the program. BPF programs can write to these streams
185+
at runtime with the **bpf_stream_vprintk**\ () kfunc. The kernel may write
186+
error messages to the standard error stream. This facility should be used
187+
only for debugging purposes.
188+
182189
bpftool prog run *PROG* data_in *FILE* [data_out *FILE* [data_size_out *L*]] [ctx_in *FILE* [ctx_out *FILE* [ctx_size_out *M*]]] [repeat *N*]
183190
Run BPF program *PROG* in the kernel testing infrastructure for BPF,
184191
meaning that the program works on the data and context provided by the

tools/bpf/bpftool/bash-completion/bpftool

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,21 @@ _bpftool()
518518
esac
519519
;;
520520
tracelog)
521-
return 0
521+
case $prev in
522+
$command)
523+
COMPREPLY+=( $( compgen -W "stdout stderr" -- \
524+
"$cur" ) )
525+
return 0
526+
;;
527+
stdout|stderr)
528+
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
529+
"$cur" ) )
530+
return 0
531+
;;
532+
*)
533+
return 0
534+
;;
535+
esac
522536
;;
523537
profile)
524538
case $cword in

tools/bpf/bpftool/prog.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,52 @@ static int do_detach(int argc, char **argv)
11131113
return 0;
11141114
}
11151115

1116+
enum prog_tracelog_mode {
1117+
TRACE_STDOUT,
1118+
TRACE_STDERR,
1119+
};
1120+
1121+
static int
1122+
prog_tracelog_stream(int prog_fd, enum prog_tracelog_mode mode)
1123+
{
1124+
FILE *file = mode == TRACE_STDOUT ? stdout : stderr;
1125+
int stream_id = mode == TRACE_STDOUT ? 1 : 2;
1126+
char buf[512];
1127+
int ret;
1128+
1129+
ret = 0;
1130+
do {
1131+
ret = bpf_prog_stream_read(prog_fd, stream_id, buf, sizeof(buf), NULL);
1132+
if (ret > 0)
1133+
fwrite(buf, sizeof(buf[0]), ret, file);
1134+
} while (ret > 0);
1135+
1136+
fflush(file);
1137+
return ret ? -1 : 0;
1138+
}
1139+
1140+
static int do_tracelog_any(int argc, char **argv)
1141+
{
1142+
enum prog_tracelog_mode mode;
1143+
int fd;
1144+
1145+
if (argc == 0)
1146+
return do_tracelog(argc, argv);
1147+
if (!is_prefix(*argv, "stdout") && !is_prefix(*argv, "stderr"))
1148+
usage();
1149+
mode = is_prefix(*argv, "stdout") ? TRACE_STDOUT : TRACE_STDERR;
1150+
NEXT_ARG();
1151+
1152+
if (!REQ_ARGS(2))
1153+
return -1;
1154+
1155+
fd = prog_parse_fd(&argc, &argv);
1156+
if (fd < 0)
1157+
return -1;
1158+
1159+
return prog_tracelog_stream(fd, mode);
1160+
}
1161+
11161162
static int check_single_stdin(char *file_data_in, char *file_ctx_in)
11171163
{
11181164
if (file_data_in && file_ctx_in &&
@@ -2493,6 +2539,7 @@ static int do_help(int argc, char **argv)
24932539
" [repeat N]\n"
24942540
" %1$s %2$s profile PROG [duration DURATION] METRICs\n"
24952541
" %1$s %2$s tracelog\n"
2542+
" %1$s %2$s tracelog { stdout | stderr } PROG\n"
24962543
" %1$s %2$s help\n"
24972544
"\n"
24982545
" " HELP_SPEC_MAP "\n"
@@ -2532,7 +2579,7 @@ static const struct cmd cmds[] = {
25322579
{ "loadall", do_loadall },
25332580
{ "attach", do_attach },
25342581
{ "detach", do_detach },
2535-
{ "tracelog", do_tracelog },
2582+
{ "tracelog", do_tracelog_any },
25362583
{ "run", do_run },
25372584
{ "profile", do_profile },
25382585
{ 0 }

0 commit comments

Comments
 (0)