Commit 6f1ae8b6 authored by Yonghong Song's avatar Yonghong Song Committed by Alexei Starovoitov

tools/bpf: simplify libbpf API function libbpf_set_print()

Currently, the libbpf API function libbpf_set_print()
takes three function pointer parameters for warning, info
and debug printout respectively.

This patch changes the API to have just one function pointer
parameter and the function pointer has one additional
parameter "debugging level". So if in the future, if
the debug level is increased, the function signature
won't change.
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 9d100a19
...@@ -54,29 +54,26 @@ ...@@ -54,29 +54,26 @@
#define __printf(a, b) __attribute__((format(printf, a, b))) #define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2) __printf(2, 3)
static int __base_pr(const char *format, ...) static int __base_pr(enum libbpf_print_level level, const char *format, ...)
{ {
va_list args; va_list args;
int err; int err;
if (level == LIBBPF_DEBUG)
return 0;
va_start(args, format); va_start(args, format);
err = vfprintf(stderr, format, args); err = vfprintf(stderr, format, args);
va_end(args); va_end(args);
return err; return err;
} }
static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; static __printf(2, 3) libbpf_print_fn_t __libbpf_pr = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_debug;
void libbpf_set_print(libbpf_print_fn_t warn, void libbpf_set_print(libbpf_print_fn_t fn)
libbpf_print_fn_t info,
libbpf_print_fn_t debug)
{ {
__pr_warning = warn; __libbpf_pr = fn;
__pr_info = info;
__pr_debug = debug;
} }
__printf(2, 3) __printf(2, 3)
...@@ -84,17 +81,11 @@ void libbpf_print(enum libbpf_print_level level, const char *format, ...) ...@@ -84,17 +81,11 @@ void libbpf_print(enum libbpf_print_level level, const char *format, ...)
{ {
va_list args; va_list args;
if (!__libbpf_pr)
return;
va_start(args, format); va_start(args, format);
if (level == LIBBPF_WARN) { __libbpf_pr(level, format, args);
if (__pr_warning)
__pr_warning(format, args);
} else if (level == LIBBPF_INFO) {
if (__pr_info)
__pr_info(format, args);
} else {
if (__pr_debug)
__pr_debug(format, args);
}
va_end(args); va_end(args);
} }
......
...@@ -53,17 +53,11 @@ enum libbpf_print_level { ...@@ -53,17 +53,11 @@ enum libbpf_print_level {
LIBBPF_DEBUG, LIBBPF_DEBUG,
}; };
/* typedef int (*libbpf_print_fn_t)(enum libbpf_print_level level,
* __printf is defined in include/linux/compiler-gcc.h. However, const char *, ...)
* it would be better if libbpf.h didn't depend on Linux header files. __attribute__((format(printf, 2, 3)));
* So instead of __printf, here we use gcc attribute directly.
*/
typedef int (*libbpf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2)));
LIBBPF_API void libbpf_set_print(libbpf_print_fn_t warn, LIBBPF_API void libbpf_set_print(libbpf_print_fn_t fn);
libbpf_print_fn_t info,
libbpf_print_fn_t debug);
/* Hide internal to user */ /* Hide internal to user */
struct bpf_object; struct bpf_object;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/* libbpf.h */ /* libbpf.h */
libbpf_set_print(NULL, NULL, NULL); libbpf_set_print(NULL);
/* bpf.h */ /* bpf.h */
bpf_prog_get_fd_by_id(0); bpf_prog_get_fd_by_id(0);
......
...@@ -24,21 +24,17 @@ ...@@ -24,21 +24,17 @@
#include "llvm-utils.h" #include "llvm-utils.h"
#include "c++/clang-c.h" #include "c++/clang-c.h"
#define DEFINE_PRINT_FN(name, level) \ static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)),
static int libbpf_##name(const char *fmt, ...) \ const char *fmt, ...)
{ \ {
va_list args; \ va_list args;
int ret; \ int ret;
\
va_start(args, fmt); \
ret = veprintf(level, verbose, pr_fmt(fmt), args);\
va_end(args); \
return ret; \
}
DEFINE_PRINT_FN(warning, 1) va_start(args, fmt);
DEFINE_PRINT_FN(info, 1) ret = veprintf(1, verbose, pr_fmt(fmt), args);
DEFINE_PRINT_FN(debug, 1) va_end(args);
return ret;
}
struct bpf_prog_priv { struct bpf_prog_priv {
bool is_tp; bool is_tp;
...@@ -59,9 +55,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) ...@@ -59,9 +55,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
struct bpf_object *obj; struct bpf_object *obj;
if (!libbpf_initialized) { if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning, libbpf_set_print(libbpf_perf_print);
libbpf_info,
libbpf_debug);
libbpf_initialized = true; libbpf_initialized = true;
} }
...@@ -79,9 +73,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source) ...@@ -79,9 +73,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
struct bpf_object *obj; struct bpf_object *obj;
if (!libbpf_initialized) { if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning, libbpf_set_print(libbpf_perf_print);
libbpf_info,
libbpf_debug);
libbpf_initialized = true; libbpf_initialized = true;
} }
......
...@@ -54,8 +54,9 @@ static int count_result(int err) ...@@ -54,8 +54,9 @@ static int count_result(int err)
#define __printf(a, b) __attribute__((format(printf, a, b))) #define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2) __printf(2, 3)
static int __base_pr(const char *format, ...) static int __base_pr(enum libbpf_print_level level __attribute__((unused)),
const char *format, ...)
{ {
va_list args; va_list args;
int err; int err;
...@@ -5650,7 +5651,7 @@ int main(int argc, char **argv) ...@@ -5650,7 +5651,7 @@ int main(int argc, char **argv)
return err; return err;
if (args.always_log) if (args.always_log)
libbpf_set_print(__base_pr, __base_pr, __base_pr); libbpf_set_print(__base_pr);
if (args.raw_test) if (args.raw_test)
err |= test_raw(); err |= test_raw();
......
...@@ -34,23 +34,22 @@ static void usage(char *argv[]) ...@@ -34,23 +34,22 @@ static void usage(char *argv[])
printf("\n"); printf("\n");
} }
#define DEFINE_PRINT_FN(name, enabled) \ static bool debug = 0;
static int libbpf_##name(const char *fmt, ...) \ static int libbpf_debug_print(enum libbpf_print_level level,
{ \ const char *fmt, ...)
va_list args; \ {
int ret; \ va_list args;
\ int ret;
va_start(args, fmt); \
if (enabled) { \ if (level == LIBBPF_DEBUG && !debug)
fprintf(stderr, "[" #name "] "); \ return 0;
ret = vfprintf(stderr, fmt, args); \
} \ va_start(args, fmt);
va_end(args); \ fprintf(stderr, "[%d] ", level);
return ret; \ ret = vfprintf(stderr, fmt, args);
va_end(args);
return ret;
} }
DEFINE_PRINT_FN(warning, 1)
DEFINE_PRINT_FN(info, 1)
DEFINE_PRINT_FN(debug, 1)
#define EXIT_FAIL_LIBBPF EXIT_FAILURE #define EXIT_FAIL_LIBBPF EXIT_FAILURE
#define EXIT_FAIL_OPTION 2 #define EXIT_FAIL_OPTION 2
...@@ -120,15 +119,14 @@ int main(int argc, char **argv) ...@@ -120,15 +119,14 @@ int main(int argc, char **argv)
int longindex = 0; int longindex = 0;
int opt; int opt;
libbpf_set_print(libbpf_warning, libbpf_info, NULL); libbpf_set_print(libbpf_debug_print);
/* Parse commands line args */ /* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hDq", while ((opt = getopt_long(argc, argv, "hDq",
long_options, &longindex)) != -1) { long_options, &longindex)) != -1) {
switch (opt) { switch (opt) {
case 'D': case 'D':
libbpf_set_print(libbpf_warning, libbpf_info, debug = 1;
libbpf_debug);
break; break;
case 'q': /* Use in scripting mode */ case 'q': /* Use in scripting mode */
verbose = 0; verbose = 0;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <time.h> #include <time.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -1783,6 +1784,21 @@ static void test_task_fd_query_tp(void) ...@@ -1783,6 +1784,21 @@ static void test_task_fd_query_tp(void)
"sys_enter_read"); "sys_enter_read");
} }
static int libbpf_debug_print(enum libbpf_print_level level,
const char *format, ...)
{
va_list args;
int ret;
if (level == LIBBPF_DEBUG)
return 0;
va_start(args, format);
ret = vfprintf(stderr, format, args);
va_end(args);
return ret;
}
static void test_reference_tracking() static void test_reference_tracking()
{ {
const char *file = "./test_sk_lookup_kern.o"; const char *file = "./test_sk_lookup_kern.o";
...@@ -1809,9 +1825,9 @@ static void test_reference_tracking() ...@@ -1809,9 +1825,9 @@ static void test_reference_tracking()
/* Expect verifier failure if test name has 'fail' */ /* Expect verifier failure if test name has 'fail' */
if (strstr(title, "fail") != NULL) { if (strstr(title, "fail") != NULL) {
libbpf_set_print(NULL, NULL, NULL); libbpf_set_print(NULL);
err = !bpf_program__load(prog, "GPL", 0); err = !bpf_program__load(prog, "GPL", 0);
libbpf_set_print(printf, printf, NULL); libbpf_set_print(libbpf_debug_print);
} else { } else {
err = bpf_program__load(prog, "GPL", 0); err = bpf_program__load(prog, "GPL", 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment