rwsnoop revision 1.1 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 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