blob: 64b5034649fc9d4719542b536e48acd4009d30fe [file] [log] [blame]
#!/usr/bin/python
#
# vfscount Count VFS calls ("vfs_*").
# For Linux, uses BCC, eBPF. See .c file.
#
# Written as a basic example of counting functions.
#
# Copyright (c) 2015 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 14-Aug-2015 Brendan Gregg Created this.
from __future__ import print_function
from bpf import BPF
from ctypes import c_ushort, c_int, c_ulonglong
from time import sleep, strftime
from sys import stderr
# kernel symbol translation
ksym_addrs = [] # addresses for binary search
ksym_names = [] # same index as ksym_addrs
def load_kallsyms():
symfile = "/proc/kallsyms"
try:
syms = open(symfile, "r")
except:
print("ERROR: reading " + symfile, file=sys.stderr)
exit()
line = syms.readline()
for line in iter(syms):
cols = line.split()
name = cols[2]
if name[:4] != "vfs_": # perf optimization
continue
addr = int(cols[0], 16)
ksym_addrs.append(addr)
ksym_names.append(name)
syms.close()
def _ksym_addr2index(addr):
start = -1
end = len(ksym_addrs)
while end != start + 1:
mid = int((start + end) / 2)
if addr < ksym_addrs[mid]:
end = mid
else:
start = mid
return start
def ksym(addr):
idx = _ksym_addr2index(addr)
if idx == -1:
return "[unknown]"
return ksym_names[idx]
load_kallsyms()
# load BPF program
b = BPF(src_file = "vfscount.c")
b.attach_kprobe(event_re="^vfs_.*", fn_name="do_count")
# header
print("Tracing... Ctrl-C to end.")
# output
try:
sleep(99999999)
except KeyboardInterrupt:
pass
print("\n%-16s %-26s %8s" % ("ADDR", "FUNC", "COUNT"))
counts = b.get_table("counts")
for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
print("%-16x %-26s %8d" % (k.ip, ksym(k.ip), v.value))