#!/usr/sbin/dtrace -s /* ** iosnoop.d - A program to print I/O events as they happen, with useful ** details such as UID, PID, inode, command, etc. ** Written in DTrace (Solaris 10 build 63). ** ** NOTE: This version is deprecated. See "iosnoop", ** http://www.brendangregg.com/dtrace.html ** ** 10-Oct-2004, ver 0.90 ** ** ** USAGE: ./iosnoop.d ** ** Different styles of output can be selected by changing ** the "PFORMAT" variable below. ** ** FIELDS: ** COMM command name for the process ** ARGS full argument listing for the process ** FILE filename (basename) for io operation ** MOUNT mount point ** SIZE size of operation, bytes ** BLOCK disk block for the operation (location) ** STIME timestamp for the disk request, us ** TIME timestamp for the disk completion, us ** D direction, Read or Write ** ... ** ** SEE ALSO: Solaris Dynamic Tracing Guide, http://docs.sun.com ** ** Standard Disclaimer: This is freeware, use at your own risk. ** ** 12-Mar-2004 Brendan Gregg Created this, build 51. ** 23-May-2004 " " Fixed mntpt bug. ** 10-Oct-2004 " " Rewritten to use the io provider, build 63. ** */ inline int PFORMAT = 1; /* 1 - Default output (COMM, PATHNAME) /* 2 - Arguments output (MOUNT, FILE, ARGS) ** 3 - Timestamp output (TIME, COMM, PATHNAME) ** 4 - Everything, space delimited (for spreadsheets) */ #pragma D option quiet /* ** Print header */ dtrace:::BEGIN /PFORMAT == 1/ { printf("%5s %5s %1s %8s %6s %10s %s\n", "UID","PID","D","BLOCK","SIZE","COMM","PATHNAME"); } dtrace:::BEGIN /PFORMAT == 2/ { printf("%5s %5s %1s %8s %6s %12s %16s %s\n", "UID","PID","D","BLOCK","SIZE","MOUNT","FILE","ARGS"); } dtrace:::BEGIN /PFORMAT == 3/ { printf("%-14s %5s %5s %1s %8s %6s %10s %s\n", "TIME","UID","PID","D","BLOCK","SIZE","COMM","PATHNAME"); } dtrace:::BEGIN /PFORMAT == 4/ { printf("%s %s %s %s %s %s %s %s %s %s %s %s %s\n", "TIME","STIME","UID","PID","PPID","D","BLOCK","SIZE","MOUNT", "FILE","PATH","COMM","ARGS"); } /* ** Store entry details */ io:::start { this->dev = args[0]->b_edev; this->blk = args[0]->b_blkno; start_uid[this->dev,this->blk] = curpsinfo->pr_euid; start_pid[this->dev,this->blk] = pid; start_ppid[this->dev,this->blk] = curpsinfo->pr_ppid; start_args[this->dev,this->blk] = (char *)curpsinfo->pr_psargs; start_comm[this->dev,this->blk] = execname; start_time[this->dev,this->blk] = timestamp; start_rw[this->dev,this->blk] = args[0]->b_flags & B_READ ? "R" : "W"; } /* ** Process completion */ io:::done { /* fetch entry values */ this->dev = args[0]->b_edev; this->blk = args[0]->b_blkno; this->suid = start_uid[this->dev,this->blk]; this->spid = start_pid[this->dev,this->blk]; this->sppid = start_ppid[this->dev,this->blk]; sargs = (int)start_args[this->dev,this->blk] == 0 ? "" : start_args[this->dev,this->blk]; scomm = start_comm[this->dev,this->blk]; this->stime = start_time[this->dev,this->blk]; readwrite = start_rw[this->dev,this->blk]; /* memory cleanup */ start_uid[this->dev,this->blk] = 0; start_pid[this->dev,this->blk] = 0; start_ppid[this->dev,this->blk] = 0; start_args[this->dev,this->blk] = 0; start_time[this->dev,this->blk] = 0; start_comm[this->dev,this->blk] = 0; start_rw[this->dev,this->blk] = 0; } /* ** Print event details */ io:::done /PFORMAT == 1/ { printf("%5d %5d %1s %8d %6d %10s %s\n", this->suid,this->spid,readwrite,args[0]->b_blkno,args[0]->b_bcount, scomm,args[2]->fi_pathname); } io:::done /PFORMAT == 2/ { printf("%5d %5d %1s %8d %6d %12s %16s %s\n", this->suid,this->spid,readwrite,args[0]->b_blkno,args[0]->b_bcount, args[2]->fi_mount,args[2]->fi_name,stringof(sargs)); } io:::done /PFORMAT == 3/ { printf("%-14d %5d %5d %1s %8d %6d %10s %s\n", timestamp/1000,this->suid,this->spid,readwrite,args[0]->b_blkno, args[0]->b_bcount,scomm,args[2]->fi_pathname); } io:::done /PFORMAT == 4/ { printf("%d %d %d %d %d %s %d %d %s %s %s %s %s\n", timestamp/1000,this->stime/1000,this->suid,this->spid,this->sppid, readwrite,args[0]->b_blkno,args[0]->b_bcount,args[2]->fi_mount, args[2]->fi_name,args[2]->fi_pathname,scomm,stringof(sargs)); }