aboutsummaryrefslogtreecommitdiff
path: root/FS/vopstat
diff options
context:
space:
mode:
Diffstat (limited to 'FS/vopstat')
-rwxr-xr-xFS/vopstat304
1 files changed, 304 insertions, 0 deletions
diff --git a/FS/vopstat b/FS/vopstat
new file mode 100755
index 000000000000..a4c5af46d7de
--- /dev/null
+++ b/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);
+ }
+'