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

bpftool: Support bpffs mountpoint as pin path for prog loadall

Currently, when using prog loadall and the pin path is a bpffs mountpoint,
bpffs will be repeatedly mounted to the parent directory of the bpffs
mountpoint path. For example, a `bpftool prog loadall test.o /sys/fs/bpf`
will trigger this.

Signed-off-by: Pengcheng Yang <yangpc@wangsu.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/1683342439-3677-1-git-send-email-yangpc@wangsu.com

authored by

Pengcheng Yang and committed by
Daniel Borkmann
2a36c26f f04a32b2

+10 -7
+6 -3
tools/bpf/bpftool/common.c
··· 68 68 va_end(ap); 69 69 } 70 70 71 - static bool is_bpffs(char *path) 71 + static bool is_bpffs(const char *path) 72 72 { 73 73 struct statfs st_fs; 74 74 ··· 244 244 return fd; 245 245 } 246 246 247 - int mount_bpffs_for_pin(const char *name) 247 + int mount_bpffs_for_pin(const char *name, bool is_dir) 248 248 { 249 249 char err_str[ERR_MAX_LEN]; 250 250 char *file; 251 251 char *dir; 252 252 int err = 0; 253 + 254 + if (is_dir && is_bpffs(name)) 255 + return err; 253 256 254 257 file = malloc(strlen(name) + 1); 255 258 if (!file) { ··· 289 286 { 290 287 int err; 291 288 292 - err = mount_bpffs_for_pin(name); 289 + err = mount_bpffs_for_pin(name, false); 293 290 if (err) 294 291 return err; 295 292
+1 -1
tools/bpf/bpftool/iter.c
··· 76 76 goto close_obj; 77 77 } 78 78 79 - err = mount_bpffs_for_pin(path); 79 + err = mount_bpffs_for_pin(path, false); 80 80 if (err) 81 81 goto close_link; 82 82
+1 -1
tools/bpf/bpftool/main.h
··· 142 142 char *get_fdinfo(int fd, const char *key); 143 143 int open_obj_pinned(const char *path, bool quiet); 144 144 int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type); 145 - int mount_bpffs_for_pin(const char *name); 145 + int mount_bpffs_for_pin(const char *name, bool is_dir); 146 146 int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(int *, char ***)); 147 147 int do_pin_fd(int fd, const char *name); 148 148
+1 -1
tools/bpf/bpftool/prog.c
··· 1739 1739 goto err_close_obj; 1740 1740 } 1741 1741 1742 - err = mount_bpffs_for_pin(pinfile); 1742 + err = mount_bpffs_for_pin(pinfile, !first_prog_only); 1743 1743 if (err) 1744 1744 goto err_close_obj; 1745 1745
+1 -1
tools/bpf/bpftool/struct_ops.c
··· 509 509 if (argc == 1) 510 510 linkdir = GET_ARG(); 511 511 512 - if (linkdir && mount_bpffs_for_pin(linkdir)) { 512 + if (linkdir && mount_bpffs_for_pin(linkdir, true)) { 513 513 p_err("can't mount bpffs for pinning"); 514 514 return -1; 515 515 }