diff options
Diffstat (limited to 'cddl/contrib/dtracetoolkit/FS')
-rw-r--r-- | cddl/contrib/dtracetoolkit/FS/Readme | 3 | ||||
-rwxr-xr-x | cddl/contrib/dtracetoolkit/FS/fspaging.d | 154 | ||||
-rwxr-xr-x | cddl/contrib/dtracetoolkit/FS/fsrw.d | 149 | ||||
-rwxr-xr-x | cddl/contrib/dtracetoolkit/FS/rfileio.d | 91 | ||||
-rwxr-xr-x | cddl/contrib/dtracetoolkit/FS/rfsio.d | 98 | ||||
-rwxr-xr-x | cddl/contrib/dtracetoolkit/FS/vopstat | 304 |
6 files changed, 799 insertions, 0 deletions
diff --git a/cddl/contrib/dtracetoolkit/FS/Readme b/cddl/contrib/dtracetoolkit/FS/Readme new file mode 100644 index 0000000..30927a5 --- /dev/null +++ b/cddl/contrib/dtracetoolkit/FS/Readme @@ -0,0 +1,3 @@ +FS - File System based analysis + + This would include VFS and UFS activity. diff --git a/cddl/contrib/dtracetoolkit/FS/fspaging.d b/cddl/contrib/dtracetoolkit/FS/fspaging.d new file mode 100755 index 0000000..4eaa718 --- /dev/null +++ b/cddl/contrib/dtracetoolkit/FS/fspaging.d @@ -0,0 +1,154 @@ +#!/usr/sbin/dtrace -s +/* + * fspaging.d - file system read/write and paging tracing. + * Written using DTrace (Solaris 10 3/05) + * + * This traces file related activity: system call reads and writes, + * vnode logical read and writes (fop), vnode putpage and getpage activity, + * and disk I/O. It can be used to examine the behaviour of each I/O + * layer, from the syscall interface to what the disk is doing. Behaviour + * such as read-ahead, and max I/O size breakup can be observed. + * + * This is a verbose version of fsrw.d, as this also traces paging activity. + * + * $Id: fspaging.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: fspaging.d + * + * FIELDS: + * Event Traced event (see EVENTS below) + * Device Device, for disk I/O + * RW Either Read or Write + * Size Size of I/O in bytes, if known + * Offset Offset of I/O in kilobytes, if known + * Path Path to file on disk + * + * EVENTS: + * sc-read System call read + * sc-write System call write + * fop_read Logical read + * fop_write Logical write + * fop_getpage Logical get page + * fop_putpage Logical put page + * disk_io Physical disk I/O + * disk_ra Physical disk I/O, read ahead + * + * The events are drawn with a level of indentation, which can sometimes + * help identify related events. + * + * SEE ALSO: fsrw.d + * + * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter. + * + * COPYRIGHT: Copyright (c) 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * ToDo: readv() + * + * 20-Mar-2006 Brendan Gregg Created this. + * 23-Apr-2006 " " Last update. + */ + +#pragma D option quiet +#pragma D option switchrate=10hz + +dtrace:::BEGIN +{ + printf("%-13s %10s %2s %8s %6s %s\n", + "Event", "Device", "RW", "Size", "Offset", "Path"); +} + +syscall::*read:entry, +syscall::*write*:entry +{ + /* + * starting with a file descriptior, dig out useful info + * from the corresponding file_t and vnode_t. + */ + this->filistp = curthread->t_procp->p_user.u_finfo.fi_list; + this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp + + (uint64_t)arg0 * (uint64_t)sizeof (uf_entry_t)); + this->filep = this->ufentryp->uf_file; + self->offset = this->filep->f_offset; + this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0; + self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ? + cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>"; + self->sc_trace = this->vnodep ? this->vnodep->v_type == 1 || + this->vnodep->v_type == 2 ? 1 : 0 : 0; +} + +syscall::*read:entry +/self->sc_trace/ +{ + printf("sc-%-10s %10s %2s %8d %6d %s\n", probefunc, ".", "R", + (int)arg2, self->offset / 1024, self->vpath); +} + +syscall::*write*:entry +/self->sc_trace/ +{ + printf("sc-%-10s %10s %2s %8d %6d %s\n", probefunc, ".", "W", + (int)arg2, self->offset / 1024, self->vpath); +} + +syscall::*read:return, +syscall::*write*:return +{ + self->vpath = 0; + self->offset = 0; + self->sc_trace = 0; +} + +fbt::fop_putpage:entry, +fbt::fop_getpage:entry +/self->sc_trace && args[0]->v_path/ +{ + printf(" %-11s %10s %2s %8d %6d %s\n", probefunc, ".", + probefunc == "fop_getpage" ? "R" : "W", (uint64_t)arg2, + args[1] / 1024, cleanpath(args[0]->v_path)); +} + + +fbt::fop_read:entry, +fbt::fop_write:entry +/self->sc_trace && args[0]->v_path/ +{ + printf(" %-11s %10s %2s %8d %6d %s\n", probefunc, ".", + probefunc == "fop_read" ? "R" : "W", args[1]->uio_resid, + args[1]->_uio_offset._f / 1024, cleanpath(args[0]->v_path)); +} + +fbt:ufs:ufs_getpage_ra:entry +{ + /* fetch the real offset (file_t is unaware of this) */ + self->offset = ((inode_t *)args[0]->v_data)->i_nextrio; + self->read_ahead = 1; +} + +fbt:ufs:ufs_getpage_ra:return +{ + self->read_ahead = 0; + self->offset = 0; +} + +io::bdev_strategy:start +{ + this->offset = self->read_ahead ? self->offset : args[2]->fi_offset; + printf(" %-9s %10s %2s %8d %6d %s\n", + self->read_ahead ? "disk_ra" : "disk_io", args[1]->dev_statname, + args[0]->b_flags & B_READ ? "R" : "W", args[0]->b_bcount, + this->offset / 1024, args[2]->fi_pathname); +} diff --git a/cddl/contrib/dtracetoolkit/FS/fsrw.d b/cddl/contrib/dtracetoolkit/FS/fsrw.d new file mode 100755 index 0000000..291f09aa --- /dev/null +++ b/cddl/contrib/dtracetoolkit/FS/fsrw.d @@ -0,0 +1,149 @@ +#!/usr/sbin/dtrace -s +/* + * fsrw.d - file system read/write event tracing. + * Written using DTrace (Solaris 10 3/05) + * + * This traces file related activity: system call reads and writes, + * vnode logical read and writes (fop), and disk I/O. It can be used + * to examine the behaviour of each I/O layer, from the syscall + * interface to what the disk is doing. Behaviour such as read-ahead, and + * max I/O size breakup can be observed. + * + * $Id: fsrw.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: fsrw.d + * + * FIELDS: + * Event Traced event (see EVENTS below) + * Device Device, for disk I/O + * RW Either Read or Write + * Size Size of I/O in bytes + * Offset Offset of I/O in kilobytes + * Path Path to file on disk + * + * EVENTS: + * sc-read System call read + * sc-write System call write + * fop_read Logical read + * fop_write Logical write + * disk_io Physical disk I/O + * disk_ra Physical disk I/O, read ahead + * + * The events are drawn with a level of indentation, which can sometimes + * help identify related events. + * + * SEE ALSO: fspaging.d + * + * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter. + * + * COPYRIGHT: Copyright (c) 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * ToDo: readv() + * + * 20-Mar-2006 Brendan Gregg Created this. + * 23-Apr-2006 " " Last update. + */ + +#pragma D option quiet +#pragma D option switchrate=10hz + +dtrace:::BEGIN +{ + printf("%-12s %10s %2s %8s %6s %s\n", + "Event", "Device", "RW", "Size", "Offset", "Path"); +} + +syscall::*read:entry, +syscall::*write*:entry +{ + /* + * starting with a file descriptior, dig out useful info + * from the corresponding file_t and vnode_t. + */ + this->filistp = curthread->t_procp->p_user.u_finfo.fi_list; + this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp + + (uint64_t)arg0 * (uint64_t)sizeof (uf_entry_t)); + this->filep = this->ufentryp->uf_file; + self->offset = this->filep->f_offset; + this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0; + self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ? + cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>"; + + /* only trace activity to regular files and directories, as */ + self->sc_trace = this->vnodep ? this->vnodep->v_type == VREG || + this->vnodep->v_type == VDIR ? 1 : 0 : 0; +} + +syscall::*read:entry +/self->sc_trace/ +{ + printf("sc-%-9s %10s %2s %8d %6d %s\n", probefunc, ".", "R", + (int)arg2, self->offset / 1024, self->vpath); +} + +syscall::*write*:entry +/self->sc_trace/ +{ + printf("sc-%-9s %10s %2s %8d %6d %s\n", probefunc, ".", "W", + (int)arg2, self->offset / 1024, self->vpath); +} + +syscall::*read:return, +syscall::*write*:return +{ + self->vpath = 0; + self->offset = 0; + self->sc_trace = 0; +} + +fbt::fop_read:entry, +fbt::fop_write:entry +/self->sc_trace && args[0]->v_path/ +{ + printf(" %-10s %10s %2s %8d %6d %s\n", probefunc, ".", + probefunc == "fop_read" ? "R" : "W", args[1]->uio_resid, + args[1]->_uio_offset._f / 1024, cleanpath(args[0]->v_path)); +} + +fbt:ufs:ufs_getpage_ra:entry +{ + /* fetch the real offset (file_t is unaware of this) */ + self->ra_offset = ((inode_t *)args[0]->v_data)->i_nextrio; + self->read_ahead = 1; +} + +fbt:ufs:ufs_getpage_ra:return +{ + self->read_ahead = 0; + self->ra_offset = 0; +} + +io::bdev_strategy:start +{ + this->offset = self->read_ahead ? self->ra_offset : args[2]->fi_offset; + printf(" %-8s %10s %2s %8d %6d %s\n", + self->read_ahead ? "disk_ra" : "disk_io", args[1]->dev_statname, + args[0]->b_flags & B_READ ? "R" : "W", args[0]->b_bcount, + this->offset / 1024, args[2]->fi_pathname); + /* + * it would seem to make sense to only trace disk events during + * an fop event, easily coded with a self->fop_trace flag. However + * writes are asynchronous to the fop_write calls (they are flushed + * at some later time), and so this approach will miss tracing + * most of the disk writes. + */ +} diff --git a/cddl/contrib/dtracetoolkit/FS/rfileio.d b/cddl/contrib/dtracetoolkit/FS/rfileio.d new file mode 100755 index 0000000..95a6caa --- /dev/null +++ b/cddl/contrib/dtracetoolkit/FS/rfileio.d @@ -0,0 +1,91 @@ +#!/usr/sbin/dtrace -s +/* + * rfileio.d - read file I/O stats, with cache miss rate. + * Written using DTrace (Solaris 10 3/05) + * + * This script provides statistics on the number of reads and the bytes + * read from filesystems (logical), and the number of bytes read from + * disk (physical). A summary is printed every five seconds by file. + * + * A total miss-rate is also provided for the file system cache. + * + * $Id: rfileio.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: rfileio.d + * + * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter. + * + * COPYRIGHT: Copyright (c) 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 19-Mar-2006 Brendan Gregg Created this. + * 23-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +self int trace; +uint64_t lbytes; +uint64_t pbytes; + +dtrace:::BEGIN +{ + trace("Tracing...\n"); +} + +fbt::fop_read:entry +/self->trace == 0 && args[0]->v_path/ +{ + self->pathname = cleanpath(args[0]->v_path); + @rio[self->pathname, "logical"] = count(); + lbytes += args[1]->uio_resid; + self->size = args[1]->uio_resid; + self->uiop = args[1]; +} + +fbt::fop_read:return +/self->size/ +{ + @rbytes[self->pathname, "logical"] = + sum(self->size - self->uiop->uio_resid); + self->size = 0; + self->uiop = 0; + self->pathname = 0; +} + +io::bdev_strategy:start +/self->size && args[0]->b_flags & B_READ/ +{ + @rio[self->pathname, "physical"] = count(); + @rbytes[self->pathname, "physical"] = sum(args[0]->b_bcount); + pbytes += args[0]->b_bcount; +} + +profile:::tick-5s +{ + trunc(@rio, 20); + trunc(@rbytes, 20); + printf("\033[H\033[2J"); + printf("\nRead IOPS, top 20 (count)\n"); + printa("%-54s %10s %10@d\n", @rio); + printf("\nRead Bandwidth, top 20 (bytes)\n"); + printa("%-54s %10s %10@d\n", @rbytes); + printf("\nTotal File System miss-rate: %d%%\n", + lbytes ? 100 * pbytes / lbytes : 0); + trunc(@rbytes); + trunc(@rio); + lbytes = pbytes = 0; +} diff --git a/cddl/contrib/dtracetoolkit/FS/rfsio.d b/cddl/contrib/dtracetoolkit/FS/rfsio.d new file mode 100755 index 0000000..8477563 --- /dev/null +++ b/cddl/contrib/dtracetoolkit/FS/rfsio.d @@ -0,0 +1,98 @@ +#!/usr/sbin/dtrace -s +/* + * rfsio.d - read FS I/O stats, with cache miss rate. + * Written using DTrace (Solaris 10 3/05) + * + * This script provides statistics on the number of reads and the bytes + * read from filesystems (logical), and the number of bytes read from + * disk (physical). A summary is printed every five seconds by filesystem. + * + * A total miss-rate is also provided for the file system cache. + * + * $Id: rfsio.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: rfsio.d + * + * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter. + * + * COPYRIGHT: Copyright (c) 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 19-Mar-2006 Brendan Gregg Created this. + * 23-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +self int trace; +uint64_t lbytes; +uint64_t pbytes; + +dtrace:::BEGIN +{ + trace("Tracing...\n"); +} + +fbt::fop_read:entry +/self->trace == 0/ +{ + self->fs_mount = args[0]->v_vfsp == `rootvfs ? "/" : + args[0]->v_vfsp->vfs_vnodecovered ? + stringof(args[0]->v_vfsp->vfs_vnodecovered->v_path) : NULL; +} + +fbt::fop_read:entry +/self->fs_mount != NULL/ +{ + @rio[self->fs_mount, "logical"] = count(); + lbytes += args[1]->uio_resid; + self->size = args[1]->uio_resid; + self->uiop = args[1]; +} + +fbt::fop_read:return +/self->size/ +{ + @rbytes[self->fs_mount, "logical"] = + sum(self->size - self->uiop->uio_resid); + self->size = 0; + self->uiop = 0; + self->fs_mount = 0; +} + +io::bdev_strategy:start +/self->size && args[0]->b_flags & B_READ/ +{ + @rio[self->fs_mount, "physical"] = count(); + @rbytes[self->fs_mount, "physical"] = sum(args[0]->b_bcount); + pbytes += args[0]->b_bcount; +} + +profile:::tick-5s +{ + trunc(@rio, 20); + trunc(@rbytes, 20); + printf("\033[H\033[2J"); + printf("\nRead IOPS (count)\n"); + printa("%-32s %10s %10@d\n", @rio); + printf("\nRead Bandwidth (bytes)\n"); + printa("%-32s %10s %10@d\n", @rbytes); + printf("\nTotal File System miss-rate: %d%%\n", + lbytes ? 100 * pbytes / lbytes : 0); + trunc(@rbytes); + trunc(@rio); + lbytes = pbytes = 0; +} diff --git a/cddl/contrib/dtracetoolkit/FS/vopstat b/cddl/contrib/dtracetoolkit/FS/vopstat new file mode 100755 index 0000000..a4c5af4 --- /dev/null +++ b/cddl/contrib/dtracetoolkit/FS/vopstat @@ -0,0 +1,304 @@ +#!/usr/bin/sh +# +# vopstat - Trace the vnode interface. +# Written using DTrace (Solaris 10 3/05) +# +# Author: Richard McDougall +# +# $Id: vopstat 3 2007-08-01 10:50:08Z brendan $ +# +# USAGE: vopstat [-t] [/mountname] +# +# vopstat # default output, summary each 5 secs +# -t # trace activity as it occurs +# +# Example: +# +# ./vopstat +# +# VOP Physical IO Count +# fop_fsync 236 +# +# VOP Count Count +# fop_create 1 +# fop_fid 1 +# fop_lookup 2 +# fop_access 3 +# fop_read 3 +# fop_poll 11 +# fop_fsync 31 +# fop_putpage 32 +# fop_ioctl 115 +# fop_write 517 +# fop_rwlock 520 +# fop_rwunlock 520 +# fop_inactive 529 +# fop_getattr 1057 +# +# VOP Wall Time mSeconds +# fop_fid 0 +# fop_access 0 +# fop_read 0 +# fop_poll 0 +# fop_lookup 0 +# fop_create 0 +# fop_ioctl 0 +# fop_putpage 1 +# fop_rwunlock 1 +# fop_rwlock 1 +# fop_inactive 1 +# fop_getattr 2 +# fop_write 22 +# fop_fsync 504 +# +# COPYRIGHT: Copyright (c) 2006 Richard McDougall +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# Shell Wrapper Concept by Brendan Gregg +# +# 08-Jan-2006 Richard McDougall Created this. +# 23-Apr-2006 Brendan Gregg Minor style tweaks. +# 23-Apr-2006 " " Last update. + + +############################## +# --- Process Arguments --- +# + +### default variables +opt_trace=0; opt_fs=0; opt_stats=1; opt_all=0 + +### process options +while getopts t name +do + case $name in + t) opt_trace=1 ;; + h|?) cat <<-END >&2 + USAGE: voptrace [-t] [/mountpoint] + voptrace # default output + -t # trace + eg, + voptrace -t # trace all file systems + voptrace -t /tmp # trace /tmp + voptrace /tmp # summary stats for /tmp + END + exit 1 + esac +done +shift `expr $OPTIND - 1` +filesys="$1" + +### option logic +if [ $opt_trace -eq 1 ]; then + opt_stats=0 +fi +if [ -z "$filesys" ]; then + opt_all=1 +fi + +################################# +# --- Main Program, DTrace --- +# +/usr/sbin/dtrace -n ' + /* + * Command line arguments + */ + inline int OPT_fs = '$opt_fs'; + inline int OPT_all = '$opt_all'; + inline int OPT_trace = '$opt_trace'; + inline int OPT_stats = '$opt_stats'; + inline string FILESYS = "'$filesys'"; + + #pragma D option quiet + + /* + * Print header + */ + dtrace:::BEGIN + { + last_event[""] = 0; + + /* print main headers */ + OPT_stats == 1 ? + printf("\033[H\033[2J") : 1; + + OPT_trace == 1 ? + printf("%2s %-15s %-10s %51s %2s %8s %8s\n", + "", "Event", "Device", "Path", "RW", "Size", "Offset") : 1; + self->path = ""; + self->trace = 0; + } + + dtrace:::BEGIN + /OPT_trace == 1/ + { + /* make D compiler happy */ + @vop_iocnt[""] = count(); + @vop_cnt[""] = count(); + @vop_time[""] = sum(0); + trunc(@vop_iocnt); + trunc(@vop_cnt); + trunc(@vop_time); + } + + fbt::fop_*:entry + { + self->trace = 0; + + /* Get vp: fop_open has a pointer to vp */ + this->vpp = (vnode_t **)arg0; + self->vp = (vnode_t *)arg0; + self->vp = probefunc == "fop_open" ? (vnode_t *)*this->vpp : self->vp; + + /* And the containing vfs */ + this->vfsp = self->vp ? self->vp->v_vfsp : 0; + + /* And the paths for the vp and containing vfs */ + this->vfsvp = this->vfsp ? + (struct vnode *)((vfs_t *)this->vfsp)->vfs_vnodecovered : 0; + self->vfspath = this->vfsvp ? stringof(this->vfsvp->v_path) : "unknown"; + + /* Check if we should trace the root fs */ + (OPT_all || + (FILESYS == "/" && this->vfsp && + (this->vfsp == `rootvfs))) ? self->trace = 1 : self->trace; + + /* Check if we should trace the fs */ + (OPT_all || (self->vfspath == FILESYS)) ? self->trace = 1 : self->trace; + + self->vfspath = 0; + } + + /* + * Trace the entry point to each fop + */ + fbt::fop_*:entry + /self->trace/ + { + self->path = (self->vp != NULL && self->vp->v_path) ? + stringof(self->vp->v_path) : "unknown"; + + /* Some fops has the len in arg2 */ + (probefunc == "fop_getpage" || + probefunc == "fop_putpage" || + probefunc == "fop_none") ? self->len = arg2 : 1; + + /* Some fops has the len in arg3 */ + (probefunc == "fop_pageio" || + probefunc == "fop_none") ? self->len = arg3 : 1; + + /* Some fops has the len in arg4 */ + (probefunc == "fop_addmap" || + probefunc == "fop_map" || + probefunc == "fop_delmap") ? self->len = arg4 : 1; + + /* Some fops has the offset in arg1 */ + (probefunc == "fop_addmap" || + probefunc == "fop_map" || + probefunc == "fop_getpage" || + probefunc == "fop_putpage" || + probefunc == "fop_seek" || + probefunc == "fop_delmap") ? self->off = arg1 : 1; + + /* Some fops has the offset in arg3 */ + (probefunc == "fop_close" || + probefunc == "fop_pageio") ? self->off = arg3 : 1; + + /* Some fops has the offset in arg4 */ + probefunc == "fop_frlock" ? self->off = arg4 : 1; + + /* Some fops has the pathname in arg1 */ + self->path = (probefunc == "fop_create" || + probefunc == "fop_mkdir" || + probefunc == "fop_rmdir" || + probefunc == "fop_remove" || + probefunc == "fop_lookup") ? + strjoin(self->path, strjoin("/", stringof(arg1))) : self->path; + + OPT_trace ? + printf("%2s %-15s %-10s %51s %2s %8d %8d\n", + "->", probefunc, "-", self->path, "-", + self->len, self->off) : 1; + + self->type = probefunc; + self->vop_entry[probefunc] = timestamp; + } + + fbt::fop_*:return + /self->trace == 1/ + { + OPT_trace ? + printf("%2s %-15s %-10s %51s %2s %8d %8d\n", + "<-", probefunc, "-", self->path, "-", + self->len, self->off) : 1; + + OPT_stats == 1 ? + @vop_time[probefunc] = + sum(timestamp - self->vop_entry[probefunc]) : 1; + OPT_stats == 1 ? + @vop_cnt[probefunc] = count() : 1; + + self->path = 0; + self->len = 0; + self->off = 0; + } + + fbt::fop_*:return + { + self->trace = 0; + self->type = 0; + self->vp = 0; + } + + /* Capture any I/O within this fop */ + io:::start + /self->trace/ + { + OPT_stats == 1 ? + @vop_iocnt[self->type] = count() : 1; + + OPT_trace == 1? + printf("%2s %-15s %-10s %51s %2s %8d %8u\n", + "--", self->type, args[1]->dev_statname, + self->path, args[0]->b_flags & B_READ ? "R" : "W", + args[0]->b_bcount, args[0]->b_blkno) : 1; + } + + profile:::tick-5s + /OPT_stats == 1/ + { + /* Print top 20 only */ + trunc(@vop_iocnt, 20); + trunc(@vop_time, 20); + + /* Display microseconds */ + normalize(@vop_time, 1000000); + printf("\033[H\033[2J"); + printf("%-60s %10s\n", "VOP Physical IO", "Count"); + printa("%-60s %10@d\n", @vop_iocnt); + printf("\n"); + printf("%-60s %10s\n", "VOP Count", "Count"); + printa("%-60s %10@d\n", @vop_cnt); + printf("\n"); + printf("%-60s %10s\n", "VOP Wall Time", "mSeconds"); + printa("%-60s %10@d\n", @vop_time); + + /* Clear data */ + trunc(@vop_iocnt); + trunc(@vop_cnt); + trunc(@vop_time); + } +' |