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