diff options
author | Daniel Borkmann <daniel@iogearbox.net> | 2018-12-18 14:47:18 +0100 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-12-18 14:47:19 +0100 |
commit | a137401d85129953a1713d443216eb6b1074c12e (patch) | |
tree | d70e6aabc236cea038bcfdba2be647dde7298764 | |
parent | 0d7410ea6efcdfda56773999f692bbd5d4e4bc00 (diff) | |
parent | 33221307c3f993500a9cfc6900811058c6bfc152 (diff) | |
download | linux-a137401d85129953a1713d443216eb6b1074c12e.tar.bz2 |
Merge branch 'bpf-bpftool-mount-tracefs'
Quentin Monnet says:
====================
This series focus on mounting (or not mounting) tracefs with bpftool.
First patch makes bpftool attempt to mount tracefs if tracefs is not
found when running "bpftool prog tracelog".
Second patch adds an option to bpftool to prevent it from attempting
to mount any file system (tracefs or bpffs), in case this behaviour
is undesirable for some users.
====================
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool-map.rst | 4 | ||||
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool-prog.rst | 4 | ||||
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool.rst | 4 | ||||
-rw-r--r-- | tools/bpf/bpftool/common.c | 31 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.c | 8 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.h | 6 | ||||
-rw-r--r-- | tools/bpf/bpftool/tracelog.c | 23 |
7 files changed, 66 insertions, 14 deletions
diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst index 3221be1b9ccc..64b001b4f777 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-map.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst @@ -128,6 +128,10 @@ OPTIONS -f, --bpffs Show file names of pinned maps. + -n, --nomount + Do not automatically attempt to mount any virtual file system + (such as tracefs or BPF virtual file system) when necessary. + EXAMPLES ======== **# bpftool map show** diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 53920ffc48dd..58c8369b77dd 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -161,6 +161,10 @@ OPTIONS -m, --mapcompat Allow loading maps with unknown map definitions. + -n, --nomount + Do not automatically attempt to mount any virtual file system + (such as tracefs or BPF virtual file system) when necessary. + EXAMPLES ======== **# bpftool prog show** diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst index 129b7a9c0f9b..e1677e81ed59 100644 --- a/tools/bpf/bpftool/Documentation/bpftool.rst +++ b/tools/bpf/bpftool/Documentation/bpftool.rst @@ -60,6 +60,10 @@ OPTIONS -m, --mapcompat Allow loading maps with unknown map definitions. + -n, --nomount + Do not automatically attempt to mount any virtual file system + (such as tracefs or BPF virtual file system) when necessary. + SEE ALSO ======== diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 24582e8a96fb..897483457bf0 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -76,7 +76,8 @@ void set_max_rlimit(void) setrlimit(RLIMIT_MEMLOCK, &rinf); } -static int mnt_bpffs(const char *target, char *buff, size_t bufflen) +static int +mnt_fs(const char *target, const char *type, char *buff, size_t bufflen) { bool bind_done = false; @@ -98,15 +99,29 @@ static int mnt_bpffs(const char *target, char *buff, size_t bufflen) bind_done = true; } - if (mount("bpf", target, "bpf", 0, "mode=0700")) { - snprintf(buff, bufflen, "mount -t bpf bpf %s failed: %s", - target, strerror(errno)); + if (mount(type, target, type, 0, "mode=0700")) { + snprintf(buff, bufflen, "mount -t %s %s %s failed: %s", + type, type, target, strerror(errno)); return -1; } return 0; } +int mount_tracefs(const char *target) +{ + char err_str[ERR_MAX_LEN]; + int err; + + err = mnt_fs(target, "tracefs", err_str, ERR_MAX_LEN); + if (err) { + err_str[ERR_MAX_LEN - 1] = '\0'; + p_err("can't mount tracefs: %s", err_str); + } + + return err; +} + int open_obj_pinned(char *path, bool quiet) { int fd; @@ -162,7 +177,13 @@ int mount_bpffs_for_pin(const char *name) /* nothing to do if already mounted */ goto out_free; - err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); + if (block_mount) { + p_err("no BPF file system found, not mounting it due to --nomount option"); + err = -1; + goto out_free; + } + + err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN); if (err) { err_str[ERR_MAX_LEN - 1] = '\0'; p_err("can't mount BPF file system to pin the object (%s): %s", diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index 9e657e7d5172..f44a1c2c4ea0 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -24,6 +24,7 @@ json_writer_t *json_wtr; bool pretty_output; bool json_output; bool show_pinned; +bool block_mount; int bpf_flags; struct pinned_obj_table prog_table; struct pinned_obj_table map_table; @@ -313,6 +314,7 @@ int main(int argc, char **argv) { "version", no_argument, NULL, 'V' }, { "bpffs", no_argument, NULL, 'f' }, { "mapcompat", no_argument, NULL, 'm' }, + { "nomount", no_argument, NULL, 'n' }, { 0 } }; int opt, ret; @@ -321,13 +323,14 @@ int main(int argc, char **argv) pretty_output = false; json_output = false; show_pinned = false; + block_mount = false; bin_name = argv[0]; hash_init(prog_table.table); hash_init(map_table.table); opterr = 0; - while ((opt = getopt_long(argc, argv, "Vhpjfm", + while ((opt = getopt_long(argc, argv, "Vhpjfmn", options, NULL)) >= 0) { switch (opt) { case 'V': @@ -354,6 +357,9 @@ int main(int argc, char **argv) case 'm': bpf_flags = MAPS_RELAX_COMPAT; break; + case 'n': + block_mount = true; + break; default: p_err("unrecognized option '%s'", argv[optind - 1]); if (json_output) diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 9487345b04a7..052c91d4dc55 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -44,7 +44,8 @@ #define HELP_SPEC_PROGRAM \ "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }" #define HELP_SPEC_OPTIONS \ - "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} | {-m|--mapcompat}" + "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n" \ + "\t {-m|--mapcompat} | {-n|--nomount} }" #define HELP_SPEC_MAP \ "MAP := { id MAP_ID | pinned FILE }" @@ -85,6 +86,7 @@ extern const char *bin_name; extern json_writer_t *json_wtr; extern bool json_output; extern bool show_pinned; +extern bool block_mount; extern int bpf_flags; extern struct pinned_obj_table prog_table; extern struct pinned_obj_table map_table; @@ -98,6 +100,8 @@ void usage(void) __noreturn; void set_max_rlimit(void); +int mount_tracefs(const char *target); + struct pinned_obj_table { DECLARE_HASHTABLE(table, 16); }; diff --git a/tools/bpf/bpftool/tracelog.c b/tools/bpf/bpftool/tracelog.c index 1fa8e513f590..e80a5c79b38f 100644 --- a/tools/bpf/bpftool/tracelog.c +++ b/tools/bpf/bpftool/tracelog.c @@ -54,7 +54,7 @@ find_tracefs_mnt_single(unsigned long magic, char *mnt, const char *mntpt) return true; } -static bool find_tracefs_pipe(char *mnt) +static bool get_tracefs_pipe(char *mnt) { static const char * const known_mnts[] = { "/sys/kernel/debug/tracing", @@ -88,7 +88,20 @@ static bool find_tracefs_pipe(char *mnt) fclose(fp); /* The string from fscanf() might be truncated, check mnt is valid */ - if (!found || validate_tracefs_mnt(mnt, TRACEFS_MAGIC)) + if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC)) + goto exit_found; + + if (block_mount) + return false; + + p_info("could not find tracefs, attempting to mount it now"); + /* Most of the time, tracefs is automatically mounted by debugfs at + * /sys/kernel/debug/tracing when we try to access it. If we could not + * find it, it is likely that debugfs is not mounted. Let's give one + * attempt at mounting just tracefs at /sys/kernel/tracing. + */ + strcpy(mnt, known_mnts[1]); + if (mount_tracefs(mnt)) return false; exit_found: @@ -115,17 +128,13 @@ int do_tracelog(int argc, char **argv) .sa_handler = exit_tracelog }; char trace_pipe[PATH_MAX]; - bool found_trace_pipe; size_t buff_len = 0; if (json_output) jsonw_start_array(json_wtr); - found_trace_pipe = find_tracefs_pipe(trace_pipe); - if (!found_trace_pipe) { - p_err("could not find trace pipe, tracefs not mounted?"); + if (!get_tracefs_pipe(trace_pipe)) return -1; - } trace_pipe_fd = fopen(trace_pipe, "r"); if (!trace_pipe_fd) { |