Skip to content

Commit 021f190

Browse files
author
abushwang
committed
tools/filetop: Add --recursive for directory filter
Signed-off-by: abushwang <[email protected]>
1 parent 2b73f76 commit 021f190

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

tools/filetop.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@
2424

2525
# arguments
2626
examples = """examples:
27-
./filetop # file I/O top, 1 second refresh
28-
./filetop -C # don't clear the screen
29-
./filetop -p 181 # PID 181 only
30-
./filetop -d /home/user # trace files in /home/user directory only
31-
./filetop 5 # 5 second summaries
32-
./filetop 5 10 # 5 second summaries, 10 times only
33-
./filetop 5 --read-only # 5 second summaries, only read operations traced
34-
./filetop 5 --write-only # 5 second summaries, only write operations traced
27+
./filetop # file I/O top, 1 second refresh
28+
./filetop -C # don't clear the screen
29+
./filetop -p 181 # PID 181 only
30+
./filetop -d /home/user # trace files in /home/user directory only
31+
./filetop -d /home/user -R # trace files in /home/user and subdirectories
32+
./filetop 5 # 5 second summaries
33+
./filetop 5 10 # 5 second summaries, 10 times only
34+
./filetop 5 --read-only # 5 second summaries, only read operations traced
35+
./filetop 5 --write-only # 5 second summaries, only write operations traced
3536
"""
3637
parser = argparse.ArgumentParser(
3738
description="File reads and writes by process",
@@ -60,6 +61,8 @@
6061
help=argparse.SUPPRESS)
6162
parser.add_argument("-d", "--directory", type=str,
6263
help="trace this directory only")
64+
parser.add_argument("-R", "--recursive", action="store_true",
65+
help="when used with -d, also trace files in subdirectories")
6366

6467
args = parser.parse_args()
6568
interval = int(args.interval)
@@ -180,12 +183,25 @@
180183
if args.directory:
181184
try:
182185
directory_inode = os.lstat(args.directory)[stat.ST_INO]
183-
print(f'Tracing directory: {args.directory} (Inode: {directory_inode})')
184-
bpf_text = bpf_text.replace('DIRECTORY_FILTER', 'file->f_path.dentry->d_parent->d_inode->i_ino != %d' % directory_inode)
186+
if args.recursive:
187+
print(f'Tracing directory recursively: {args.directory} (Inode: {directory_inode})')
188+
directory_filter = ("({ struct dentry *pde = de; int found = 0; "
189+
"for (int i = 0; i < 50; i++) { "
190+
"if (!pde->d_parent) break; pde = pde->d_parent; "
191+
"if (pde->d_inode->i_ino == %d) { found = 1; break; } } "
192+
"!found; })") % directory_inode
193+
else:
194+
print(f'Tracing directory: {args.directory} (Inode: {directory_inode})')
195+
directory_filter = "file->f_path.dentry->d_parent->d_inode->i_ino != %d" % directory_inode
196+
197+
bpf_text = bpf_text.replace('DIRECTORY_FILTER', directory_filter)
185198
except (FileNotFoundError, PermissionError) as e:
186199
print(f'Error accessing directory {args.directory}: {e}')
187200
exit(1)
188201
else:
202+
if args.recursive:
203+
print("Error: --recursive can only be used with -d/--directory option")
204+
exit(1)
189205
bpf_text = bpf_text.replace('DIRECTORY_FILTER', '0')
190206

191207
if debug or args.ebpf:

0 commit comments

Comments
 (0)