1 #!/bin/sh 2 # 3 # opensnoop - snoop file opens as they occur. 4 # Written using DTrace (Solaris 10 3/05). 5 # 6 # $Id: opensnoop,v 1.1.1.1 2015/09/30 22:01:06 christos Exp $ 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 ' 245