]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - cddl/contrib/dtracetoolkit/opensnoop
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / cddl / contrib / dtracetoolkit / opensnoop
1 #!/bin/sh
2 #
3 # opensnoop - snoop file opens as they occur.
4 #             Written using DTrace (Solaris 10 3/05).
5 #
6 # $Id: opensnoop 3 2007-08-01 10:50:08Z brendan $
7 #
8 # USAGE:        opensnoop [-a|-A|-ceghsvxZ] [-f pathname] [-n name] [-p PID]
9 #
10 #               opensnoop       # default output
11 #
12 #               -a              # print most data
13 #               -A              # dump all data, space delimited
14 #               -c              # print cwd of process
15 #               -e              # print errno value
16 #               -g              # print command arguments
17 #               -s              # print start time, us
18 #               -v              # print start time, string
19 #               -x              # only print failed opens
20 #               -Z              # print zonename
21 #               -f pathname     # file pathname to snoop
22 #               -n name         # command name to snoop
23 #               -p PID          # process ID to snoop
24 #       eg,
25 #               opensnoop -v                    # human readable timestamps
26 #               opensnoop -e                    # see error codes
27 #               opensnoop -f /etc/passwd        # snoop this file only
28 #       
29 # FIELDS:
30 #               ZONE            Zone name
31 #               UID             User ID
32 #               PID             Process ID
33 #               PPID            Parent Process ID
34 #               FD              file descriptor (-1 for error)
35 #               ERR             errno value (see /usr/include/sys/errno.h)
36 #               CWD             print current working directory of process
37 #               PATH            pathname for file open
38 #               COMM            command name for the process
39 #               ARGS            argument listing for the process
40 #               TIME            timestamp for the open event, us
41 #               STRTIME         timestamp for the open event, string
42 #
43 # SEE ALSO: truss, BSM auditing.
44 #
45 # COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
46 #
47 # CDDL HEADER START
48 #
49 #  The contents of this file are subject to the terms of the
50 #  Common Development and Distribution License, Version 1.0 only
51 #  (the "License").  You may not use this file except in compliance
52 #  with the License.
53 #
54 #  You can obtain a copy of the license at Docs/cddl1.txt
55 #  or http://www.opensolaris.org/os/licensing.
56 #  See the License for the specific language governing permissions
57 #  and limitations under the License.
58 #
59 # CDDL HEADER END
60 #
61 # Author: Brendan Gregg  [Sydney, Australia]
62 #
63 # 09-May-2004   Brendan Gregg   Created this.
64 # 21-Jan-2005      "      "     Wrapped in sh to provide options.
65 # 08-May-2005      "      "     Rewritten for performance.
66 # 14-May-2005      "      "     Added errno.
67 # 28-Jun-2005      "      "     Added cwd, zonename.
68 # 17-Sep-2005      "      "     Increased switchrate, fixed page fault bug.
69 # 16-Jan-2006      "      "     Added -n, -p.
70 # 16-Jan-2006      "      "     Last update.
71
72
73
74 ##############################
75 # --- Process Arguments ---
76 #
77
78 ### Default variables
79 opt_dump=0; opt_file=0; opt_time=0; opt_timestr=0; opt_args=0
80 opt_zone=0; opt_cwd=0; opt_failonly=0; opt_err=0; filter=0; pathname=.
81 opt_name=0; opt_pid=0; pname=.; pid=0
82
83 ### Process options
84 while getopts aAcef:ghn:p:svxZ name
85 do
86         case $name in
87         a)      opt_time=1; opt_timestr=1; opt_args=1; opt_err=1 ;;
88         A)      opt_dump=1 ;;
89         c)      opt_cwd=1 ;;
90         e)      opt_err=1 ;;
91         g)      opt_args=1 ;;
92         f)      opt_file=1; pathname=$OPTARG ;;
93         n)      opt_name=1; pname=$OPTARG ;;
94         p)      opt_pid=1; pid=$OPTARG ;;
95         s)      opt_time=1 ;;
96         v)      opt_timestr=1 ;;
97         x)      opt_failonly=1 ;;
98         Z)      opt_zone=1 ;;
99         h|?)    cat <<-END >&2
100                 USAGE: opensnoop [-a|-A|-ceghsvxZ] [-f pathname]
101                                  [-n name] [-p PID]
102                        opensnoop                # default output
103                                 -a              # print most data
104                                 -A              # dump all data, space delimited
105                                 -c              # print cwd of process
106                                 -e              # print errno value
107                                 -g              # print command arguments
108                                 -s              # print start time, us
109                                 -v              # print start time, string
110                                 -x              # only print failed opens
111                                 -Z              # print zonename
112                                 -f pathname     # pathname name to snoop
113                                 -n name         # process name to snoop
114                                 -p PID          # process ID to snoop
115                   eg,
116                        opensnoop -v             # human readable timestamps
117                        opensnoop -e             # see error codes
118                        opensnoop -f /etc/motd   # snoop this file only
119                 END
120                 exit 1
121         esac
122 done
123
124 ### Option logic
125 if [ $opt_dump -eq 1 ]; then
126         opt_zone=0; opt_cwd=0; opt_time=0; opt_timestr=0; opt_args=2 
127 fi
128 if [ $opt_name -eq 1 -o $opt_pid -eq 1 ]; then
129         filter=1
130 fi
131
132
133 #################################
134 # --- Main Program, DTrace ---
135 #
136 /usr/sbin/dtrace -n '
137  /*
138   * Command line arguments
139   */
140  inline int OPT_dump     = '$opt_dump';
141  inline int OPT_file     = '$opt_file';
142  inline int OPT_args     = '$opt_args';
143  inline int OPT_cwd      = '$opt_cwd';
144  inline int OPT_err      = '$opt_err';
145  inline int OPT_zone     = '$opt_zone';
146  inline int OPT_time     = '$opt_time';
147  inline int OPT_timestr  = '$opt_timestr';
148  inline int OPT_failonly = '$opt_failonly';
149  inline int OPT_pid      = '$opt_pid';
150  inline int OPT_name     = '$opt_name';
151  inline int FILTER       = '$filter';
152  inline int PID          = '$pid';
153  inline string PATHNAME  = "'$pathname'";
154  inline string NAME      = "'$pname'";
155  
156  #pragma D option quiet
157  #pragma D option switchrate=10hz
158  
159  /*
160   * Print header
161   */
162  dtrace:::BEGIN 
163  {
164         /* 
165          * ternary operators are used to improve performance. 
166          * OPT_args is unusual in that it can have one of three values.
167          */
168  
169         /* print optional headers */
170         OPT_time ? printf("%-14s ", "TIME") : 1;
171         OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
172         OPT_zone ? printf("%-10s ", "ZONE") : 1;
173
174         /* print dump headers */
175         OPT_dump ? printf("%s %s %s %s %s %s %s %s %s %s %s", "ZONE",
176             "TIME", "UID", "PID", "PPID", "COMM", "FD", "ERR", "CWD", 
177             "PATH", "ARGS") : printf("%5s %6s ","UID","PID");
178         
179         /* print main headers */
180         OPT_args == 0 ? printf("%-12s ", "COMM") : 1;
181         OPT_dump == 0 ? printf("%3s ", "FD") : 1;
182         OPT_err ? printf("%3s ", "ERR") : 1;
183         OPT_cwd ? printf("%-20s ", "CWD") : 1;
184         OPT_dump == 0 ? printf("%-20s ", "PATH") : 1;
185         OPT_args == 1 ? printf("%s", "ARGS") : 1;
186         printf("\n");
187  }
188
189  /*
190   * Print open event
191   */
192  syscall::open:entry
193  {
194         /* save pathname */
195         self->pathp = arg0;
196
197         /* default is to trace unless filtering */
198         self->ok = FILTER ? 0 : 1;
199
200         /* check each filter */
201         (OPT_name == 1 && NAME == execname) ? self->ok = 1 : 1;
202         (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1;
203         /* OPT_file is checked on return to ensure pathp is mapped */
204  }
205
206  syscall::open:return
207  /self->ok && (! OPT_failonly || (int)arg0 < 0) && 
208  ((OPT_file == 0) || (OPT_file == 1 && PATHNAME == copyinstr(self->pathp)))/
209  {
210         /* print optional fields */
211         OPT_time ? printf("%-14d ", timestamp/1000) : 1;
212         OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
213         OPT_zone ? printf("%-10s ", zonename) : 1;
214
215         /* print dump fields */
216         OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %s %S", zonename,
217             timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno,
218             cwd, copyinstr(self->pathp), curpsinfo->pr_psargs) :
219             printf("%5d %6d ", uid, pid);
220
221         /* print main fields */
222         OPT_args == 0 ? printf("%-12s ", execname) : 1;
223         OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1;
224         OPT_err ? printf("%3d ", errno) : 1;
225         OPT_cwd ? printf("%-20s ", cwd) : 1;
226         OPT_dump == 0 ? printf("%-20s ", copyinstr(self->pathp)) : 1;
227         OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1;
228         printf("\n");
229
230         /* cleanup */
231         self->pathp = 0;
232         self->ok = 0;
233  }
234
235  /* 
236   * Cleanup 
237   */
238  syscall::open:return
239  /self->ok/
240  {
241         self->pathp = 0;
242         self->ok = 0;
243  }
244 '