bcc/tools: use device number and inode number to identify a file
authorHengqi Chen <chenhengqi@outlook.com>
Wed, 28 Jul 2021 15:49:11 +0000 (23:49 +0800)
committeryonghong-song <ys114321@gmail.com>
Mon, 2 Aug 2021 06:27:54 +0000 (23:27 -0700)
Currently, the filetop tool use (tid, filename, type) tuple to
key a file, which is not enough to uniquely identify a file.
A thread write to multi files with the same name would add up to
same value in the map which can be repro by the following command:

$ cat somefile | tee /foo/bar/xxx /fuz/baz/xxx

Let us add device number and inode number to uniquely identify
a file.

Signed-off-by: Hengqi Chen <chenhengqi@outlook.com>
tools/filetop.py

index 17ead81713bee57774cefb85a0056daa0583d62d..9a79a64f0f2291f14af175c9167c092e1afa61a0 100755 (executable)
@@ -65,6 +65,8 @@ bpf_text = """
 
 // the key for the output summary
 struct info_t {
+    unsigned long inode;
+    dev_t dev;
     u32 pid;
     u32 name_len;
     char comm[TASK_COMM_LEN];
@@ -100,7 +102,11 @@ static int do_entry(struct pt_regs *ctx, struct file *file,
         return 0;
 
     // store counts and sizes by pid & file
-    struct info_t info = {.pid = pid};
+    struct info_t info = {
+        .pid = pid,
+        .inode = file->f_inode->i_ino,
+        .dev = file->f_inode->i_rdev,
+    };
     bpf_get_current_comm(&info.comm, sizeof(info.comm));
     info.name_len = d_name.len;
     bpf_probe_read_kernel(&info.name, sizeof(info.name), d_name.name);
@@ -184,7 +190,7 @@ while 1:
         print()
     with open(loadavg) as stats:
         print("%-8s loadavg: %s" % (strftime("%H:%M:%S"), stats.read()))
-    print("%-6s %-16s %-6s %-6s %-7s %-7s %1s %s" % ("TID", "COMM",
+    print("%-7s %-16s %-6s %-6s %-7s %-7s %1s %s" % ("TID", "COMM",
         "READS", "WRITES", "R_Kb", "W_Kb", "T", "FILE"))
 
     # by-TID output
@@ -197,7 +203,7 @@ while 1:
             name = name[:-3] + "..."
 
         # print line
-        print("%-6d %-16s %-6d %-6d %-7d %-7d %1s %s" % (k.pid,
+        print("%-7d %-16s %-6d %-6d %-7d %-7d %1s %s" % (k.pid,
             k.comm.decode('utf-8', 'replace'), v.reads, v.writes,
             v.rbytes / 1024, v.wbytes / 1024,
             k.type.decode('utf-8', 'replace'), name))