diff --git a/libbpf-tools/opensnoop.bpf.c b/libbpf-tools/opensnoop.bpf.c index f38ea979db48..64d931a8ff7e 100644 --- a/libbpf-tools/opensnoop.bpf.c +++ b/libbpf-tools/opensnoop.bpf.c @@ -155,13 +155,18 @@ int trace_exit(struct syscall_trace_exit* ctx) if (full_path && eventp->fname[0] != '/') { int depth; struct task_struct *task; - struct dentry *dentry, *parent_dentry; + struct dentry *dentry, *parent_dentry, *mnt_root; + struct vfsmount *vfsmnt; + struct mount *mnt; size_t filepart_length; - void *payload = eventp->fname; + char *payload = eventp->fname; task = (struct task_struct *)bpf_get_current_task_btf(); dentry = BPF_CORE_READ(task, fs, pwd.dentry); + vfsmnt = BPF_CORE_READ(task, fs, pwd.mnt); + mnt = container_of(vfsmnt, struct mount, mnt); + mnt_root = BPF_CORE_READ(vfsmnt, mnt_root); for (depth = 1, payload += NAME_MAX; depth < MAX_PATH_DEPTH; depth++) { filepart_length = @@ -173,13 +178,32 @@ int trace_exit(struct syscall_trace_exit* ctx) break; } - parent_dentry = BPF_CORE_READ(dentry, d_parent); - if (dentry == parent_dentry) - break; - if (filepart_length > NAME_MAX) break; + parent_dentry = BPF_CORE_READ(dentry, d_parent); + + if (dentry == parent_dentry || dentry == mnt_root) { + struct mount *mnt_parent; + mnt_parent = BPF_CORE_READ(mnt, mnt_parent); + + if (mnt != mnt_parent) { + dentry = BPF_CORE_READ(mnt, mnt_mountpoint); + + mnt = mnt_parent; + vfsmnt = &mnt->mnt; + + mnt_root = BPF_CORE_READ(vfsmnt, mnt_root); + + eventp->path_depth++; + payload += NAME_MAX; + continue; + } else { + /* Real root directory */ + break; + } + } + payload += NAME_MAX; dentry = parent_dentry; diff --git a/libbpf-tools/opensnoop.c b/libbpf-tools/opensnoop.c index 49d54b94a020..b8cd301bcfea 100644 --- a/libbpf-tools/opensnoop.c +++ b/libbpf-tools/opensnoop.c @@ -268,7 +268,16 @@ int handle_event(void *ctx, void *data, size_t data_sz) sps_cnt += 9; } if (env.full_path) { - for (int depth = e.path_depth; depth >= 0; depth--) + for (int depth = e.path_depth; depth >= 0; depth--) { + char *fname = (char *)&e.fname[NAME_MAX * depth]; + + /** + * If it is a mount point, there will be a '/', because + * the '/' will be added below, so just skip this '/'. + */ + if (fname[0] == '/' && fname[1] == '\0') + continue; + /** * 1. If the file/path name starts with '/', do not * print the '/' prefix. @@ -281,7 +290,8 @@ int handle_event(void *ctx, void *data, size_t data_sz) "/\0" + (e.fname[NAME_MAX * depth] == '/' || ((e.get_path_failed || e.path_depth == MAX_PATH_DEPTH - 1) && depth == e.path_depth)), - (char *)&e.fname[NAME_MAX * depth]); + fname); + } printf("\n"); } else printf("%s\n", e.fname);