Skip to content

Commit

Permalink
tools/filegone: Support rename/unlink failed situation
Browse files Browse the repository at this point in the history
When deleting or renaming a file or folder for which you do not have
permissions, vfs_unlink/rename will fail and we should skip the failure.

Reproducing the problem:

  Terminal 1:

    $ sudo ./filegone.py

  Terminal 2, failed 1,2,3,4:

    $ sudo touch /etc/a.txt
    $ sudo mkdir /etc/a.dir
    $ # Permission deny
    $ rm -f /etc/a.txt
    rm: cannot remove '/etc/a.txt': Permission denied               << 1
    $ mv /etc/a.txt /etc/b.txt
    mv: cannot move '/etc/a.txt' to '/etc/b.txt': Permission denied << 2
    $ rmdir /etc/a.dir
    rmdir: failed to remove '/etc/a.dir': Permission denied         << 3
    $ mv /etc/a.dir /etc/b.dir
    mv: cannot move '/etc/a.dir' to '/etc/b.dir': Permission denied << 4
    $ # Success gone
    $ sudo mv /etc/a.txt /etc/b.txt
    $ sudo rm /etc/b.txt
    $ sudo mv /etc/a.dir /etc/b.dir
    $ sudo rmdir /etc/b.dir

  Then terminal 1, wrong statistic 1,2,3,4:

    $ sudo ./filegone.py
    TIME     PID     COMM             ACTION FILE
    13:32:11 10767   rm               DELETE a.txt                  << 1
    13:32:11 10768   mv               RENAME a.txt > b.txt          << 2
    13:32:11 10769   rmdir            DELETE a.dir                  << 3
    13:32:11 10770   mv               RENAME a.dir > b.dir          << 4
    13:32:11 10772   mv               RENAME a.txt > b.txt
    13:32:11 10774   rm               DELETE b.txt
    13:32:11 10776   mv               RENAME a.dir > b.dir
    13:32:11 10778   rmdir            DELETE b.dir

This commit fix the statistical error above, the result:

    $ sudo ./filegone.py
    TIME     PID     COMM             ACTION FILE
    13:36:52 10937   mv               RENAME a.txt > b.txt
    13:36:52 10939   rm               DELETE b.txt
    13:36:52 10941   mv               RENAME a.dir > b.dir
    13:36:52 10943   rmdir            DELETE b.dir

Signed-off-by: Rong Tao <[email protected]>
  • Loading branch information
Rtoax authored and yonghong-song committed Nov 7, 2023
1 parent 076ccf0 commit 130c81d
Showing 1 changed file with 33 additions and 4 deletions.
37 changes: 33 additions & 4 deletions tools/filegone.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#
# 08-Nov-2022 Curu. modified from filelife
# 19-Nov-2022 Rong Tao Check btf struct field instead of KERNEL_VERSION macro.
# 05-Nov-2023 Rong Tao Support rename/unlink failed situation.

from __future__ import print_function
from bcc import BPF
Expand Down Expand Up @@ -47,11 +48,14 @@
};
BPF_PERF_OUTPUT(events);
BPF_HASH(currdata, u32, struct data_t);
// trace file deletion and output details
TRACE_VFS_UNLINK_FUNC
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = (u32)pid_tgid;
FILTER
Expand All @@ -65,15 +69,17 @@
data.action = 'D';
bpf_probe_read(&data.fname, sizeof(data.fname), d_name.name);
events.perf_submit(ctx, &data, sizeof(data));
currdata.update(&tid, &data);
return 0;
}
// trace file rename
TRACE_VFS_RENAME_FUNC
u32 pid = bpf_get_current_pid_tgid() >> 32;
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = (u32)pid_tgid;
FILTER
Expand All @@ -88,10 +94,30 @@
data.action = 'R';
bpf_probe_read(&data.fname, sizeof(data.fname), s_name.name);
bpf_probe_read(&data.fname2, sizeof(data.fname), d_name.name);
events.perf_submit(ctx, &data, sizeof(data));
currdata.update(&tid, &data);
return 0;
}
int trace_return(struct pt_regs *ctx)
{
struct data_t *data;
u32 tid = (u32)bpf_get_current_pid_tgid();
int ret = PT_REGS_RC(ctx);
data = currdata.lookup(&tid);
if (data == 0)
return 0;
currdata.delete(&tid);
/* Skip failed */
if (ret)
return 0;
events.perf_submit(ctx, data, sizeof(*data));
return 0;
}
"""

bpf_vfs_rename_text_old="""
Expand Down Expand Up @@ -150,6 +176,9 @@ def action2str(action):
b.attach_kprobe(event="vfs_unlink", fn_name="trace_unlink")
b.attach_kprobe(event="vfs_rmdir", fn_name="trace_unlink")
b.attach_kprobe(event="vfs_rename", fn_name="trace_rename")
b.attach_kretprobe(event="vfs_unlink", fn_name="trace_return")
b.attach_kretprobe(event="vfs_rmdir", fn_name="trace_return")
b.attach_kretprobe(event="vfs_rename", fn_name="trace_return")

# header
print("%-8s %-7s %-16s %6s %s" % ("TIME", "PID", "COMM", "ACTION", "FILE"))
Expand Down

0 comments on commit 130c81d

Please sign in to comment.