Created
August 4, 2017 01:58
-
-
Save nikhilm/05b97b2131ada363fc1936a1b21aa110 to your computer and use it in GitHub Desktop.
opencloseunlinksnoop - modified from opensnoop on OSX to also track unlink() and close()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# #!/usr/bin/sh | |
# | |
# opensnoop - snoop file opens as they occur. | |
# Written using DTrace (Solaris 10 3/05). | |
# | |
# 12-Jan-2006, ver 1.60 | |
# | |
# USAGE: opensnoop [-a|-A|-ceghstvxZ] [-f pathname] [-n name] [-p PID] | |
# | |
# opensnoop # default output | |
# | |
# -a # print most data | |
# -A # dump all data, space delimited | |
# -c # print cwd of process | |
# -e # print errno value | |
# -g # print command arguments | |
# -F # print the flags passed to open | |
# -s # print start time, us | |
# -t # print user stack trace | |
# -v # print start time, string | |
# -x # only print failed opens | |
# -Z # print zonename | |
# -f pathname # file pathname to snoop | |
# -n name # command name to snoop | |
# -p PID # process ID to snoop | |
# eg, | |
# opensnoop -v # human readable timestamps | |
# opensnoop -e # see error codes | |
# opensnoop -f /etc/passwd # snoop this file only | |
# | |
# FIELDS: | |
# ZONE Zone name | |
# UID User ID | |
# PID Process ID | |
# PPID Parent Process ID | |
# FD file descriptor (-1 for error) | |
# FLAGS flags passed to open | |
# ERR errno value (see /usr/include/sys/errno.h) | |
# CWD print current working directory of process | |
# PATH pathname for file open | |
# COMM command name for the process | |
# ARGS argument listing for the process | |
# TIME timestamp for the open event, us | |
# STRTIME timestamp for the open event, string | |
# | |
# SEE ALSO: truss, BSM auditing. | |
# | |
# COPYRIGHT: Copyright (c) 2006 Brendan Gregg. | |
# | |
# CDDL HEADER START | |
# | |
# The contents of this file are subject to the terms of the | |
# Common Development and Distribution License, Version 1.0 only | |
# (the "License"). You may not use this file except in compliance | |
# with the License. | |
# | |
# You can obtain a copy of the license at Docs/cddl1.txt | |
# or http://www.opensolaris.org/os/licensing. | |
# See the License for the specific language governing permissions | |
# and limitations under the License. | |
# | |
# CDDL HEADER END | |
# | |
# Author: Brendan Gregg [Sydney, Australia] | |
# | |
# 09-May-2004 Brendan Gregg Created this. | |
# 21-Jan-2005 " " Wrapped in sh to provide options. | |
# 08-May-2005 " " Rewritten for performance. | |
# 14-May-2005 " " Added errno. | |
# 28-Jun-2005 " " Added cwd, zonename. | |
# 17-Sep-2005 " " Increased switchrate, fixed page fault bug. | |
# 16-Jan-2006 " " Added -n, -p. | |
# | |
############################## | |
# --- Process Arguments --- | |
# | |
### Default variables | |
opt_dump=0; opt_file=0; opt_time=0; opt_timestr=0; opt_args=0 | |
opt_zone=0; opt_cwd=0; opt_failonly=0; opt_err=0; filter=0; pathname=. | |
opt_name=0; opt_pid=0; pname=.; pid=0; opt_trace=0; opt_flags=0; | |
### Process options | |
while getopts aAceFf:ghn:p:stvxZ name | |
do | |
case $name in | |
a) opt_time=1; opt_timestr=1; opt_args=1; opt_err=1 ;; | |
A) opt_dump=1 ;; | |
c) opt_cwd=1 ;; | |
e) opt_err=1 ;; | |
g) opt_args=1 ;; | |
F) opt_flags=1 ;; | |
f) opt_file=1; pathname=$OPTARG ;; | |
n) opt_name=1; pname=$OPTARG ;; | |
p) opt_pid=1; pid=$OPTARG ;; | |
s) opt_time=1 ;; | |
t) opt_trace=1 ;; | |
v) opt_timestr=1 ;; | |
x) opt_failonly=1 ;; | |
Z) opt_zone=1 ;; | |
h|?) cat <<-END >&2 | |
USAGE: opensnoop [-a|-A|-ceghsvxZ] [-f pathname] | |
[-n name] [-p PID] | |
opensnoop # default output | |
-a # print most data | |
-A # dump all data, space delimited | |
-c # print cwd of process | |
-e # print errno value | |
-F # print the flags passed to open | |
-g # print command arguments | |
-s # print start time, us | |
-t # print user stack trace | |
-v # print start time, string | |
-x # only print failed opens | |
-Z # print zonename | |
-f pathname # pathname name to snoop | |
-n name # process name to snoop | |
-p PID # process ID to snoop | |
eg, | |
opensnoop -v # human readable timestamps | |
opensnoop -e # see error codes | |
opensnoop -f /etc/motd # snoop this file only | |
END | |
exit 1 | |
esac | |
done | |
### Option logic | |
if [ $opt_dump -eq 1 ]; then | |
opt_zone=0; opt_cwd=0; opt_time=0; opt_timestr=0; opt_args=2 | |
fi | |
if [ $opt_name -eq 1 -o $opt_pid -eq 1 ]; then | |
filter=1 | |
fi | |
################################# | |
# --- Main Program, DTrace --- | |
# | |
/usr/sbin/dtrace -n ' | |
/* | |
* Command line arguments | |
*/ | |
inline int OPT_dump = '$opt_dump'; | |
inline int OPT_file = '$opt_file'; | |
inline int OPT_args = '$opt_args'; | |
inline int OPT_cwd = '$opt_cwd'; | |
inline int OPT_err = '$opt_err'; | |
inline int OPT_zone = '$opt_zone'; | |
inline int OPT_time = '$opt_time'; | |
inline int OPT_timestr = '$opt_timestr'; | |
inline int OPT_failonly = '$opt_failonly'; | |
inline int OPT_pid = '$opt_pid'; | |
inline int OPT_name = '$opt_name'; | |
inline int OPT_trace = '$opt_trace'; | |
inline int OPT_flags = '$opt_flags'; | |
inline int FILTER = '$filter'; | |
inline int PID = '$pid'; | |
inline string PATHNAME = "'$pathname'"; | |
inline string NAME = "'$pname'"; | |
#pragma D option quiet | |
#pragma D option switchrate=10hz | |
/* | |
* Print header | |
*/ | |
dtrace:::BEGIN | |
{ | |
/* | |
* ternary operators are used to improve performance. | |
* OPT_args is unusual in that it can have one of three values. | |
*/ | |
/* print optional headers */ | |
OPT_time ? printf("%-14s ", "TIME") : 1; | |
OPT_timestr ? printf("%-20s ", "STRTIME") : 1; | |
OPT_zone ? printf("%-10s ", "ZONE") : 1; | |
/* print dump headers */ | |
OPT_dump ? printf("%s %s %s %s %s %s %s %s %s %s %s", "ZONE", | |
"TIME", "UID", "PID", "PPID", "COMM", "FD", "ERR", "CWD", | |
"PATH", "ARGS") : printf("%5s %6s ","UID","PID"); | |
/* print main headers */ | |
OPT_args == 0 ? printf("%-12s ", "COMM") : 1; | |
OPT_dump == 0 ? printf("%3s ", "FD") : 1; | |
OPT_flags == 1 ? printf("%10s ", "FLAGS") : 1; | |
OPT_err ? printf("%3s ", "ERR") : 1; | |
OPT_cwd ? printf("%-20s ", "CWD") : 1; | |
OPT_dump == 0 ? printf("%-20s ", "PATH") : 1; | |
OPT_args == 1 ? printf("%s", "ARGS") : 1; | |
printf("\n"); | |
} | |
/* | |
* Print open event | |
*/ | |
/* SOLARIS: syscall::open:entry, syscall::open64:entry */ | |
syscall::open:entry, syscall::open_nocancel:entry, syscall::open_extended:entry | |
{ | |
/* save pathname */ | |
self->pathp = arg0; | |
/* save flags */ | |
self->flags = arg1; | |
/* default is to trace unless filtering */ | |
self->ok = FILTER ? 0 : 1; | |
/* check each filter */ | |
(OPT_name == 1 && NAME == strstr(NAME, execname))? self->ok = 1 : 1; | |
(OPT_name == 1 && execname == strstr(execname, NAME))? self->ok = 1 : 1; | |
(OPT_pid == 1 && PID == pid) ? self->ok = 1 : 1; | |
/* OPT_file is checked on return to ensure pathp is mapped */ | |
} | |
/* SOLARIS: syscall::open:return, syscall::open64:return */ | |
syscall::open:return, syscall::open_nocancel:return, syscall::open_extended:return | |
/self->ok && (! OPT_failonly || (int)arg0 < 0) && | |
((OPT_file == 0) || (OPT_file == 1 && PATHNAME == copyinstr(self->pathp)))/ | |
{ | |
/* print optional fields */ | |
OPT_time ? printf("%-14d ", timestamp/1000) : 1; | |
OPT_timestr ? printf("%-20Y ", walltimestamp) : 1; | |
OPT_zone ? printf("%-10s ", zonename) : 1; | |
/* print dump fields */ | |
OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %s %S", zonename, | |
timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno, | |
cwd, copyinstr(self->pathp), curpsinfo->pr_psargs) : | |
printf("%5d %6d ", uid, pid); | |
/* print main fields */ | |
OPT_args == 0 ? printf("%-12s ", execname) : 1; | |
OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1; | |
OPT_flags ? printf("0x%08x ", self->flags) : 1; | |
OPT_err ? printf("%3d ", errno) : 1; | |
OPT_cwd ? printf("%-20s ", cwd) : 1; | |
OPT_dump == 0 ? printf("%-20s ", copyinstr(self->pathp)) : 1; | |
OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1; | |
OPT_trace == 1 ? ustack() : 1; | |
printf("\n"); | |
/* cleanup */ | |
self->pathp = 0; | |
self->ok = 0; | |
} | |
syscall::close:entry | |
{ | |
self->close_ok = FILTER ? 0 : 1; | |
(OPT_name == 1 && NAME == strstr(NAME, execname))? self->close_ok = 1 : 1; | |
(OPT_name == 1 && execname == strstr(execname, NAME))? self->close_ok = 1 : 1; | |
(OPT_pid == 1 && PID == pid) ? self->close_ok = 1 : 1; | |
self->close_fd = arg0; | |
} | |
syscall::close:return | |
/self->close_ok/ | |
{ | |
/* print optional fields */ | |
OPT_time ? printf("%-14d ", timestamp/1000) : 1; | |
OPT_timestr ? printf("%-20Y ", walltimestamp) : 1; | |
OPT_zone ? printf("%-10s ", zonename) : 1; | |
/* print dump fields */ | |
OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %d %S", zonename, | |
timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno, | |
cwd, copyinstr(self->close_fd), curpsinfo->pr_psargs) : | |
printf("%5d %6d ", uid, pid); | |
/* print main fields */ | |
OPT_args == 0 ? printf("%-12s ", execname) : 1; | |
OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1; | |
OPT_flags ? printf("<close: no flags>") : 1; | |
OPT_err ? printf("%3d ", errno) : 1; | |
OPT_cwd ? printf("%-20s ", cwd) : 1; | |
OPT_dump == 0 ? printf("%d ", self->close_fd) : 1; | |
OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1; | |
OPT_trace == 1 ? ustack() : 1; | |
printf("\n"); | |
self->close_ok = 0; | |
self->close_fd = 0; | |
} | |
syscall::unlink:entry | |
{ | |
/* save pathname */ | |
self->unlink_pathp = arg0; | |
/* default is to trace unless filtering */ | |
self->unlink_ok = FILTER ? 0 : 1; | |
/* check each filter */ | |
(OPT_name == 1 && NAME == strstr(NAME, execname))? self->unlink_ok = 1 : 1; | |
(OPT_name == 1 && execname == strstr(execname, NAME))? self->unlink_ok = 1 : 1; | |
(OPT_pid == 1 && PID == pid) ? self->unlink_ok = 1 : 1; | |
/* OPT_file is checked on return to ensure pathp is mapped */ | |
} | |
syscall::unlink:return | |
/self->unlink_ok/ | |
{ | |
/* print optional fields */ | |
OPT_time ? printf("%-14d ", timestamp/1000) : 1; | |
OPT_timestr ? printf("%-20Y ", walltimestamp) : 1; | |
OPT_zone ? printf("%-10s ", zonename) : 1; | |
/* print dump fields */ | |
OPT_dump ? printf("%s %d %d %d %d %s %d %d %s %s %S", zonename, | |
timestamp/1000, uid, pid, ppid, execname, (int)arg0, errno, | |
cwd, copyinstr(self->unlink_pathp), curpsinfo->pr_psargs) : | |
printf("%5d %6d ", uid, pid); | |
/* print main fields */ | |
OPT_args == 0 ? printf("%-12s ", execname) : 1; | |
OPT_dump == 0 ? printf("%3d ", (int)arg0) : 1; | |
OPT_flags ? printf("<unlink: no flags>") : 1; | |
OPT_err ? printf("%3d ", errno) : 1; | |
OPT_cwd ? printf("%-20s ", cwd) : 1; | |
OPT_dump == 0 ? printf("%-20s ", copyinstr(self->unlink_pathp)) : 1; | |
OPT_args == 1 ? printf("%S", curpsinfo->pr_psargs) : 1; | |
OPT_trace == 1 ? ustack() : 1; | |
printf("\n"); | |
self->unlink_ok = 0; | |
self->unlink_pathp = 0; | |
} | |
/* | |
* Cleanup | |
*/ | |
/* SOLARIS: syscall::open:return, syscall::open64:return */ | |
syscall::open:return, syscall::open_nocancel:return, syscall::open_extended:return | |
/self->ok/ | |
{ | |
self->pathp = 0; | |
self->ok = 0; | |
} | |
' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment