1 1.1 christos #!/bin/sh 2 1.1 christos # 3 1.1 christos # rwsnoop - snoop read/write events. 4 1.1 christos # Originally written using DTrace (Solaris 10 3/05). 5 1.1 christos # 6 1.1 christos # This is measuring reads and writes at the application level. This matches 7 1.1 christos # the syscalls read, and write. 8 1.1 christos # 9 1.1 christos # $Id: rwsnoop,v 1.1.1.1 2015/09/30 22:01:06 christos Exp $ 10 1.1 christos # 11 1.1 christos # USAGE: rwsnoop [-jPtvZ] [-n name] [-p pid] 12 1.1 christos # 13 1.1 christos # rwsnoop # default output 14 1.1 christos # 15 1.1 christos # -P # print parent process ID 16 1.1 christos # -t # print timestamp, us 17 1.1 christos # -v # print time, string 18 1.1 christos # -J # print jail ID 19 1.1 christos # -n name # this process name only 20 1.1 christos # -p PID # this PID only 21 1.1 christos # eg, 22 1.1 christos # rwsnoop -J # print jail ID 23 1.1 christos # rwsnoop -n bash # monitor processes named "bash" 24 1.1 christos # rwsnoop > out.txt # recommended 25 1.1 christos # 26 1.1 christos # NOTE: 27 1.1 christos # rwsnoop usually prints plenty of output, which itself will cause 28 1.1 christos # more output. It can be better to redirect the output of rwsnoop 29 1.1 christos # to a file to prevent this. 30 1.1 christos # 31 1.1 christos # FIELDS: 32 1.1 christos # TIME Timestamp, us 33 1.1 christos # TIMESTR Time, string 34 1.1 christos # JAIL JAIL ID 35 1.1 christos # UID User ID 36 1.1 christos # PID Process ID 37 1.1 christos # PPID Parent Process ID 38 1.1 christos # CMD Process name 39 1.1 christos # D Direction, Read or Write 40 1.1 christos # BYTES Total bytes during sample, -1 for error 41 1.1 christos # FILE Filename, if file based 42 1.1 christos # 43 1.1 christos # Reads and writes that are not file based, for example with sockets, will 44 1.1 christos # print "<unknown>" as the filename. 45 1.1 christos # 46 1.1 christos # SEE ALSO: rwtop 47 1.1 christos # 48 1.1 christos # COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 49 1.1 christos # 50 1.1 christos # CDDL HEADER START 51 1.1 christos # 52 1.1 christos # The contents of this file are subject to the terms of the 53 1.1 christos # Common Development and Distribution License, Version 1.0 only 54 1.1 christos # (the "License"). You may not use this file except in compliance 55 1.1 christos # with the License. 56 1.1 christos # 57 1.1 christos # You can obtain a copy of the license at Docs/cddl1.txt 58 1.1 christos # or http://www.opensolaris.org/os/licensing. 59 1.1 christos # See the License for the specific language governing permissions 60 1.1 christos # and limitations under the License. 61 1.1 christos # 62 1.1 christos # CDDL HEADER END 63 1.1 christos # 64 1.1 christos # TODO: 65 1.1 christos # Track readv and writev. 66 1.1 christos # 67 1.1 christos # Author: Brendan Gregg [Sydney, Australia] 68 1.1 christos # 69 1.1 christos # 24-Jul-2005 Brendan Gregg Created this. 70 1.1 christos # 17-Sep-2005 " " Increased switchrate. 71 1.1 christos # 17-Sep-2005 " " Last update. 72 1.1 christos # 26-Jul-2014 George Neville-Neil Port to FreeBSD 73 1.1 christos # 74 1.1 christos 75 1.1 christos 76 1.1 christos ############################## 77 1.1 christos # --- Process Arguments --- 78 1.1 christos # 79 1.1 christos 80 1.1 christos ### default variables 81 1.1 christos opt_name=0; opt_pid=0; opt_jailid=0; opt_time=0; opt_timestr=0 82 1.1 christos opt_bytes=1; filter=0; pname=.; pid=0; opt_ppid=0; 83 1.1 christos 84 1.1 christos ### process options 85 1.1 christos while getopts n:Pp:jtvZ name 86 1.1 christos do 87 1.1 christos case $name in 88 1.1 christos n) opt_name=1; pname=$OPTARG ;; 89 1.1 christos p) opt_pid=1; pid=$OPTARG ;; 90 1.1 christos P) opt_ppid=1 ;; 91 1.1 christos t) opt_time=1 ;; 92 1.1 christos v) opt_timestr=1 ;; 93 1.1 christos J) opt_jailid=1 ;; 94 1.1 christos h|?) cat <<-END >&2 95 1.1 christos USAGE: rwsnoop [-jPtvZ] [-n name] [-p pid] 96 1.1 christos 97 1.1 christos -P # print parent process ID 98 1.1 christos -t # print timestamp, us 99 1.1 christos -v # print time, string 100 1.1 christos -J # print jail ID 101 1.1 christos -n name # this process name only 102 1.1 christos -p PID # this PID only 103 1.1 christos eg, 104 1.1 christos rwsnoop # default output 105 1.1 christos rwsnoop -J # print jail ID 106 1.1 christos rwsnoop -n bash # monitor processes named "bash" 107 1.1 christos END 108 1.1 christos exit 1 109 1.1 christos esac 110 1.1 christos done 111 1.1 christos 112 1.1 christos shift $(( $OPTIND - 1 )) 113 1.1 christos 114 1.1 christos ### option logic 115 1.1 christos if [ $opt_name -ne 0 ]; then 116 1.1 christos filter=1 117 1.1 christos fi 118 1.1 christos 119 1.1 christos if [ $opt_pid -ne 0 ]; then 120 1.1 christos filter=1 121 1.1 christos fi 122 1.1 christos 123 1.1 christos ################################# 124 1.1 christos # --- Main Program, DTrace --- 125 1.1 christos # 126 1.1 christos /usr/sbin/dtrace -n ' 127 1.1 christos /* 128 1.1 christos * Command line arguments 129 1.1 christos */ 130 1.1 christos inline int OPT_jailid = '$opt_jailid'; 131 1.1 christos inline int OPT_bytes = '$opt_bytes'; 132 1.1 christos inline int OPT_name = '$opt_name'; 133 1.1 christos inline int OPT_ppid = '$opt_ppid'; 134 1.1 christos inline int OPT_pid = '$opt_pid'; 135 1.1 christos inline int OPT_time = '$opt_time'; 136 1.1 christos inline int OPT_timestr = '$opt_timestr'; 137 1.1 christos inline int FILTER = '$filter'; 138 1.1 christos inline int PID = '$pid'; 139 1.1 christos inline string NAME = "'$pname'"; 140 1.1 christos 141 1.1 christos #pragma D option quiet 142 1.1 christos #pragma D option switchrate=10hz 143 1.1 christos 144 1.1 christos /* 145 1.1 christos * Print header 146 1.1 christos */ 147 1.1 christos dtrace:::BEGIN 148 1.1 christos { 149 1.1 christos /* print header */ 150 1.1 christos OPT_time ? printf("%-14s ", "TIME") : 1; 151 1.1 christos OPT_timestr ? printf("%-20s ", "TIMESTR") : 1; 152 1.1 christos OPT_jailid ? printf("%5s ", "JAILID") : 1; 153 1.1 christos OPT_ppid ? printf("%6s ", "PPID") : 1; 154 1.1 christos printf("%5s %6s %-12s %4s %1s %7s\n", 155 1.1 christos "UID", "PID", "CMD", "FD", "D", "BYTES"); 156 1.1 christos } 157 1.1 christos 158 1.1 christos /* 159 1.1 christos * Check event is being traced 160 1.1 christos */ 161 1.1 christos syscall::*read:entry, 162 1.1 christos syscall::*write:entry 163 1.1 christos /pid != $pid/ 164 1.1 christos { 165 1.1 christos /* default is to trace unless filtering, */ 166 1.1 christos self->ok = FILTER ? 0 : 1; 167 1.1 christos 168 1.1 christos /* check each filter, */ 169 1.1 christos (OPT_name == 1 && NAME == execname)? self->ok = 1 : 1; 170 1.1 christos (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1; 171 1.1 christos 172 1.1 christos /* save file descriptor */ 173 1.1 christos self->fd = self->ok ? arg0 : 0; 174 1.1 christos } 175 1.1 christos 176 1.1 christos /* 177 1.1 christos * Save read details 178 1.1 christos */ 179 1.1 christos syscall::*read:return 180 1.1 christos /self->ok/ 181 1.1 christos { 182 1.1 christos self->rw = "R"; 183 1.1 christos self->size = arg0; 184 1.1 christos } 185 1.1 christos 186 1.1 christos /* 187 1.1 christos * Save write details 188 1.1 christos */ 189 1.1 christos syscall::*write:entry 190 1.1 christos /self->ok/ 191 1.1 christos { 192 1.1 christos self->rw = "W"; 193 1.1 christos self->size = arg2; 194 1.1 christos } 195 1.1 christos 196 1.1 christos /* 197 1.1 christos * Process event 198 1.1 christos */ 199 1.1 christos syscall::*read:return, 200 1.1 christos syscall::*write:entry 201 1.1 christos /self->ok/ 202 1.1 christos { 203 1.1 christos /* 204 1.1 christos * Fetch filename 205 1.1 christos * XXX Not yet implemented. 206 1.1 christos */ 207 1.1 christos /* 208 1.1 christos 209 1.1 christos this->filistp = curthread->t_procp->p_user.u_finfo.fi_list; 210 1.1 christos this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp + 211 1.1 christos (uint64_t)self->fd * (uint64_t)sizeof(uf_entry_t)); 212 1.1 christos this->filep = this->ufentryp->uf_file; 213 1.1 christos this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0; 214 1.1 christos self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ? 215 1.1 christos cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>"; 216 1.1 christos */ 217 1.1 christos /* 218 1.1 christos * Print details 219 1.1 christos */ 220 1.1 christos OPT_time ? printf("%-14d ", timestamp / 1000) : 1; 221 1.1 christos OPT_timestr ? printf("%-20Y ", walltimestamp) : 1; 222 1.1 christos OPT_jailid ? printf("%5d ", curpsinfo->pr_jailid) : 1; 223 1.1 christos OPT_ppid ? printf("%6d ", ppid) : 1; 224 1.1 christos printf("%5d %6d %-12.12s %4d %1s %7d\n", 225 1.1 christos uid, pid, execname, self->fd, self->rw, (int)self->size); 226 1.1 christos 227 1.1 christos self->ok = 0; 228 1.1 christos self->fd = 0; 229 1.1 christos self->rw = 0; 230 1.1 christos self->size = 0; 231 1.1 christos self->vpath = 0; 232 1.1 christos } 233 1.1 christos ' 234