1#!/usr/bin/env python 2# @lint-avoid-python-3-compatibility-imports 3# 4# vfsstat Count some VFS calls. 5# For Linux, uses BCC, eBPF. See .c file. 6# 7# Written as a basic example of counting multiple events as a stat tool. 8# 9# USAGE: vfsstat [interval [count]] 10# 11# Copyright (c) 2015 Brendan Gregg. 12# Licensed under the Apache License, Version 2.0 (the "License") 13# 14# 14-Aug-2015 Brendan Gregg Created this. 15 16from __future__ import print_function 17from bcc import BPF 18from ctypes import c_int 19from time import sleep, strftime 20from sys import argv 21 22def usage(): 23 print("USAGE: %s [interval [count]]" % argv[0]) 24 exit() 25 26# arguments 27interval = 1 28count = -1 29if len(argv) > 1: 30 try: 31 interval = int(argv[1]) 32 if interval == 0: 33 raise 34 if len(argv) > 2: 35 count = int(argv[2]) 36 except: # also catches -h, --help 37 usage() 38 39# load BPF program 40b = BPF(text=""" 41#include <uapi/linux/ptrace.h> 42 43enum stat_types { 44 S_READ = 1, 45 S_WRITE, 46 S_FSYNC, 47 S_OPEN, 48 S_CREATE, 49 S_MAXSTAT 50}; 51 52BPF_ARRAY(stats, u64, S_MAXSTAT); 53 54static void stats_increment(int key) { 55 u64 *leaf = stats.lookup(&key); 56 if (leaf) (*leaf)++; 57} 58 59void do_read(struct pt_regs *ctx) { stats_increment(S_READ); } 60void do_write(struct pt_regs *ctx) { stats_increment(S_WRITE); } 61void do_fsync(struct pt_regs *ctx) { stats_increment(S_FSYNC); } 62void do_open(struct pt_regs *ctx) { stats_increment(S_OPEN); } 63void do_create(struct pt_regs *ctx) { stats_increment(S_CREATE); } 64""") 65b.attach_kprobe(event="vfs_read", fn_name="do_read") 66b.attach_kprobe(event="vfs_write", fn_name="do_write") 67b.attach_kprobe(event="vfs_fsync", fn_name="do_fsync") 68b.attach_kprobe(event="vfs_open", fn_name="do_open") 69b.attach_kprobe(event="vfs_create", fn_name="do_create") 70 71# stat column labels and indexes 72stat_types = { 73 "READ": 1, 74 "WRITE": 2, 75 "FSYNC": 3, 76 "OPEN": 4, 77 "CREATE": 5 78} 79 80# header 81print("%-8s " % "TIME", end="") 82for stype in stat_types.keys(): 83 print(" %8s" % (stype + "/s"), end="") 84 idx = stat_types[stype] 85print("") 86 87# output 88i = 0 89while (1): 90 if count > 0: 91 i += 1 92 if i > count: 93 exit() 94 try: 95 sleep(interval) 96 except KeyboardInterrupt: 97 pass 98 exit() 99 100 print("%-8s: " % strftime("%H:%M:%S"), end="") 101 # print each statistic as a column 102 for stype in stat_types.keys(): 103 idx = stat_types[stype] 104 try: 105 val = b["stats"][c_int(idx)].value / interval 106 print(" %8d" % val, end="") 107 except: 108 print(" %8d" % 0, end="") 109 b["stats"].clear() 110 print("") 111