diff options
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
| -rw-r--r-- | tools/bpf/bpftool/prog.c | 49 | 
1 files changed, 48 insertions, 1 deletions
| diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index deeaa5c1ed7d..9722d841abc0 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -1113,6 +1113,52 @@ static int do_detach(int argc, char **argv)  	return 0;  } +enum prog_tracelog_mode { +	TRACE_STDOUT, +	TRACE_STDERR, +}; + +static int +prog_tracelog_stream(int prog_fd, enum prog_tracelog_mode mode) +{ +	FILE *file = mode == TRACE_STDOUT ? stdout : stderr; +	int stream_id = mode == TRACE_STDOUT ? 1 : 2; +	char buf[512]; +	int ret; + +	ret = 0; +	do { +		ret = bpf_prog_stream_read(prog_fd, stream_id, buf, sizeof(buf), NULL); +		if (ret > 0) +			fwrite(buf, sizeof(buf[0]), ret, file); +	} while (ret > 0); + +	fflush(file); +	return ret ? -1 : 0; +} + +static int do_tracelog_any(int argc, char **argv) +{ +	enum prog_tracelog_mode mode; +	int fd; + +	if (argc == 0) +		return do_tracelog(argc, argv); +	if (!is_prefix(*argv, "stdout") && !is_prefix(*argv, "stderr")) +		usage(); +	mode = is_prefix(*argv, "stdout") ? TRACE_STDOUT : TRACE_STDERR; +	NEXT_ARG(); + +	if (!REQ_ARGS(2)) +		return -1; + +	fd = prog_parse_fd(&argc, &argv); +	if (fd < 0) +		return -1; + +	return prog_tracelog_stream(fd, mode); +} +  static int check_single_stdin(char *file_data_in, char *file_ctx_in)  {  	if (file_data_in && file_ctx_in && @@ -2493,6 +2539,7 @@ static int do_help(int argc, char **argv)  		"                         [repeat N]\n"  		"       %1$s %2$s profile PROG [duration DURATION] METRICs\n"  		"       %1$s %2$s tracelog\n" +		"       %1$s %2$s tracelog { stdout | stderr } PROG\n"  		"       %1$s %2$s help\n"  		"\n"  		"       " HELP_SPEC_MAP "\n" @@ -2532,7 +2579,7 @@ static const struct cmd cmds[] = {  	{ "loadall",	do_loadall },  	{ "attach",	do_attach },  	{ "detach",	do_detach }, -	{ "tracelog",	do_tracelog }, +	{ "tracelog",	do_tracelog_any },  	{ "run",	do_run },  	{ "profile",	do_profile },  	{ 0 } | 
