Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools: bpftool: attempt to mount tracefs if required for tracelog cmd

As a follow-up to commit 30da46b5dc3a ("tools: bpftool: add a command to
dump the trace pipe"), attempt to mount the tracefs virtual file system
if it is not detected on the system before trying to dump content of the
tracing pipe on an invocation of "bpftool prog tracelog".

Usually, tracefs in automatically mounted by debugfs when the user tries
to access it (e.g. "ls /sys/kernel/debug/tracing" mounts the tracefs).
So if we failed to find it, it is probably that debugfs is not here
either. Therefore, we just attempt a single mount, at a location that
does not involve debugfs: /sys/kernel/tracing.

Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>

authored by

Quentin Monnet and committed by
Daniel Borkmann
be3245e2 0d7410ea

+35 -12
+20 -5
tools/bpf/bpftool/common.c
··· 76 76 setrlimit(RLIMIT_MEMLOCK, &rinf); 77 77 } 78 78 79 - static int mnt_bpffs(const char *target, char *buff, size_t bufflen) 79 + static int 80 + mnt_fs(const char *target, const char *type, char *buff, size_t bufflen) 80 81 { 81 82 bool bind_done = false; 82 83 ··· 99 98 bind_done = true; 100 99 } 101 100 102 - if (mount("bpf", target, "bpf", 0, "mode=0700")) { 103 - snprintf(buff, bufflen, "mount -t bpf bpf %s failed: %s", 104 - target, strerror(errno)); 101 + if (mount(type, target, type, 0, "mode=0700")) { 102 + snprintf(buff, bufflen, "mount -t %s %s %s failed: %s", 103 + type, type, target, strerror(errno)); 105 104 return -1; 106 105 } 107 106 108 107 return 0; 108 + } 109 + 110 + int mount_tracefs(const char *target) 111 + { 112 + char err_str[ERR_MAX_LEN]; 113 + int err; 114 + 115 + err = mnt_fs(target, "tracefs", err_str, ERR_MAX_LEN); 116 + if (err) { 117 + err_str[ERR_MAX_LEN - 1] = '\0'; 118 + p_err("can't mount tracefs: %s", err_str); 119 + } 120 + 121 + return err; 109 122 } 110 123 111 124 int open_obj_pinned(char *path, bool quiet) ··· 177 162 /* nothing to do if already mounted */ 178 163 goto out_free; 179 164 180 - err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); 165 + err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN); 181 166 if (err) { 182 167 err_str[ERR_MAX_LEN - 1] = '\0'; 183 168 p_err("can't mount BPF file system to pin the object (%s): %s",
+2
tools/bpf/bpftool/main.h
··· 98 98 99 99 void set_max_rlimit(void); 100 100 101 + int mount_tracefs(const char *target); 102 + 101 103 struct pinned_obj_table { 102 104 DECLARE_HASHTABLE(table, 16); 103 105 };
+13 -7
tools/bpf/bpftool/tracelog.c
··· 54 54 return true; 55 55 } 56 56 57 - static bool find_tracefs_pipe(char *mnt) 57 + static bool get_tracefs_pipe(char *mnt) 58 58 { 59 59 static const char * const known_mnts[] = { 60 60 "/sys/kernel/debug/tracing", ··· 88 88 fclose(fp); 89 89 90 90 /* The string from fscanf() might be truncated, check mnt is valid */ 91 - if (!found || validate_tracefs_mnt(mnt, TRACEFS_MAGIC)) 91 + if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC)) 92 + goto exit_found; 93 + 94 + p_info("could not find tracefs, attempting to mount it now"); 95 + /* Most of the time, tracefs is automatically mounted by debugfs at 96 + * /sys/kernel/debug/tracing when we try to access it. If we could not 97 + * find it, it is likely that debugfs is not mounted. Let's give one 98 + * attempt at mounting just tracefs at /sys/kernel/tracing. 99 + */ 100 + strcpy(mnt, known_mnts[1]); 101 + if (mount_tracefs(mnt)) 92 102 return false; 93 103 94 104 exit_found: ··· 125 115 .sa_handler = exit_tracelog 126 116 }; 127 117 char trace_pipe[PATH_MAX]; 128 - bool found_trace_pipe; 129 118 size_t buff_len = 0; 130 119 131 120 if (json_output) 132 121 jsonw_start_array(json_wtr); 133 122 134 - found_trace_pipe = find_tracefs_pipe(trace_pipe); 135 - if (!found_trace_pipe) { 136 - p_err("could not find trace pipe, tracefs not mounted?"); 123 + if (!get_tracefs_pipe(trace_pipe)) 137 124 return -1; 138 - } 139 125 140 126 trace_pipe_fd = fopen(trace_pipe, "r"); 141 127 if (!trace_pipe_fd) {