1139815Simp#!/bin/sh 2206361Sjoel# 375332Sbp# opensnoop - snoop file opens as they occur. 475332Sbp# Written using DTrace (Solaris 10 3/05). 575332Sbp# 675332Sbp# $Id: opensnoop 3 2007-08-01 10:50:08Z brendan $ 775332Sbp# 875332Sbp# USAGE: opensnoop [-a|-A|-ceghsvxZ] [-f pathname] [-n name] [-p PID] 975332Sbp# 1075332Sbp# opensnoop # default output 1175332Sbp# 1275332Sbp# -a # print most data 1375332Sbp# -A # dump all data, space delimited 1475332Sbp# -c # print cwd of process 1575332Sbp# -e # print errno value 1675332Sbp# -g # print command arguments 1775332Sbp# -s # print start time, us 1875332Sbp# -v # print start time, string 1975332Sbp# -x # only print failed opens 2075332Sbp# -Z # print zonename 2175332Sbp# -f pathname # file pathname to snoop 2275332Sbp# -n name # command name to snoop 2375332Sbp# -p PID # process ID to snoop 2475332Sbp# eg, 2575332Sbp# opensnoop -v # human readable timestamps 26116189Sobrien# opensnoop -e # see error codes 27116189Sobrien# opensnoop -f /etc/passwd # snoop this file only 28116189Sobrien# 29116189Sobrien# FIELDS: 3075332Sbp# ZONE Zone name 3175332Sbp# UID User ID 3275332Sbp# PID Process ID 3375332Sbp# PPID Parent Process ID 3475332Sbp# FD file descriptor (-1 for error) 35120492Sfjoe# ERR errno value (see /usr/include/sys/errno.h) 36185652Sjhb# CWD print current working directory of process 37120492Sfjoe# PATH pathname for file open 3875332Sbp# COMM command name for the process 3975332Sbp# ARGS argument listing for the process 4075332Sbp# TIME timestamp for the open event, us 4175332Sbp# STRTIME timestamp for the open event, string 4275332Sbp# 4375332Sbp# SEE ALSO: truss, BSM auditing. 4475332Sbp# 45151897Srwatson# COPYRIGHT: Copyright (c) 2006 Brendan Gregg. 46227293Sed# 4775332Sbp# CDDL HEADER START 48120492Sfjoe# 4975332Sbp# The contents of this file are subject to the terms of the 50185652Sjhb# Common Development and Distribution License, Version 1.0 only 51185652Sjhb# (the "License"). You may not use this file except in compliance 5275332Sbp# with the License. 5375332Sbp# 5475332Sbp# You can obtain a copy of the license at Docs/cddl1.txt 5575332Sbp# or http://www.opensolaris.org/os/licensing. 5675332Sbp# See the License for the specific language governing permissions 5775332Sbp# and limitations under the License. 5875332Sbp# 5975332Sbp# CDDL HEADER END 6075332Sbp# 6175332Sbp# Author: Brendan Gregg [Sydney, Australia] 6275332Sbp# 6375332Sbp# 09-May-2004 Brendan Gregg Created this. 6475332Sbp# 21-Jan-2005 " " Wrapped in sh to provide options. 6575332Sbp# 08-May-2005 " " Rewritten for performance. 6675332Sbp# 14-May-2005 " " Added errno. 6775332Sbp# 28-Jun-2005 " " Added cwd, zonename. 6875332Sbp# 17-Sep-2005 " " Increased switchrate, fixed page fault bug. 6975332Sbp# 16-Jan-2006 " " Added -n, -p. 7075332Sbp# 16-Jan-2006 " " Last update. 7175332Sbp# 7275332Sbp 7375332Sbp 7475332Sbp############################## 7575332Sbp# --- Process Arguments --- 7675332Sbp# 7775332Sbp 7875332Sbp### Default variables 7975332Sbpopt_dump=0; opt_file=0; opt_time=0; opt_timestr=0; opt_args=0 8075332Sbpopt_zone=0; opt_cwd=0; opt_failonly=0; opt_err=0; filter=0; pathname=. 8175332Sbpopt_name=0; opt_pid=0; pname=.; pid=0 8275332Sbp 8375332Sbp### Process options 8475332Sbpwhile getopts aAcef:ghn:p:svxZ name 8575332Sbpdo 86185652Sjhb case $name in 87236899Smjg a) opt_time=1; opt_timestr=1; opt_args=1; opt_err=1 ;; 88236899Smjg A) opt_dump=1 ;; 89236899Smjg c) opt_cwd=1 ;; 9075332Sbp e) opt_err=1 ;; 91236899Smjg g) opt_args=1 ;; 92185652Sjhb f) opt_file=1; pathname=$OPTARG ;; 93185652Sjhb n) opt_name=1; pname=$OPTARG ;; 94185652Sjhb p) opt_pid=1; pid=$OPTARG ;; 9575332Sbp s) opt_time=1 ;; 96185652Sjhb v) opt_timestr=1 ;; 97185652Sjhb x) opt_failonly=1 ;; 9875332Sbp Z) opt_zone=1 ;; 9975332Sbp h|?) cat <<-END >&2 10075332Sbp USAGE: opensnoop [-a|-A|-ceghsvxZ] [-f pathname] 10175332Sbp [-n name] [-p PID] 10275332Sbp opensnoop # default output 10375332Sbp -a # print most data 10475332Sbp -A # dump all data, space delimited 10575332Sbp -c # print cwd of process 10675332Sbp -e # print errno value 10775332Sbp -g # print command arguments 10875332Sbp -s # print start time, us 109185652Sjhb -v # print start time, string 11075332Sbp -x # only print failed opens 11175332Sbp -Z # print zonename 11275332Sbp -f pathname # pathname name to snoop 11375332Sbp -n name # process name to snoop 11475332Sbp -p PID # process ID to snoop 11575332Sbp eg, 11675332Sbp opensnoop -v # human readable timestamps 11775332Sbp opensnoop -e # see error codes 11875332Sbp opensnoop -f /etc/motd # snoop this file only 11975332Sbp END 12075332Sbp exit 1 12175332Sbp esac 12275332Sbpdone 12375332Sbp 12475332Sbp### Option logic 12575332Sbpif [ $opt_dump -eq 1 ]; then 12675332Sbp opt_zone=0; opt_cwd=0; opt_time=0; opt_timestr=0; opt_args=2 12775332Sbpfi 12875332Sbpif [ $opt_name -eq 1 -o $opt_pid -eq 1 ]; then 12975332Sbp filter=1 13075332Sbpfi 13175332Sbp 13275332Sbp 13375332Sbp################################# 13475332Sbp# --- Main Program, DTrace --- 13575332Sbp# 13675332Sbp/usr/sbin/dtrace -n ' 13775332Sbp /* 138235712Skevlo * Command line arguments 13975332Sbp */ 14075332Sbp inline int OPT_dump = '$opt_dump'; 14175332Sbp inline int OPT_file = '$opt_file'; 14275332Sbp inline int OPT_args = '$opt_args'; 14375332Sbp inline int OPT_cwd = '$opt_cwd'; 14475332Sbp inline int OPT_err = '$opt_err'; 14575332Sbp inline int OPT_zone = '$opt_zone'; 14675332Sbp inline int OPT_time = '$opt_time'; 14775332Sbp inline int OPT_timestr = '$opt_timestr'; 14875332Sbp inline int OPT_failonly = '$opt_failonly'; 14975332Sbp inline int OPT_pid = '$opt_pid'; 15075332Sbp inline int OPT_name = '$opt_name'; 15175332Sbp inline int FILTER = '$filter'; 15275332Sbp inline int PID = '$pid'; 15375332Sbp inline string PATHNAME = "'$pathname'"; 15475332Sbp inline string NAME = "'$pname'"; 15575332Sbp 15675332Sbp #pragma D option quiet 15775332Sbp #pragma D option switchrate=10hz 15875332Sbp 15975332Sbp /* 16075332Sbp * Print header 16175332Sbp */ 16275332Sbp dtrace:::BEGIN 16375332Sbp { 16475332Sbp /* 16575332Sbp * ternary operators are used to improve performance. 16675332Sbp * OPT_args is unusual in that it can have one of three values. 16775332Sbp */ 16875332Sbp 16975332Sbp /* print optional headers */ 17075332Sbp OPT_time ? printf("%-14s ", "TIME") : 1; 171267980Sjhb OPT_timestr ? printf("%-20s ", "STRTIME") : 1; 172267980Sjhb OPT_zone ? printf("%-10s ", "ZONE") : 1; 17375332Sbp 17475332Sbp /* print dump headers */ 17575332Sbp OPT_dump ? printf("%s %s %s %s %s %s %s %s %s %s %s", "ZONE", 17675332Sbp "TIME", "UID", "PID", "PPID", "COMM", "FD", "ERR", "CWD", 17775332Sbp "PATH", "ARGS") : printf("%5s %6s ","UID","PID"); 17875332Sbp 17975332Sbp /* print main headers */ 18075332Sbp OPT_args == 0 ? printf("%-12s ", "COMM") : 1; 18175332Sbp OPT_dump == 0 ? printf("%3s ", "FD") : 1; 18275332Sbp OPT_err ? printf("%3s ", "ERR") : 1; 18375332Sbp OPT_cwd ? printf("%-20s ", "CWD") : 1; 18475332Sbp OPT_dump == 0 ? printf("%-20s ", "PATH") : 1; 18575332Sbp OPT_args == 1 ? printf("%s", "ARGS") : 1; 18675332Sbp printf("\n"); 18775332Sbp } 18875332Sbp 18975332Sbp /* 19075332Sbp * Print open event 19175332Sbp */ 19275332Sbp syscall::open:entry 19375332Sbp { 19475332Sbp /* save pathname */ 19575332Sbp self->pathp = arg0; 19675332Sbp 19775332Sbp /* default is to trace unless filtering */ 19875332Sbp self->ok = FILTER ? 0 : 1; 199111119Simp 20075332Sbp /* check each filter */ 20175332Sbp (OPT_name == 1 && NAME == execname) ? self->ok = 1 : 1; 20275332Sbp (OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1; 20375332Sbp /* OPT_file is checked on return to ensure pathp is mapped */ 20475332Sbp } 20575332Sbp 20675332Sbp syscall::open:return 20775332Sbp /self->ok && (! OPT_failonly || (int)arg0 < 0) && 20875332Sbp ((OPT_file == 0) || (OPT_file == 1 && PATHNAME == copyinstr(self->pathp)))/ 20975332Sbp { 21075332Sbp /* print optional fields */ 21175332Sbp OPT_time ? printf("%-14d ", timestamp/1000) : 1; 21275332Sbp OPT_timestr ? printf("%-20Y ", walltimestamp) : 1; 21375332Sbp OPT_zone ? printf("%-10s ", zonename) : 1; 21475332Sbp 21575332Sbp /* print dump fields */ 21675332Sbp OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %s %S", zonename, 21775332Sbp timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno, 21875332Sbp cwd, copyinstr(self->pathp), curpsinfo->pr_psargs) : 21975332Sbp printf("%5d %6d ", uid, pid); 22075332Sbp 22175332Sbp /* print main fields */ 22275332Sbp OPT_args == 0 ? printf("%-12s ", execname) : 1; 22375332Sbp OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1; 22475332Sbp OPT_err ? printf("%3d ", errno) : 1; 22575332Sbp OPT_cwd ? printf("%-20s ", cwd) : 1; 22675332Sbp OPT_dump == 0 ? printf("%-20s ", copyinstr(self->pathp)) : 1; 22775332Sbp OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1; 22875332Sbp printf("\n"); 22975332Sbp 23075332Sbp /* cleanup */ 23175332Sbp self->pathp = 0; 23275332Sbp self->ok = 0; 23375332Sbp } 23475332Sbp 23575332Sbp /* 23675332Sbp * Cleanup 23775332Sbp */ 23875332Sbp syscall::open:return 23975332Sbp /self->ok/ 24075332Sbp { 24175332Sbp self->pathp = 0; 24275332Sbp self->ok = 0; 24375332Sbp } 24475332Sbp' 24575332Sbp