#!/usr/bin/python # @lint-avoid-python-3-compatibility-imports # # vfsstat Count some VFS calls. # For Linux, uses BCC, eBPF. See .c file. # # Written as a basic example of counting multiple events as a stat tool. # # USAGE: vfsstat [interval [count]] # # 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 bcc import BPF from ctypes import c_int from time import sleep, strftime from sys import argv def usage(): print("USAGE: %s [interval [count]]" % argv[0]) exit() # arguments interval = 1 count = -1 if len(argv) > 1: try: interval = int(argv[1]) if interval == 0: raise if len(argv) > 2: count = int(argv[2]) except: # also catches -h, --help usage() # load BPF program b = BPF(text=""" #include enum stat_types { S_READ = 1, S_WRITE, S_FSYNC, S_OPEN, S_CREATE, S_MAXSTAT }; BPF_ARRAY(stats, u64, S_MAXSTAT); static void stats_increment(int key) { u64 *leaf = stats.lookup(&key); if (leaf) (*leaf)++; } void do_read(struct pt_regs *ctx) { stats_increment(S_READ); } void do_write(struct pt_regs *ctx) { stats_increment(S_WRITE); } void do_fsync(struct pt_regs *ctx) { stats_increment(S_FSYNC); } void do_open(struct pt_regs *ctx) { stats_increment(S_OPEN); } void do_create(struct pt_regs *ctx) { stats_increment(S_CREATE); } """) b.attach_kprobe(event="vfs_read", fn_name="do_read") b.attach_kprobe(event="vfs_write", fn_name="do_write") b.attach_kprobe(event="vfs_fsync", fn_name="do_fsync") b.attach_kprobe(event="vfs_open", fn_name="do_open") b.attach_kprobe(event="vfs_create", fn_name="do_create") # stat column labels and indexes stat_types = { "READ": 1, "WRITE": 2, "FSYNC": 3, "OPEN": 4, "CREATE": 5 } # header print("%-8s " % "TIME", end="") for stype in stat_types.keys(): print(" %8s" % (stype + "/s"), end="") idx = stat_types[stype] print("") # output i = 0 while (1): if count > 0: i += 1 if i > count: exit() try: sleep(interval) except KeyboardInterrupt: pass exit() print("%-8s: " % strftime("%H:%M:%S"), end="") # print each statistic as a column for stype in stat_types.keys(): idx = stat_types[stype] try: val = b["stats"][c_int(idx)].value / interval print(" %8d" % val, end="") except: print(" %8d" % 0, end="") b["stats"].clear() print("")