xref: /aosp_15_r20/external/bcc/tools/old/filelife.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports
3*387f9dfdSAndroid Build Coastguard Worker#
4*387f9dfdSAndroid Build Coastguard Worker# filelife    Trace the lifespan of short-lived files.
5*387f9dfdSAndroid Build Coastguard Worker#             For Linux, uses BCC, eBPF. Embedded C.
6*387f9dfdSAndroid Build Coastguard Worker#
7*387f9dfdSAndroid Build Coastguard Worker# This traces the creation and deletion of files, providing information
8*387f9dfdSAndroid Build Coastguard Worker# on who deleted the file, the file age, and the file name. The intent is to
9*387f9dfdSAndroid Build Coastguard Worker# provide information on short-lived files, for debugging or performance
10*387f9dfdSAndroid Build Coastguard Worker# analysis.
11*387f9dfdSAndroid Build Coastguard Worker#
12*387f9dfdSAndroid Build Coastguard Worker# USAGE: filelife [-h] [-p PID]
13*387f9dfdSAndroid Build Coastguard Worker#
14*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc.
15*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
16*387f9dfdSAndroid Build Coastguard Worker#
17*387f9dfdSAndroid Build Coastguard Worker# 08-Feb-2015   Brendan Gregg   Created this.
18*387f9dfdSAndroid Build Coastguard Worker
19*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
20*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
21*387f9dfdSAndroid Build Coastguard Workerimport argparse
22*387f9dfdSAndroid Build Coastguard Workerfrom time import strftime
23*387f9dfdSAndroid Build Coastguard Worker
24*387f9dfdSAndroid Build Coastguard Worker# arguments
25*387f9dfdSAndroid Build Coastguard Workerexamples = """examples:
26*387f9dfdSAndroid Build Coastguard Worker    ./filelife           # trace all stat() syscalls
27*387f9dfdSAndroid Build Coastguard Worker    ./filelife -p 181    # only trace PID 181
28*387f9dfdSAndroid Build Coastguard Worker"""
29*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
30*387f9dfdSAndroid Build Coastguard Worker    description="Trace stat() syscalls",
31*387f9dfdSAndroid Build Coastguard Worker    formatter_class=argparse.RawDescriptionHelpFormatter,
32*387f9dfdSAndroid Build Coastguard Worker    epilog=examples)
33*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid",
34*387f9dfdSAndroid Build Coastguard Worker    help="trace this PID only")
35*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
36*387f9dfdSAndroid Build Coastguard Workerdebug = 0
37*387f9dfdSAndroid Build Coastguard Worker
38*387f9dfdSAndroid Build Coastguard Worker# define BPF program
39*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
40*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
41*387f9dfdSAndroid Build Coastguard Worker#include <linux/fs.h>
42*387f9dfdSAndroid Build Coastguard Worker
43*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(birth, struct dentry *);
44*387f9dfdSAndroid Build Coastguard Worker
45*387f9dfdSAndroid Build Coastguard Worker// trace file creation time
46*387f9dfdSAndroid Build Coastguard Workerint trace_create(struct pt_regs *ctx, struct inode *dir, struct dentry *dentry)
47*387f9dfdSAndroid Build Coastguard Worker{
48*387f9dfdSAndroid Build Coastguard Worker    u32 pid = bpf_get_current_pid_tgid();
49*387f9dfdSAndroid Build Coastguard Worker    FILTER
50*387f9dfdSAndroid Build Coastguard Worker
51*387f9dfdSAndroid Build Coastguard Worker    u64 ts = bpf_ktime_get_ns();
52*387f9dfdSAndroid Build Coastguard Worker    birth.update(&dentry, &ts);
53*387f9dfdSAndroid Build Coastguard Worker
54*387f9dfdSAndroid Build Coastguard Worker    return 0;
55*387f9dfdSAndroid Build Coastguard Worker};
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard Worker// trace file deletion and output details
58*387f9dfdSAndroid Build Coastguard Workerint trace_unlink(struct pt_regs *ctx, struct inode *dir, struct dentry *dentry)
59*387f9dfdSAndroid Build Coastguard Worker{
60*387f9dfdSAndroid Build Coastguard Worker    u32 pid = bpf_get_current_pid_tgid();
61*387f9dfdSAndroid Build Coastguard Worker    FILTER
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker    u64 *tsp, delta;
64*387f9dfdSAndroid Build Coastguard Worker    tsp = birth.lookup(&dentry);
65*387f9dfdSAndroid Build Coastguard Worker    if (tsp == 0) {
66*387f9dfdSAndroid Build Coastguard Worker        return 0;   // missed create
67*387f9dfdSAndroid Build Coastguard Worker    }
68*387f9dfdSAndroid Build Coastguard Worker    delta = (bpf_ktime_get_ns() - *tsp) / 1000000;
69*387f9dfdSAndroid Build Coastguard Worker    birth.delete(&dentry);
70*387f9dfdSAndroid Build Coastguard Worker
71*387f9dfdSAndroid Build Coastguard Worker    if (dentry->d_iname[0] == 0)
72*387f9dfdSAndroid Build Coastguard Worker        return 0;
73*387f9dfdSAndroid Build Coastguard Worker
74*387f9dfdSAndroid Build Coastguard Worker    bpf_trace_printk("%d %s\\n", delta, dentry->d_iname);
75*387f9dfdSAndroid Build Coastguard Worker
76*387f9dfdSAndroid Build Coastguard Worker    return 0;
77*387f9dfdSAndroid Build Coastguard Worker}
78*387f9dfdSAndroid Build Coastguard Worker"""
79*387f9dfdSAndroid Build Coastguard Workerif args.pid:
80*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER',
81*387f9dfdSAndroid Build Coastguard Worker        'if (pid != %s) { return 0; }' % args.pid)
82*387f9dfdSAndroid Build Coastguard Workerelse:
83*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER', '')
84*387f9dfdSAndroid Build Coastguard Workerif debug:
85*387f9dfdSAndroid Build Coastguard Worker    print(bpf_text)
86*387f9dfdSAndroid Build Coastguard Worker
87*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
88*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
89*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="vfs_create", fn_name="trace_create")
90*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="vfs_unlink", fn_name="trace_unlink")
91*387f9dfdSAndroid Build Coastguard Worker
92*387f9dfdSAndroid Build Coastguard Worker# header
93*387f9dfdSAndroid Build Coastguard Workerprint("%-8s %-6s %-16s %-7s %s" % ("TIME", "PID", "COMM", "AGE(s)", "FILE"))
94*387f9dfdSAndroid Build Coastguard Worker
95*387f9dfdSAndroid Build Coastguard Workerstart_ts = 0
96*387f9dfdSAndroid Build Coastguard Worker
97*387f9dfdSAndroid Build Coastguard Worker# format output
98*387f9dfdSAndroid Build Coastguard Workerwhile 1:
99*387f9dfdSAndroid Build Coastguard Worker    (task, pid, cpu, flags, ts, msg) = b.trace_fields()
100*387f9dfdSAndroid Build Coastguard Worker    (delta, filename) = msg.split(" ", 1)
101*387f9dfdSAndroid Build Coastguard Worker
102*387f9dfdSAndroid Build Coastguard Worker    # print columns
103*387f9dfdSAndroid Build Coastguard Worker    print("%-8s %-6d %-16s %-7.2f %s" % (strftime("%H:%M:%S"), pid, task,
104*387f9dfdSAndroid Build Coastguard Worker        float(delta) / 1000, filename))
105