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