Home | History | Annotate | Line # | Download | only in Bin
vopstat revision 1.1
      1  1.1  christos #!/usr/bin/sh
      2  1.1  christos #
      3  1.1  christos # vopstat - Trace the vnode interface.
      4  1.1  christos #           Written using DTrace (Solaris 10 3/05)
      5  1.1  christos #
      6  1.1  christos # Author: Richard McDougall
      7  1.1  christos #
      8  1.1  christos # $Id: vopstat,v 1.1 2015/09/30 22:01:07 christos Exp $
      9  1.1  christos #
     10  1.1  christos # USAGE:	vopstat [-t] [/mountname]
     11  1.1  christos #
     12  1.1  christos #		vopstat		# default output, summary each 5 secs
     13  1.1  christos #		-t 		# trace activity as it occurs
     14  1.1  christos #
     15  1.1  christos # Example:
     16  1.1  christos #
     17  1.1  christos # ./vopstat
     18  1.1  christos # 
     19  1.1  christos # VOP Physical IO                                                   Count
     20  1.1  christos # fop_fsync                                                           236
     21  1.1  christos # 
     22  1.1  christos # VOP Count                                                         Count
     23  1.1  christos # fop_create                                                            1
     24  1.1  christos # fop_fid                                                               1
     25  1.1  christos # fop_lookup                                                            2
     26  1.1  christos # fop_access                                                            3
     27  1.1  christos # fop_read                                                              3
     28  1.1  christos # fop_poll                                                             11
     29  1.1  christos # fop_fsync                                                            31
     30  1.1  christos # fop_putpage                                                          32
     31  1.1  christos # fop_ioctl                                                           115
     32  1.1  christos # fop_write                                                           517
     33  1.1  christos # fop_rwlock                                                          520
     34  1.1  christos # fop_rwunlock                                                        520
     35  1.1  christos # fop_inactive                                                        529
     36  1.1  christos # fop_getattr                                                        1057
     37  1.1  christos # 
     38  1.1  christos # VOP Wall Time                                                  mSeconds
     39  1.1  christos # fop_fid                                                               0
     40  1.1  christos # fop_access                                                            0
     41  1.1  christos # fop_read                                                              0
     42  1.1  christos # fop_poll                                                              0
     43  1.1  christos # fop_lookup                                                            0
     44  1.1  christos # fop_create                                                            0
     45  1.1  christos # fop_ioctl                                                             0
     46  1.1  christos # fop_putpage                                                           1
     47  1.1  christos # fop_rwunlock                                                          1
     48  1.1  christos # fop_rwlock                                                            1
     49  1.1  christos # fop_inactive                                                          1
     50  1.1  christos # fop_getattr                                                           2
     51  1.1  christos # fop_write                                                            22
     52  1.1  christos # fop_fsync                                                           504
     53  1.1  christos # 
     54  1.1  christos # COPYRIGHT: Copyright (c) 2006 Richard McDougall
     55  1.1  christos #
     56  1.1  christos # CDDL HEADER START
     57  1.1  christos #
     58  1.1  christos #  The contents of this file are subject to the terms of the
     59  1.1  christos #  Common Development and Distribution License, Version 1.0 only
     60  1.1  christos #  (the "License").  You may not use this file except in compliance
     61  1.1  christos #  with the License.
     62  1.1  christos #
     63  1.1  christos #  You can obtain a copy of the license at Docs/cddl1.txt
     64  1.1  christos #  or http://www.opensolaris.org/os/licensing.
     65  1.1  christos #  See the License for the specific language governing permissions
     66  1.1  christos #  and limitations under the License.
     67  1.1  christos #
     68  1.1  christos # CDDL HEADER END
     69  1.1  christos #
     70  1.1  christos # Shell Wrapper Concept by Brendan Gregg
     71  1.1  christos #
     72  1.1  christos # 08-Jan-2006	Richard McDougall	Created this.
     73  1.1  christos # 23-Apr-2006	Brendan Gregg		Minor style tweaks.
     74  1.1  christos # 23-Apr-2006	   "      "		Last update.
     75  1.1  christos 
     76  1.1  christos 
     77  1.1  christos ##############################
     78  1.1  christos # --- Process Arguments ---
     79  1.1  christos #
     80  1.1  christos 
     81  1.1  christos ### default variables
     82  1.1  christos opt_trace=0; opt_fs=0; opt_stats=1; opt_all=0
     83  1.1  christos 
     84  1.1  christos ### process options
     85  1.1  christos while getopts t name
     86  1.1  christos do
     87  1.1  christos 	case $name in
     88  1.1  christos 	t)	opt_trace=1 ;;
     89  1.1  christos 	h|?)	cat <<-END >&2
     90  1.1  christos 		USAGE: voptrace [-t] [/mountpoint]
     91  1.1  christos 		        voptrace         # default output
     92  1.1  christos 		                 -t      # trace
     93  1.1  christos 		   eg,
     94  1.1  christos 		        voptrace -t      # trace all file systems
     95  1.1  christos 		        voptrace -t /tmp # trace /tmp
     96  1.1  christos 		        voptrace  /tmp   # summary stats for /tmp
     97  1.1  christos 		END
     98  1.1  christos 		exit 1
     99  1.1  christos 	esac
    100  1.1  christos done
    101  1.1  christos shift `expr $OPTIND - 1`
    102  1.1  christos filesys="$1"
    103  1.1  christos 
    104  1.1  christos ### option logic
    105  1.1  christos if [ $opt_trace -eq 1 ]; then
    106  1.1  christos 	opt_stats=0
    107  1.1  christos fi
    108  1.1  christos if [ -z "$filesys" ]; then
    109  1.1  christos 	opt_all=1
    110  1.1  christos fi
    111  1.1  christos 
    112  1.1  christos #################################
    113  1.1  christos # --- Main Program, DTrace ---
    114  1.1  christos #
    115  1.1  christos /usr/sbin/dtrace -n '
    116  1.1  christos  /*
    117  1.1  christos   * Command line arguments
    118  1.1  christos   */
    119  1.1  christos  inline int OPT_fs 	= '$opt_fs';
    120  1.1  christos  inline int OPT_all 	= '$opt_all';
    121  1.1  christos  inline int OPT_trace 	= '$opt_trace';
    122  1.1  christos  inline int OPT_stats 	= '$opt_stats';
    123  1.1  christos  inline string FILESYS 	= "'$filesys'";
    124  1.1  christos  
    125  1.1  christos  #pragma D option quiet
    126  1.1  christos 
    127  1.1  christos  /*
    128  1.1  christos   * Print header
    129  1.1  christos   */
    130  1.1  christos  dtrace:::BEGIN 
    131  1.1  christos  {
    132  1.1  christos 	last_event[""] = 0;
    133  1.1  christos 
    134  1.1  christos 	/* print main headers */
    135  1.1  christos 	OPT_stats == 1 ?
    136  1.1  christos 		printf("\033[H\033[2J") : 1;
    137  1.1  christos 
    138  1.1  christos 	OPT_trace == 1 ?
    139  1.1  christos 		printf("%2s %-15s %-10s %51s %2s %8s %8s\n", 
    140  1.1  christos 		    "", "Event", "Device", "Path", "RW", "Size", "Offset") : 1;
    141  1.1  christos 	self->path = "";
    142  1.1  christos 	self->trace = 0;
    143  1.1  christos  }
    144  1.1  christos 
    145  1.1  christos  dtrace:::BEGIN
    146  1.1  christos  /OPT_trace == 1/
    147  1.1  christos  {
    148  1.1  christos 	/* make D compiler happy */
    149  1.1  christos 	@vop_iocnt[""] = count();
    150  1.1  christos 	@vop_cnt[""]   = count();
    151  1.1  christos 	@vop_time[""]  = sum(0);
    152  1.1  christos 	trunc(@vop_iocnt);
    153  1.1  christos 	trunc(@vop_cnt);
    154  1.1  christos 	trunc(@vop_time);
    155  1.1  christos  }
    156  1.1  christos  
    157  1.1  christos  fbt::fop_*:entry
    158  1.1  christos  {
    159  1.1  christos  	self->trace = 0;
    160  1.1  christos 
    161  1.1  christos  	/* Get vp: fop_open has a pointer to vp */
    162  1.1  christos  	this->vpp = (vnode_t **)arg0;
    163  1.1  christos  	self->vp = (vnode_t *)arg0;
    164  1.1  christos  	self->vp = probefunc == "fop_open" ? (vnode_t *)*this->vpp : self->vp;
    165  1.1  christos 
    166  1.1  christos  	/* And the containing vfs */
    167  1.1  christos          this->vfsp = self->vp ? self->vp->v_vfsp : 0;
    168  1.1  christos 
    169  1.1  christos  	/* And the paths for the vp and containing vfs */
    170  1.1  christos  	this->vfsvp = this->vfsp ?
    171  1.1  christos 	    (struct vnode *)((vfs_t *)this->vfsp)->vfs_vnodecovered : 0;
    172  1.1  christos  	self->vfspath = this->vfsvp ? stringof(this->vfsvp->v_path) : "unknown";
    173  1.1  christos  
    174  1.1  christos  	/* Check if we should trace the root fs */
    175  1.1  christos  	(OPT_all || 
    176  1.1  christos  	    (FILESYS == "/" && this->vfsp &&
    177  1.1  christos  	    (this->vfsp == `rootvfs))) ? self->trace = 1 : self->trace;
    178  1.1  christos  
    179  1.1  christos  	/* Check if we should trace the fs */
    180  1.1  christos  	(OPT_all || (self->vfspath == FILESYS)) ? self->trace = 1 : self->trace;
    181  1.1  christos 
    182  1.1  christos 	self->vfspath = 0;
    183  1.1  christos  }
    184  1.1  christos  
    185  1.1  christos  /*
    186  1.1  christos   * Trace the entry point to each fop
    187  1.1  christos   */ 
    188  1.1  christos  fbt::fop_*:entry
    189  1.1  christos  /self->trace/
    190  1.1  christos  {
    191  1.1  christos  	self->path = (self->vp != NULL && self->vp->v_path) ?
    192  1.1  christos 	    stringof(self->vp->v_path) : "unknown";
    193  1.1  christos  
    194  1.1  christos  	/* Some fops has the len in arg2 */
    195  1.1  christos  	(probefunc == "fop_getpage" ||
    196  1.1  christos  	 probefunc == "fop_putpage" ||
    197  1.1  christos  	 probefunc == "fop_none") ? self->len = arg2 : 1; 
    198  1.1  christos  
    199  1.1  christos  	/* Some fops has the len in arg3 */
    200  1.1  christos  	(probefunc == "fop_pageio" ||
    201  1.1  christos  	 probefunc == "fop_none") ? self->len = arg3 : 1; 
    202  1.1  christos  
    203  1.1  christos  	/* Some fops has the len in arg4 */
    204  1.1  christos  	(probefunc == "fop_addmap" ||
    205  1.1  christos  	 probefunc == "fop_map" ||
    206  1.1  christos  	 probefunc == "fop_delmap") ? self->len = arg4 : 1; 
    207  1.1  christos  
    208  1.1  christos  	/* Some fops has the offset in arg1 */
    209  1.1  christos  	(probefunc == "fop_addmap" ||
    210  1.1  christos  	 probefunc == "fop_map" ||
    211  1.1  christos  	 probefunc == "fop_getpage" ||
    212  1.1  christos  	 probefunc == "fop_putpage" ||
    213  1.1  christos  	 probefunc == "fop_seek" ||
    214  1.1  christos  	 probefunc == "fop_delmap") ? self->off = arg1 : 1; 
    215  1.1  christos  
    216  1.1  christos  	/* Some fops has the offset in arg3 */
    217  1.1  christos  	(probefunc == "fop_close" ||
    218  1.1  christos  	 probefunc == "fop_pageio") ? self->off = arg3 : 1; 
    219  1.1  christos  
    220  1.1  christos  	/* Some fops has the offset in arg4 */
    221  1.1  christos  	probefunc == "fop_frlock" ? self->off = arg4 : 1; 
    222  1.1  christos  
    223  1.1  christos  	/* Some fops has the pathname in arg1 */
    224  1.1  christos  	self->path = (probefunc == "fop_create" ||
    225  1.1  christos  	 probefunc == "fop_mkdir" ||
    226  1.1  christos  	 probefunc == "fop_rmdir" ||
    227  1.1  christos  	 probefunc == "fop_remove" ||
    228  1.1  christos  	 probefunc == "fop_lookup") ?
    229  1.1  christos  	    strjoin(self->path, strjoin("/", stringof(arg1))) : self->path;
    230  1.1  christos  
    231  1.1  christos 	OPT_trace ?
    232  1.1  christos  		printf("%2s %-15s %-10s %51s %2s %8d %8d\n", 
    233  1.1  christos  		    "->", probefunc, "-", self->path, "-",
    234  1.1  christos 		    self->len, self->off) : 1;
    235  1.1  christos 
    236  1.1  christos  	self->type = probefunc;
    237  1.1  christos  	self->vop_entry[probefunc] = timestamp;
    238  1.1  christos  }
    239  1.1  christos  
    240  1.1  christos  fbt::fop_*:return
    241  1.1  christos  /self->trace == 1/
    242  1.1  christos  {
    243  1.1  christos 	OPT_trace ?
    244  1.1  christos  		printf("%2s %-15s %-10s %51s %2s %8d %8d\n", 
    245  1.1  christos 		    "<-", probefunc, "-", self->path, "-",
    246  1.1  christos 		    self->len, self->off) : 1;
    247  1.1  christos 
    248  1.1  christos 	OPT_stats == 1 ?
    249  1.1  christos  		@vop_time[probefunc] =
    250  1.1  christos 			sum(timestamp - self->vop_entry[probefunc]) : 1;
    251  1.1  christos 	OPT_stats == 1 ?
    252  1.1  christos  		@vop_cnt[probefunc] = count() : 1;
    253  1.1  christos 
    254  1.1  christos 	self->path = 0;
    255  1.1  christos 	self->len = 0;
    256  1.1  christos 	self->off = 0;
    257  1.1  christos  }
    258  1.1  christos 
    259  1.1  christos  fbt::fop_*:return
    260  1.1  christos  {
    261  1.1  christos 	self->trace = 0;
    262  1.1  christos 	self->type = 0;
    263  1.1  christos 	self->vp = 0;
    264  1.1  christos  }
    265  1.1  christos  
    266  1.1  christos  /* Capture any I/O within this fop */
    267  1.1  christos  io:::start
    268  1.1  christos  /self->trace/
    269  1.1  christos  {
    270  1.1  christos 	OPT_stats == 1 ?
    271  1.1  christos  		@vop_iocnt[self->type] = count() : 1;
    272  1.1  christos 
    273  1.1  christos 	OPT_trace == 1?
    274  1.1  christos 	 	printf("%2s %-15s %-10s %51s %2s %8d %8u\n",
    275  1.1  christos 		    "--", self->type, args[1]->dev_statname,
    276  1.1  christos 		    self->path, args[0]->b_flags & B_READ ? "R" : "W",
    277  1.1  christos 		    args[0]->b_bcount, args[0]->b_blkno) : 1;
    278  1.1  christos  }
    279  1.1  christos  
    280  1.1  christos  profile:::tick-5s
    281  1.1  christos  /OPT_stats == 1/
    282  1.1  christos  {
    283  1.1  christos 	/* Print top 20 only */
    284  1.1  christos  	trunc(@vop_iocnt, 20);
    285  1.1  christos  	trunc(@vop_time, 20);
    286  1.1  christos 
    287  1.1  christos 	/* Display microseconds */
    288  1.1  christos  	normalize(@vop_time, 1000000);
    289  1.1  christos  	printf("\033[H\033[2J");
    290  1.1  christos  	printf("%-60s %10s\n", "VOP Physical IO", "Count");
    291  1.1  christos  	printa("%-60s %10@d\n", @vop_iocnt);
    292  1.1  christos  	printf("\n");
    293  1.1  christos  	printf("%-60s %10s\n", "VOP Count", "Count");
    294  1.1  christos  	printa("%-60s %10@d\n", @vop_cnt);
    295  1.1  christos  	printf("\n");
    296  1.1  christos  	printf("%-60s %10s\n", "VOP Wall Time", "mSeconds");
    297  1.1  christos  	printa("%-60s %10@d\n", @vop_time);
    298  1.1  christos 
    299  1.1  christos 	/* Clear data */
    300  1.1  christos  	trunc(@vop_iocnt);
    301  1.1  christos  	trunc(@vop_cnt);
    302  1.1  christos  	trunc(@vop_time);
    303  1.1  christos  }
    304  1.1  christos '
    305