Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135566870
D10006.id26472.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
127 KB
Referenced Files
None
Subscribers
None
D10006.id26472.diff
View Options
Index: ObsoleteFiles.inc
===================================================================
--- ObsoleteFiles.inc
+++ ObsoleteFiles.inc
@@ -38,6 +38,10 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20170418: remove DTrace scripts made obsolete by dwatch(8)
+OLD_FILES+=usr/share/dtrace/watch_execve
+OLD_FILES+=usr/share/dtrace/watch_kill
+OLD_FILES+=usr/share/dtrace/watch_vop_remove
# 20170319: io_test requires zh_TW.Big5 locale.
OLD_FILES+=usr/tests/lib/libc/locale/io_test
# 20170319: remove nls for non supported Big5* locales
Index: cddl/usr.sbin/dwatch/Makefile
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+SUBDIR= libexec
+
+.if ${MK_EXAMPLES} != "no"
+SUBDIR+= examples
+.endif
+
+SCRIPTS= dwatch
+
+MAN= dwatch.8
+
+.include <bsd.prog.mk>
Index: cddl/usr.sbin/dwatch/dwatch
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/dwatch
@@ -0,0 +1,620 @@
+#!/bin/sh
+#-
+# Copyright (c) 2014-2017 Devin Teske
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+############################################################ IDENT(1)
+#
+# $Title: Watch processes as they enter a particular DTrace probe $
+# $FreeBSD$
+#
+############################################################ CONFIGURATION
+
+#
+# DTrace pragma settings
+#
+DTRACE_PRAGMA="
+ option quiet
+ option dynvarsize=16m
+ option switchrate=10hz
+" # END-QUOTE
+
+#
+# Modules
+#
+: ${DWATCH_MODULES_PATH="/usr/libexec/dwatch:/usr/local/libexec/dwatch"}
+
+############################################################ GLOBALS
+
+pgm="${0##*/}" # Program basename
+
+#
+# Command-line arguments
+#
+PROBE=
+MODULE=
+
+#
+# Command-line options
+#
+COUNT=0 # -c count
+DEBUG= # -d
+EVENT_CODE= # -e code
+FILTER= # -f regex
+GROUP= # -g group
+LIST= # -l
+MAX_ARGS=64 # -m num
+MAX_DEPTH=64 # -n num
+PRINT=entry # -p action
+QUIET= # -q
+USER= # -u user
+VERBOSE= # -v
+
+#
+# Global exit status
+#
+SUCCESS=0
+FAILURE=1
+
+#
+# Miscellaneous
+#
+ACTIONS=
+DEFAULT_EVENT_TAG='printf("%d.%d %s[%d]: ",
+ this->uid0, this->gid0, execname, this->pid0);'
+DETAILS=
+EVENT_TAG=
+ID=2
+RGID=
+RUID=
+SUDO=
+export SUDO_PROMPT="[sudo] Password:"
+
+############################################################ FUNCTIONS
+
+usage()
+{
+ local optfmt="\t%-9s %s\n"
+ exec >&2
+ [ "$*" ] && printf "%s: %s\n" "$pgm" "$*"
+ printf "Usage: %s [OPTIONS] probe | module\n" "$pgm"
+ printf " %s [OPTIONS] -l [pattern]\n" "$pgm"
+ printf "OPTIONS:\n"
+ printf "$optfmt" "-c count" \
+ "Exit after count matching entries (Default 0 for disabled)."
+ printf "$optfmt" "-d" \
+ "Debug. Send dtrace(1) script to stdout instead of executing."
+ printf "$optfmt" "-e code" \
+ "DTrace code for event details. If \`-', read from stdin."
+ printf "$optfmt" "-f regex" \
+ "Filter. Only show blocks matching awk(1) regular expression."
+ printf "$optfmt" "-g group" \
+ "Group filter. Only show processes matching group name/gid."
+ printf "$optfmt" "-h" \
+ "Help. Display syntax and available modules then exit."
+ printf "$optfmt" "-l" \
+ "List available probe points on standard output and exit."
+ printf "$optfmt" "-M" \
+ "Disable modules. Same as setting DWATCH_MODULES_PATH to NULL."
+ printf "$optfmt" "-m num" \
+ "Maximum number of arguments to display (Default $MAX_ARGS)."
+ printf "$optfmt" "-n num" \
+ "Maximum directory depth to display (Default $MAX_DEPTH)."
+ printf "$optfmt" "-p action" \
+ "Print event details on action (Default \`$PRINT')."
+ printf "$optfmt" "-q" \
+ "Quiet. Disable informational messages displayed on stderr."
+ printf "$optfmt" "-u user" \
+ "User filter. Only show processes matching user name/uid."
+ printf "$optfmt" "-v" \
+ "Verbose. Show parent, grandparent, and ancestor of process."
+
+ # Build a list of modules available
+ local modules
+ modules=$( { IFS=:
+ for dir in $DWATCH_MODULES_PATH; do
+ [ -d "$dir" ] || continue
+ for path in $dir/*; do
+ [ -f "$path" ] || continue
+ name="${path##*/}"
+ [ "$name" = "${name%%[!0-9A-Za-z_]*}" ] ||
+ continue
+ echo $name
+ done
+ done
+ } | sort -u )
+
+ # Get the longest module name
+ local longest_module_name
+ longest_module_name=$( echo "$modules" |
+ awk -v N=0 '(L = length($0)) > N { N = L } END { print N }' )
+
+ # Get the width of the terminal
+ local max_size="$( stty size 2> /dev/null )"
+ : ${max_size:=24 80}
+ local max_width="${max_size#*[$IFS]}"
+
+ # Determine how many columns we can display
+ local x=$longest_module_name ncols=1
+ x=$(( $x + 8 )) # Accommodate leading tab character
+ x=$(( $x + 3 + $longest_module_name )) # Preload end of next column
+ while [ $x -lt $max_width ]; do
+ ncols=$(( $ncols + 1 ))
+ x=$(( $x + 3 + $longest_module_name ))
+ done
+
+ printf "MODULES:\n"
+ echo "$modules" |
+ awk -v ncols=$ncols -v colsize=$longest_module_name '
+ BEGIN { row_item[1] = "" }
+ function print_row()
+ {
+ printf "\t%-*s", colsize, row_item[1]
+ for (i = 2; i <= cur_col; i++)
+ printf " %-*s", colsize, row_item[i]
+ printf "\n"
+ }
+ {
+ n++
+ cur_col = (( n - 1 ) % ncols ) + 1
+ row_item[cur_col] = $0
+ if ( cur_col == ncols ) print_row()
+ }
+ END { if (cur_col < ncols) print_row() }'
+
+ exit $FAILURE
+}
+
+pproc()
+{
+ local proc="curthread->td_proc"
+ [ $1 -gt 0 ] && proc="this->proc->p_pptr"
+
+ awk 'NR > 1 && $0 { $0 = "\t" $0 } 1' <<-EOFPREAMBLE
+ this->proc = $proc;
+ this->pid$1 = this->proc->p_pid;
+ this->uid$1 = this->proc->p_ucred->cr_uid;
+ this->gid$1 = this->proc->p_ucred->cr_rgid;
+ this->p_args = this->proc ? this->proc->p_args : 0;
+ this->ar_length = this->p_args ? this->p_args->ar_length : 0;
+ this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
+
+ this->arg${1}_0 = this->ar_length > 0 ?
+ this->ar_args : stringof(this->proc->p_comm);
+ this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
+ this->ar_args += this->len;
+ this->ar_length -= this->len;
+
+ EOFPREAMBLE
+
+ awk -v P=$1 -v MAX_ARGS=$MAX_ARGS '
+ $0 { $0 = "\t" $0 }
+ buf = buf $0 "\n" { }
+ END {
+ while (++N <= MAX_ARGS) {
+ $0 = buf
+ gsub(/P/, P)
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFARGS
+ this->argP_N = this->ar_length > 0 ? this->ar_args : "";
+ this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
+ this->ar_args += this->len;
+ this->ar_length -= this->len;
+
+ EOFARGS
+
+ awk '$0 = "\t" $0' <<-EOFPROC
+ this->arg${1}_$(( $MAX_ARGS + 1 )) = this->ar_length > 0 ? "..." : "";
+ EOFPROC
+}
+
+pproc_dump()
+{
+ local OPTIND=1 OPTARG flag
+ local nl=1 verbose=
+
+ while getopts nv flag; do
+ case "$flag" in
+ n) nl= ;;
+ v) verbose=1 ;;
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ [ "$verbose" ] && awk -v P=$1 '
+ $0 { $0 = "\t" $0 }
+ buf = buf $0 "\n" { }
+ END {
+ $0 = buf
+ gsub(/S/, P < 3 ? sprintf("%" 7-2*(P+1) "s", "") : "")
+ gsub(/B/, P < 3 ? "\\" : "")
+ print
+ }
+ ' <<-EOFPREAMBLE
+ printf(" SB-+= %05d %d.%d %s",
+ this->pid$1, this->uid$1, this->gid$1, this->arg${1}_0);
+ EOFPREAMBLE
+
+ awk -v P=$1 -v MAX_ARGS=$MAX_ARGS '
+ $0 { $0 = "\t" $0 }
+ buf = buf $0 "\n" { }
+ END {
+ while (++N <= MAX_ARGS) {
+ $0 = buf
+ if (N == 1) sub(/^\t/, "")
+ gsub(/P/, P)
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFARGS
+ printf("%s%s", this->argP_N != "" ? " " : "", this->argP_N);
+ EOFARGS
+
+ if [ "$nl" ]; then
+ awk '$0 = "\t" $0' <<-EOFTAIL
+ printf("%s", this->arg${1}_0 != "" ? "\\n" : "");
+ EOFTAIL
+ fi
+}
+
+############################################################ MAIN
+
+#
+# Process command-line options
+#
+while getopts c:de:f:g:hlMm:n:p:qu:v flag; do
+ case "$flag" in
+ c) COUNT="$OPTARG" ;;
+ d) DEBUG=1 ;;
+ e) EVENT_CODE=1 DETAILS="$OPTARG" ;;
+ f) FILTER="$OPTARG" ;;
+ g) GROUP="$OPTARG" ;;
+ h) usage ;; # NOTREACHED
+ l) LIST=1 ;;
+ M) DWATCH_MODULES_PATH= ;;
+ m) MAX_ARGS="$OPTARG" ;;
+ n) MAX_DEPTH="$OPTARG" ;;
+ p) PRINT="$OPTARG" ;;
+ q) QUIET=1 ;;
+ u) USER="$OPTARG" ;;
+ v) VERBOSE=1 ;;
+ *) usage # NOTREACHED
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+# If we're running as root, no need for sudo(8)
+[ "$( id -u )" != 0 ] && type sudo > /dev/null 2>&1 && SUDO=sudo
+
+#
+# Read event code from stdin if `-' is the argument to `-e code' option
+#
+[ "$EVENT_CODE" -a "$DETAILS" = "-" ] && DETAILS=$( cat )
+
+#
+# List probes if `-l' was given
+#
+if [ "$LIST" ]; then
+ $SUDO dtrace -l | awk -v pattern="$1" '$NF == "entry" &&
+ !_[$0 = $2 ":" (NF > 4 ? $3 : "") ":" $--NF]++ &&
+ $0 ~ pattern'
+ exit
+fi
+
+#
+# Validate number of arguments
+#
+[ $# -gt 0 ] || usage "missing probe/module argument" # NOTREACHED
+
+#
+# Validate `-c count' option argument
+#
+case "$COUNT" in
+"") usage "-c option requires a number argument" ;; # NOTREACHED
+*[!0-9]*) usage "-c argument must be a number" ;; # NOTREACHED
+esac
+
+#
+# Validate `-g group' option argument
+#
+case "$GROUP" in
+"") : fall through ;;
+*[!0-9]*)
+ if ! RGID=$( getent group |
+ awk -F: -v group="$GROUP" '$1 == group { print $3 }' )
+ then
+ echo "$pgm: No such group: $GROUP" >&2
+ exit $FAILURE
+ fi
+ ;;
+*) RGID=$GROUP
+esac
+
+#
+# Validate `-m num' option argument
+#
+case "$MAX_ARGS" in
+"") usage "-m option requires a number argument" ;; # NOTREACHED
+*[!0-9]*) usage "-m argument must be a number" ;; # NOTREACHED
+esac
+
+#
+# Validate `-n num' option argument
+#
+case "$MAX_DEPTH" in
+"") usage "-n option requires a number argument" ;; # NOTREACHED
+*[!0-9]*) usage "-n argument must be a number" ;; # NOTREACHED
+esac
+
+#
+# Validate `-u user' option argument
+#
+case "$USER" in
+"") : fall through ;;
+*[!0-9]*)
+ if ! RUID=$( id -u "$USER" ); then
+ echo "$pgm: No such user: $USER" >&2
+ exit $FAILURE
+ fi
+ ;;
+*) RUID=$USER
+esac
+
+#
+# Load kernel module(s) if necessary
+#
+if type kldstat > /dev/null 2>&1; then
+ kldstat -qm dtrace || $SUDO kldload dtraceall || exit
+fi
+
+#
+# If argument is not fully qualified probe (e.g., one that contains ":"), check
+# for a module by that name, otherwise try to expand the probe name.
+#
+PROBE="$1"
+case "$PROBE" in
+*[![:alnum:]_]*) : fall through ;;
+*)
+ found=1
+ oldIFS="$IFS" IFS=:
+ for dir in $DWATCH_MODULES_PATH; do
+ [ -d "$dir" ] || continue
+ [ -f "$dir/$PROBE" ] || continue
+ MODULE="$PROBE" found=1
+ unset EVENT_TAG
+ . "$dir/$MODULE"
+ : ${PROBE:=$MODULE}
+ : ${ID:=2}
+ : ${PRINT:=entry}
+ : ${EVENT_TAG=$DEFAULT_EVENT_TAG}
+ break
+ done
+ IFS="$oldIFS"
+
+ # A loaded module may have left PROBE unqualified
+ case "$PROBE" in
+ *[![:alnum:]_]*) : fall through ;;
+ *)
+ P=$( $SUDO dtrace -ln "$PROBE:entry" | awk '
+ $NF == "entry" { print $2 "::" $(NF-1); exit found++ }
+ END { exit !found }
+ ' ) && PROBE="$P"
+ esac
+esac
+
+#
+# Header for watched probe entry
+#
+[ "$MODULE" ] || case "$PROBE" in
+*:execve)
+ PRINT="return /execname != this->caller_execname/"
+ EVENT_TAG='printf("%d.%d %s[%d]: ",
+ this->uid1, this->gid1, this->caller_execname, this->pid1);'
+ ;;
+*)
+ EVENT_TAG="$DEFAULT_EVENT_TAG"
+esac
+
+#
+# Event details
+#
+[ "$MODULE" -o "$EVENT_CODE" ] || DETAILS="
+ printf(\"%s\", this->arg0_0);
+ $( pproc_dump -n 0 )
+" # END-QUOTE
+
+#
+# DTrace script
+#
+# If `-d' is given, script is sent to stdout for debugging
+# If `-c count", `-f regex', `-g group', or `-u user' is given, run script with
+# dtrace and send output to awk(1) post-processor (making sure to preserve the
+# exit code returned by dtrace invocation). Otherwise, simply run script with
+# dtrace and then exit.
+#
+{
+ if [ "$DEBUG" ]; then
+ # Send script to stdout
+ cat
+ exit
+ fi
+ if ! [ "$FILTER" -o "$COUNT" != 0 -o "$USER" -o "$GROUP" ]; then
+ # Run script without filter
+ $SUDO dtrace -s /dev/stdin
+ exit
+ fi
+
+ if [ ! "$QUIET" ]; then
+ msg="dtrace:"
+ [ "$COUNT" ] && msg="$msg count: $COUNT"
+ [ "$FILTER" ] && msg="$msg filter: $FILTER"
+ [ "$GROUP" ] && msg="$msg group: $GROUP"
+ [ "$USER" ] && msg="$msg user: $USER"
+ echo "$msg" >&2
+ fi
+
+ # Send script output to post-processor for filtering
+ exec 3>&1
+ exec 4>&2
+ status=$( exec 5>&1; (
+ trap 'echo $? >&5' EXIT
+ ( trap exit INT; $SUDO dtrace -s /dev/stdin ) &
+ echo $!
+ ) 2>&4 | awk \
+ -v count="$COUNT" \
+ -v filter="$FILTER" \
+ -v gid=$RGID \
+ -v uid=$RUID \
+ -v verbose=$VERBOSE \
+ ' # Start awk(1) post-processor
+ ############################################# BEGIN
+ BEGIN {
+ getline dtrace
+ pid = num = "[[:digit:]]+"
+ fmt = "(\n%6s\\\\-\\+= %s|^[^\n]*) %s\\.%s [^\n]*$"
+ uidfilter = sprintf(fmt, "", pid, uid, num)
+ gidfilter = sprintf(fmt, "", pid, num, gid)
+ }
+ ############################################# FUNCTIONS
+ function dump() {
+ lines = block
+ block = ""
+ if (uid && lines !~ uidfilter) return
+ if (gid && lines !~ gidfilter) return
+ if (filter && lines !~ filter) return
+ if (lines) print lines
+ ++matches
+ }
+ ############################################# MAIN
+ { block = (block ? block "\n" : block) $0 }
+ !verbose { dump() }
+ $0 ~ sprintf("^%6s\\\\-\\+= %s ", "", pid) { dump() }
+ count && matches >= count { exit }
+ ############################################# END
+ END { dump(); system(sprintf("kill %s", dtrace)) }
+ ' >&3 )
+ exit $status
+
+} <<EOF
+#!/usr/sbin/dtrace -s
+/* -
+ * Copyright (c) 2014-2017 Devin Teske <dteske@FreeBSD.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS \`\`AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * \$Title: dtrace(1) script to log process(es) entering $PROBE $
+ * \$FreeBSD$
+ */
+
+$( echo "$DTRACE_PRAGMA" | awk '
+ !/^[[:space:]]*(#|$)/, sub(/^[[:space:]]*/, "#pragma D ")||1
+' )
+
+/*********************************************************/
+
+syscall::execve:entry /* probe ID 1 */
+{
+ this->caller_execname = execname;
+}
+${ACTIONS:+
+/*********************************************************/
+
+$ACTIONS}
+/*********************************************************/
+
+$PROBE:$PRINT /* probe ID $ID */
+{
+ /*
+ * Examine process, parent process, and grandparent process details
+ */
+
+ /******************* CURPROC *******************/
+
+ $( pproc 0 )
+
+ /******************* PPARENT *******************/
+
+ $( if [ "$VERBOSE" ]; then pproc 1; else echo "
+ this->proc = this->proc->p_pptr;
+ this->pid1 = this->proc->p_pid;
+ this->uid1 = this->proc->p_ucred->cr_uid;
+ this->gid1 = this->proc->p_ucred->cr_rgid;
+ "; fi )
+
+ /******************* GPARENT *******************/
+
+ $( [ "$VERBOSE" ] && pproc 2 )
+
+ /******************* APARENT *******************/
+
+ $( [ "$VERBOSE" ] && pproc 3 )
+
+ /***********************************************/
+
+ /*
+ * Print process, parent, grandparent, and ancestor details
+ */
+
+ printf("%Y ", timestamp + 1468045731600000000);
+ $EVENT_TAG
+ $DETAILS
+ printf("\\n");
+
+ $( if [ "$VERBOSE" ]; then
+ pproc_dump -v 3
+ pproc_dump -v 2
+ pproc_dump -v 1
+ pproc_dump -v 0
+ fi )
+}
+EOF
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/dwatch.8
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/dwatch.8
@@ -0,0 +1,206 @@
+.\" Copyright (c) 2014-2017 Devin Teske
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd Mar 20, 2017
+.Dt DWATCH 8
+.Os
+.Sh NAME
+.Nm dwatch
+.Nd Watch processes as they enter a particular DTrace probe
+.Sh SYNOPSIS
+.Nm
+.Op OPTIONS
+probe | module
+.Nm
+.Fl l Op pattern
+.Sh DESCRIPTION
+The
+.Nm
+utility uses
+.Xr dtrace 1
+to display information when a process enters a given probe.
+The following options are available:
+.Bl -tag -width "-p action"
+.It Fl c Ar count
+Exit after
+.Ar count
+matching entries
+.Pq Default 0 for disabled .
+.It Fl d
+Debug.
+Send
+.Xr dtrace 1
+script to stdout instead of executing.
+.It Fl e Ar code
+DTrace code for event details.
+If `-', read from stdin.
+This allows you to customize what is printed after the date/time and user info.
+By default, the name and arguments of the program entering the probe are shown.
+.It Fl f Ar regex
+Filter.
+Only show blocks matching
+.Xr awk 1
+regular expression.
+.It Fl g Ar group
+Group filter.
+Only show processes matching
+.Ar group
+name/gid.
+.It Fl h
+Help.
+Display syntax and available modules then exit.
+.It Fl l
+List available probe points on standard output and exit.
+.It Fl M
+Disable modules.
+Same as setting DWATCH_MODULES_PATH to NULL.
+.It Fl m Ar num
+Maximum number of arguments to display
+.Pq Default 64 .
+.It Fl n Ar num
+Maximum directory depth to display
+.Pq Default 64 .
+.It Fl p Ar action
+Print event details on action
+.Pq Default Ql Li entry .
+.It Fl q
+Quiet.
+Disable informational messages displayed on stderr.
+.It Fl u Ar user
+User filter.
+Only show processes matching
+.Ar user
+name/uid.
+.It Fl v
+Verbose.
+Show parent,
+grandparent,
+and ancestor of process.
+.El
+.Pp
+Either the name of a
+.Xr dwatch 8
+module
+.Pq available with Ql Nm Fl h
+or
+.Xr dtrace 1
+probe
+.Pq available with Ql Nm Fl l
+must be given as the first/only non-option argument.
+.Pp
+If given an argument consisting of only alpha-numeric/underscore characters,
+.Xr dwatch 8
+checks for a module by that name in the colon-separated list of directories in
+.Ev DWATCH_MODULES_PATH
+.Pq unless given Ql Fl M .
+If no module is found,
+.Xr dwatch 8
+tries to expand the probe name using the following
+.Xr dtrace 1
+command:
+.Pp
+.Bl -tag -width indent+
+.It
+dtrace -ln <probe>:entry
+.El
+.Pp
+For example, if given a probe of
+.Dq Li foo ,
+.Xr dwatch 8
+will execute
+.Ql Li dtrace -ln foo:entry
+and take the first probe available.
+.Pp
+Each time a process enters the given probe,
+the date/time of entry,
+name/id of process,
+and
+.Pq if no module and not given Ql Fl e Ar code
+the process name and arguments are printed.
+.Pp
+If the probe is
+.Ql Li execve
+the full name and arguments of the forked child process are instead shown.
+.Sh MODULES
+Modules customize the data printed during events.
+Modules are loaded from a colon-separated list of directories in
+.Ev DWATCH_MODULES_PATH .
+Below is an incomplete list of modules available with a basic description:
+.Pp
+.Bl -tag -width "vop_readdir"
+.It chmod
+Print arguments being passed to chmod(2)
+.It fchmod
+Print arguments being passed to fchmod(2)
+.It fchmodat
+Print arguments being passed to fchmodat(2)
+.It kill
+Print arguments being passed to kill(2)
+.It lchmod
+Print arguments being passed to lchmod(2)
+.It nanosleep
+Print arguments being passed to nanosleep(2)
+.It vop_create
+Print filesystem paths being created by VOP_CREATE(9)
+.It vop_lookup
+Print filesystem paths being looked-up by VOP_LOOKUP(9)
+.It vop_mkdir
+Print directory paths being created by VOP_MKDIR(9)
+.It vop_mknod
+Print device node paths being created by VOP_MKNOD(9)
+.It vop_readdir
+Print directory paths being read by VOP_READDIR(9)
+.It vop_remove
+Print filesystem paths being removed by VOP_REMOVE(9)
+.It vop_rename
+Print filesystem paths being renamed by VOP_RENAME(9)
+.It vop_rmdir
+Print directory paths being removed by VOP_RMDIR(9)
+.It vop_symlink
+Print symlink paths being created by VOP_SYMLINK(9)
+.El
+.Sh ENVIRONMENT VARIABLES
+The following environment variables affect the execution of
+.Nm :
+.Bl -tag -width "DWATCH_MODULES_PATH"
+.It Ev DWATCH_MODULES_PATH
+If DWATCH_MODULES_PATH is set,
+.Nm
+will search for modules in the colon-separated list of directories
+instead of the default
+.Ql Li /usr/libexec/dwatch:/usr/local/libexec/dwatch .
+If set to NULL, no modules will be loaded.
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr dtrace 1
+.Sh HISTORY
+.Nm
+first appeared in
+.Fx 12.0-CURRENT .
+.Sh AUTHORS
+.An Devin Teske Aq Mt dteske@FreeBSD.org
Index: cddl/usr.sbin/dwatch/examples/Makefile
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/examples/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+FILESDIR= ${SHAREDIR}/examples/dwatch
+FILES= module_template
+
+.include <bsd.prog.mk>
Index: cddl/usr.sbin/dwatch/examples/module_template
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/examples/module_template
@@ -0,0 +1,65 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for XXX entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Put some text here
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+#PROBE=
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+#exec 9<<EOF
+# printf("XXX");
+#EOF
+#DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/Makefile
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/Makefile
@@ -0,0 +1,20 @@
+# $FreeBSD$
+
+FILESDIR= ${LIBEXECDIR}/dwatch
+FILES= chmod \
+ fchmod \
+ fchmodat \
+ kill \
+ lchmod \
+ nanosleep \
+ vop_create \
+ vop_mkdir \
+ vop_mknod \
+ vop_lookup \
+ vop_readdir \
+ vop_remove \
+ vop_rename \
+ vop_rmdir \
+ vop_symlink
+
+.include <bsd.prog.mk>
Index: cddl/usr.sbin/dwatch/libexec/chmod
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/chmod
@@ -0,0 +1,66 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for chmod(2) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to chmod(2)
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=syscall::chmod
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<'EOF'
+ this->path = (string)copyinstr(arg0);
+ printf("chmod(path \"%s\", mode %04o)", this->path, (mode_t)arg1);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/fchmod
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/fchmod
@@ -0,0 +1,65 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for fchmod(2) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to fchmod(2)
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=syscall::fchmod
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ printf("fchmod(fd %i, mode %04o)", (int)arg0, (mode_t)arg1);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/fchmodat
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/fchmodat
@@ -0,0 +1,67 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for fchmodat(2) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to fchmodat(2)
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=syscall::fchmodat
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<'EOF'
+ this->path = (string)copyinstr(arg1);
+ printf("fchmodat(fd %i, path \"%s\", mode %04o, flag %i)",
+ (int)arg0, this->path, (mode_t)arg2, (int)arg3);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/kill
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/kill
@@ -0,0 +1,67 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for kill(2) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to kill(2)
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=syscall::kill
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ printf("kill(pid %d, sig %u)",
+ (pid_t)arg0 > 0 ? arg0 : arg0 == -1 ? -1 : arg0 * -1,
+ (int)arg1);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/lchmod
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/lchmod
@@ -0,0 +1,66 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for lchmod(2) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to lchmod(2)
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=syscall::lchmod
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<'EOF'
+ this->path = (string)copyinstr(arg0);
+ printf("lchmod(path \"%s\", mode %04o)", this->path, (mode_t)arg1);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/nanosleep
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/nanosleep
@@ -0,0 +1,69 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for nanosleep(2) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to nanosleep(2)
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=syscall::nanosleep
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+#PRINT=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ this->rqtp = (struct timespec *)copyin(arg0, sizeof(struct timespec));
+ this->rmtp = (struct timespec *)copyin(arg1, sizeof(struct timespec));
+ printf("nanosleep(rqtp {%d, %d}, rmtp {%d, %d})",
+ this->rqtp->tv_sec, this->rqtp->tv_nsec,
+ this->rmtp->tv_sec, this->rmtp->tv_nsec);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_create
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_create
@@ -0,0 +1,175 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_CREATE(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print filesystem paths being created by VOP_CREATE(9)
+# NB: All paths are shown even if error prevents their creation.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_create
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_lookup
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_lookup
@@ -0,0 +1,175 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_LOOKUP(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print filesystem paths being looked-up by VOP_LOOKUP(9)
+# NB: All paths are shown even if error prevents their lookup.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_lookup
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_mkdir
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_mkdir
@@ -0,0 +1,175 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_MKDIR(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print directory paths being created by VOP_MKDIR(9)
+# NB: All paths are shown even if error prevents their creation.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_mkdir
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_mknod
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_mknod
@@ -0,0 +1,175 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_MKNOD(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print device node paths being created by VOP_MKNOD(9)
+# NB: All paths are shown even if error prevents their creation.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_mknod
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_readdir
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_readdir
@@ -0,0 +1,166 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_READDIR(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print directory paths being read by VOP_READDIR(9)
+# NB: All paths are shown even if error prevents their reading.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_readdir
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_remove
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_remove
@@ -0,0 +1,175 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_REMOVE(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print filesystem paths being removed by VOP_REMOVE(9)
+# NB: All paths are shown even if error prevents their removal.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_remove
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_rename
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_rename
@@ -0,0 +1,262 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_RENAME(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print filesystem paths being renamed by VOP_RENAME(9)
+# NB: All paths are shown even if error prevents their rename.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_rename
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->fvp = args[1] ? args[1]->a_fdvp : NULL;
+ this->fncp = this->fvp != NULL ?
+ this->fvp->v_cache_dst.tqh_first : 0;
+ this->ffi_name = args[1] ? (
+ args[1]->a_fcnp != NULL ?
+ stringof(args[1]->a_fcnp->cn_nameptr) : ""
+ ) : "";
+ this->fmount = this->fvp != NULL ?
+ this->fvp->v_mount : NULL; /* ptr to vfs we are in */
+ this->ffi_fs = this->fmount != NULL ?
+ stringof(this->fmount->mnt_stat.f_fstypename) : "";
+ this->ffi_mount = this->fmount != NULL ?
+ stringof(this->fmount->mnt_stat.f_mntonname) : "";
+ this->fd_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+
+ this->tvp = args[1] ? args[1]->a_tdvp : NULL;
+ this->tncp = this->tvp != NULL ?
+ this->tvp->v_cache_dst.tqh_first : 0;
+ this->tfi_name = args[1] ? (
+ args[1]->a_tcnp != NULL ?
+ stringof(args[1]->a_tcnp->cn_nameptr) : ""
+ ) : "";
+ this->tmount = this->tvp != NULL ?
+ this->tvp->v_mount : NULL; /* ptr to vfs we are in */
+ this->tfi_fs = this->tmount != NULL ?
+ stringof(this->tmount->mnt_stat.f_fstypename) : "";
+ this->tfi_mount = this->tmount != NULL ?
+ stringof(this->tmount->mnt_stat.f_mntonname) : "";
+ this->td_name = this->tvp != NULL ? (
+ this->tvp->v_cache_dd != NULL ?
+ stringof(this->tvp->v_cache_dd->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->fvp == 0 || this->ffi_fs == 0 ||
+ this->ffi_fs == "devfs" || this->ffi_fs == "" ||
+ this->ffi_name == ""/ /* probe ID 3 */
+{
+ this->fncp = 0;
+}
+
+$PROBE:entry /this->tvp == 0 || this->tfi_fs == 0 ||
+ this->tfi_fs == "devfs" || this->tfi_fs == "" ||
+ this->tfi_name == ""/ /* probe ID 4 */
+{
+ this->tncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->fncp/ /* probe ID 5 (depth 1) */
+{
+ this->fdvp = this->fncp->nc_dvp != NULL ? (
+ this->fncp->nc_dvp != NULL ?
+ this->fncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->fname1 = this->fdvp != 0 ? (
+ this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->tncp/ /* probe ID 6 (depth 1) */
+{
+ this->tdvp = this->tncp->nc_dvp != NULL ? (
+ this->tncp->nc_dvp != NULL ?
+ this->tncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->tname1 = this->tdvp != 0 ? (
+ this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->fname1 == 0 || this->ffi_fs == 0 ||
+ this->ffi_fs == "devfs" || this->ffi_fs == "" ||
+ this->fname1 == "/" || this->fname1 == ""/ /* probe ID 7 */
+{
+ this->fdvp = 0;
+}
+
+$PROBE:entry /this->tname1 == 0 || this->tfi_fs == 0 ||
+ this->tfi_fs == "devfs" || this->tfi_fs == "" ||
+ this->tname1 == "/" || this->tname1 == ""/ /* probe ID 8 */
+{
+ this->tdvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=9 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM1/, ID)
+ gsub(/IDNUM2/, ID + 1)
+ sub(/\n$/, "")
+ print
+ ID = ID + 2
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->fdvp/ /* probe ID IDNUM1 (depth DEPTH) */
+{
+ this->fdvp = this->fdvp->nc_dvp != NULL ? (
+ this->fdvp->nc_dvp != NULL ?
+ this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->fnameDEPTH = this->fdvp != 0 ? (
+ this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : ""
+ ) : "";
+}
+$PROBE:entry /this->tdvp/ /* probe ID IDNUM2 (depth DEPTH) */
+{
+ this->tdvp = this->tdvp->nc_dvp != NULL ? (
+ this->tdvp->nc_dvp != NULL ?
+ this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->tnameDEPTH = this->tdvp != 0 ? (
+ this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 8 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->ffi_mount != 0 && this->tfi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print 'from' full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->ffi_mount, this->ffi_mount != 0 ? (
+ this->ffi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->fname = this->fnameN, this->fname != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the 'from' parent directory name */
+ this->fname = this->fd_name != 0 ? this->fd_name : "";
+ printf("%s%s", this->fname, this->fname != "" ? "/" : "");
+
+ /* Print the 'from' entry name */
+ this->fname = this->ffi_name != 0 ? this->ffi_name : "";
+ printf("%s", this->fname);
+
+ printf(" -> ");
+
+ /*
+ * Print 'to' full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->tfi_mount, this->tfi_mount != 0 ? (
+ this->tfi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->tname = this->tnameN, this->tname != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the 'to' parent directory name */
+ this->tname = this->td_name != 0 ? this->td_name : "";
+ printf("%s%s", this->tname, this->tname != "" ? "/" : "");
+
+ /* Print the 'to' entry name */
+ this->tname = this->tfi_name != 0 ? this->tfi_name : "";
+ printf("%s", this->tname);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_rmdir
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_rmdir
@@ -0,0 +1,175 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_RMDIR(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print directory paths being removed by VOP_RMDIR(9)
+# NB: All paths are shown even if error prevents their removal.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_rmdir
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: cddl/usr.sbin/dwatch/libexec/vop_symlink
===================================================================
--- /dev/null
+++ cddl/usr.sbin/dwatch/libexec/vop_symlink
@@ -0,0 +1,179 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_SYMLINK(9) entry $
+# $Copyright: 2014-2017 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print symlink paths being created by VOP_SYMLINK(9)
+# NB: All paths are shown even if error prevents their creation.
+#
+############################################################ PROBE
+
+# This is optional, if you don't set or it is NULL, dwatch(8) will try to
+# dynamically determine the probe via the module's filename. For example, if
+# the module file is named `foo' then dwatch(8) will try `dtrace -ln foo:entry'
+# to determine an appropriate probe for watching `foo'.
+
+PROBE=vfs:vop:vop_symlink
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+exec 9<<EOF
+$PROBE:entry /* probe ID 2 */
+{
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->target = args[1] ? args[1]->a_target : "";
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+}
+
+$PROBE:entry /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID 3 */
+{
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE:entry /this->ncp/ /* probe ID 4 (depth 1) */
+{
+ this->dvp = this->ncp->nc_dvp != NULL ? (
+ this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE:entry /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID 5 */
+{
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=6 -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ sub(/\n$/, "")
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE:entry /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{
+ this->dvp = this->dvp->nc_dvp != NULL ? (
+ this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
+ ) : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+/*
+ * END Pathname-depth iterators
+ */
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $MAX_DEPTH + 5 ))
+
+############################################################ PRINT ACTION
+
+# The default value is simply `entry'. This is paired with $PROBE (which can be
+# auto-probed when unset or NULL) and can be customized to include clauses for
+# the final print action which must be true before the print action will run.
+
+PRINT="entry /this->fi_mount != 0/"
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the PRINT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the PRINT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+exec 9<<EOF
+ /*
+ * Print full path
+ * NB: Up-to but not including the parent directory (printed below)
+ */
+ printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ buf = buf $0 "\n" { }
+ END {
+ for (N = MAX_DEPTH; N > 0; N--) {
+ $0 = (N < MAX_DEPTH ? "\t" : "") buf
+ gsub(/N/, N)
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFDEPTH
+ printf("%s%s", this->name = this->nameN, this->name != "" ? "/" : "");
+ EOFDEPTH
+ )
+
+ /* Print the parent directory name */
+ this->name = this->d_name != 0 ? this->d_name : "";
+ printf("%s%s", this->name, this->name != "" ? "/" : "");
+
+ /* Print the entry name */
+ this->name = this->fi_name != 0 ? this->fi_name : "";
+ printf("%s", this->name);
+
+ /* Print the target */
+ printf(" -> %s", this->target);
+EOF
+DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: etc/mtree/BSD.usr.dist
===================================================================
--- etc/mtree/BSD.usr.dist
+++ etc/mtree/BSD.usr.dist
@@ -118,6 +118,8 @@
..
bsdinstall
..
+ dwatch
+ ..
hyperv
..
lpr
Index: share/dtrace/Makefile
===================================================================
--- share/dtrace/Makefile
+++ share/dtrace/Makefile
@@ -17,10 +17,7 @@
tcpdebug \
tcpstate \
tcptrack \
- udptrack \
- watch_execve \
- watch_kill \
- watch_vop_remove
+ udptrack
SCRIPTSDIR= ${SHAREDIR}/dtrace
Index: share/dtrace/watch_execve
===================================================================
--- share/dtrace/watch_execve
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/sbin/dtrace -s
-/* -
- * Copyright (c) 2014 Devin Teske <dteske@FreeBSD.org>
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Title: dtrace(1) script to log process(es) entering syscall::execve $
- * $FreeBSD$
- */
-
-#pragma D option quiet
-#pragma D option dynvarsize=16m
-#pragma D option switchrate=10hz
-
-/*********************************************************/
-
-syscall::execve:entry /* probe ID 1 */
-{
- this->caller_execname = execname;
-}
-
-/*********************************************************/
-
-syscall::execve:return /execname != this->caller_execname/ /* probe ID 2 */
-{
- /*
- * Examine process, parent process, and grandparent process details
- */
-
- /******************* CURPROC *******************/
-
- this->proc = curthread->td_proc;
- this->pid0 = this->proc->p_pid;
- this->uid0 = this->proc->p_ucred->cr_uid;
- this->gid0 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc->p_args;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg0_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* PPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid1 = this->proc->p_pid;
- this->uid1 = this->proc->p_ucred->cr_uid;
- this->gid1 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg1_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* GPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid2 = this->proc->p_pid;
- this->uid2 = this->proc->p_ucred->cr_uid;
- this->gid2 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg2_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* APARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid3 = this->proc->p_pid;
- this->uid3 = this->proc->p_ucred->cr_uid;
- this->gid3 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg3_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_4 = this->ar_length > 0 ? "..." : "";
-
- /***********************************************/
-
- /*
- * Print process, parent, and grandparent details
- */
-
- printf("%Y %s[%d]: ", timestamp + 1406598400000000000,
- this->caller_execname, this->pid1);
- printf("%s", this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("\n");
-
- printf(" -+= %05d %d.%d %s",
- this->pid3, this->uid3, this->gid3, this->arg3_0);
- printf("%s%s", this->arg3_1 != "" ? " " : "", this->arg3_1);
- printf("%s%s", this->arg3_2 != "" ? " " : "", this->arg3_2);
- printf("%s%s", this->arg3_3 != "" ? " " : "", this->arg3_3);
- printf("%s%s", this->arg3_4 != "" ? " " : "", this->arg3_4);
- printf("%s", this->arg3_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid2, this->uid2, this->gid2, this->arg2_0);
- printf("%s%s", this->arg2_1 != "" ? " " : "", this->arg2_1);
- printf("%s%s", this->arg2_2 != "" ? " " : "", this->arg2_2);
- printf("%s%s", this->arg2_3 != "" ? " " : "", this->arg2_3);
- printf("%s%s", this->arg2_4 != "" ? " " : "", this->arg2_4);
- printf("%s", this->arg2_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid1, this->uid1, this->gid1, this->arg1_0);
- printf("%s%s", this->arg1_1 != "" ? " " : "", this->arg1_1);
- printf("%s%s", this->arg1_2 != "" ? " " : "", this->arg1_2);
- printf("%s%s", this->arg1_3 != "" ? " " : "", this->arg1_3);
- printf("%s%s", this->arg1_4 != "" ? " " : "", this->arg1_4);
- printf("%s", this->arg1_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid0, this->uid0, this->gid0, this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("%s", this->arg0_0 != "" ? "\n" : "");
-}
Index: share/dtrace/watch_kill
===================================================================
--- share/dtrace/watch_kill
+++ /dev/null
@@ -1,232 +0,0 @@
-#!/usr/sbin/dtrace -s
-/* -
- * Copyright (c) 2014-2016 Devin Teske <dteske@FreeBSD.org>
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Title: dtrace(1) script to log process(es) entering syscall::kill $
- * $FreeBSD$
- */
-
-#pragma D option quiet
-#pragma D option dynvarsize=16m
-#pragma D option switchrate=10hz
-
-/*********************************************************/
-
-syscall::execve:entry /* probe ID 1 */
-{
- this->caller_execname = execname;
-}
-
-/*********************************************************/
-
-syscall::kill:entry /* probe ID 2 */
-{
- this->pid_to_kill = (pid_t)arg0;
- this->kill_signal = (int)arg1;
-
- /*
- * Examine process, parent process, and grandparent process details
- */
-
- /******************* CURPROC *******************/
-
- this->proc = curthread->td_proc;
- this->pid0 = this->proc->p_pid;
- this->uid0 = this->proc->p_ucred->cr_uid;
- this->gid0 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc->p_args;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg0_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* PPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid1 = this->proc->p_pid;
- this->uid1 = this->proc->p_ucred->cr_uid;
- this->gid1 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg1_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* GPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid2 = this->proc->p_pid;
- this->uid2 = this->proc->p_ucred->cr_uid;
- this->gid2 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg2_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* APARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid3 = this->proc->p_pid;
- this->uid3 = this->proc->p_ucred->cr_uid;
- this->gid3 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg3_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_4 = this->ar_length > 0 ? "..." : "";
-
- /***********************************************/
-
- /*
- * Print process, parent, and grandparent details
- */
-
- printf("%Y %s[%d]: ", timestamp + 1406598400000000000,
- this->caller_execname, this->pid1);
- printf("%s", this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf(" (sending signal %u to pid %u)",
- this->kill_signal, this->pid_to_kill);
- printf("\n");
-
- printf(" -+= %05d %d.%d %s",
- this->pid3, this->uid3, this->gid3, this->arg3_0);
- printf("%s%s", this->arg3_1 != "" ? " " : "", this->arg3_1);
- printf("%s%s", this->arg3_2 != "" ? " " : "", this->arg3_2);
- printf("%s%s", this->arg3_3 != "" ? " " : "", this->arg3_3);
- printf("%s%s", this->arg3_4 != "" ? " " : "", this->arg3_4);
- printf("%s", this->arg3_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid2, this->uid2, this->gid2, this->arg2_0);
- printf("%s%s", this->arg2_1 != "" ? " " : "", this->arg2_1);
- printf("%s%s", this->arg2_2 != "" ? " " : "", this->arg2_2);
- printf("%s%s", this->arg2_3 != "" ? " " : "", this->arg2_3);
- printf("%s%s", this->arg2_4 != "" ? " " : "", this->arg2_4);
- printf("%s", this->arg2_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid1, this->uid1, this->gid1, this->arg1_0);
- printf("%s%s", this->arg1_1 != "" ? " " : "", this->arg1_1);
- printf("%s%s", this->arg1_2 != "" ? " " : "", this->arg1_2);
- printf("%s%s", this->arg1_3 != "" ? " " : "", this->arg1_3);
- printf("%s%s", this->arg1_4 != "" ? " " : "", this->arg1_4);
- printf("%s", this->arg1_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid0, this->uid0, this->gid0, this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("%s", this->arg0_0 != "" ? "\n" : "");
-}
Index: share/dtrace/watch_vop_remove
===================================================================
--- share/dtrace/watch_vop_remove
+++ /dev/null
@@ -1,476 +0,0 @@
-#!/usr/sbin/dtrace -s
-/* -
- * Copyright (c) 2014 Devin Teske <dteske@FreeBSD.org>
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Title: dtrace(1) script to log process(es) entering vfs::vop_remove $
- * $FreeBSD$
- */
-
-#pragma D option quiet
-#pragma D option dynvarsize=16m
-#pragma D option switchrate=10hz
-
-/*********************************************************/
-
-vfs::vop_remove:entry /* probe ID 1 */
-{
- this->vp = (struct vnode *)arg0;
- this->ncp = &(this->vp->v_cache_dst) != NULL ?
- this->vp->v_cache_dst.tqh_first : 0;
- this->fi_name = args[1] ? (
- args[1]->a_cnp != NULL ?
- stringof(args[1]->a_cnp->cn_nameptr) : ""
- ) : "";
- this->mount = this->vp->v_mount; /* ptr to vfs we are in */
- this->fi_fs = this->mount != 0 ?
- stringof(this->mount->mnt_stat.f_fstypename) : "";
- this->fi_mount = this->mount != 0 ?
- stringof(this->mount->mnt_stat.f_mntonname) : "";
- this->d_name = args[0]->v_cache_dd != NULL ?
- stringof(args[0]->v_cache_dd->nc_name) : "";
-}
-
-vfs::vop_remove:entry /this->vp == 0 || this->fi_fs == 0 ||
- this->fi_fs == "devfs" || this->fi_fs == "" ||
- this->fi_name == ""/ /* probe ID 2 */
-{
- this->ncp = 0;
-}
-
-/*********************************************************/
-
-vfs::vop_remove:entry /this->ncp/ /* probe ID 3 (depth 1) */
-{
- this->dvp = this->ncp->nc_dvp != NULL ? (
- &(this->ncp->nc_dvp->v_cache_dst) != NULL ?
- this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name1 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->name1 == 0 || this->fi_fs == 0 ||
- this->fi_fs == "devfs" || this->fi_fs == "" ||
- this->name1 == "/" || this->name1 == ""/ /* probe ID 4 */
-{
- this->dvp = 0;
-}
-
-/*********************************************************/
-
-/*
- * BEGIN Pathname-depth iterators (copy/paste as many times as-desired)
- */
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 5 (depth 2) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name2 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 6 (depth 3) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name3 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 7 (depth 4) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name4 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 8 (depth 5) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name5 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 9 (depth 6) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name6 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 10 (depth 7) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name7 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 11 (depth 8) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name8 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 12 (depth 9) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name9 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 13 (depth 10) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name10 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 14 (depth 11) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name11 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 15 (depth 12) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name12 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 16 (depth 13) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name13 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 17 (depth 14) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name14 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 18 (depth 15) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name15 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 19 (depth 16) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name16 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 20 (depth 17) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name17 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 21 (depth 18) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name18 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 22 (depth 19) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name19 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 23 (depth 20) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name20 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-/*
- * END Pathname-depth iterators
- */
-
-/*********************************************************/
-
-vfs::vop_remove:entry /this->fi_mount != 0/ /* probe ID 24 */
-{
- printf("%Y %s[%d]: ", timestamp + 1406598400000000000, execname, pid);
-
- /*
- * Print full path of file to delete
- * NB: Up-to but not including the parent directory (printed below)
- */
- printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
- this->fi_mount == "/" ? "" : "/"
- ) : "/");
- printf("%s%s", this->name = this->name20, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name19, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name18, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name17, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name16, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name15, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name14, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name13, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name12, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name11, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name10, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name9, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name8, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name7, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name6, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name5, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name4, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name3, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name2, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name1, this->name != "" ? "/" : "");
-
- /* Print the parent directory name */
- this->name = this->d_name != 0 ? this->d_name : "";
- printf("%s%s", this->name, this->name != "" ? "/" : "");
-
- /* Print the entry name */
- this->name = this->fi_name != 0 ? this->fi_name : "";
- printf("%s", this->name);
-
- printf("\n");
-
- /*
- * Examine process, parent process, and grandparent process details
- */
-
- /******************* CURPROC *******************/
-
- this->proc = curthread->td_proc;
- this->pid0 = this->proc->p_pid;
- this->uid0 = this->proc->p_ucred->cr_uid;
- this->gid0 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc->p_args;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg0_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* PPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid1 = this->proc->p_pid;
- this->uid1 = this->proc->p_ucred->cr_uid;
- this->gid1 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg1_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* GPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid2 = this->proc->p_pid;
- this->uid2 = this->proc->p_ucred->cr_uid;
- this->gid2 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg2_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_4 = this->ar_length > 0 ? "..." : "";
-
- /***********************************************/
-
- /*
- * Print process, parent, and grandparent details
- */
-
- printf(" -+= %05d %d.%d %s",
- this->pid2, this->uid2, this->gid2, this->arg2_0);
- printf("%s%s", this->arg2_1 != "" ? " " : "", this->arg2_1);
- printf("%s%s", this->arg2_2 != "" ? " " : "", this->arg2_2);
- printf("%s%s", this->arg2_3 != "" ? " " : "", this->arg2_3);
- printf("%s%s", this->arg2_4 != "" ? " " : "", this->arg2_4);
- printf("%s", this->arg2_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid1, this->uid1, this->gid1, this->arg1_0);
- printf("%s%s", this->arg1_1 != "" ? " " : "", this->arg1_1);
- printf("%s%s", this->arg1_2 != "" ? " " : "", this->arg1_2);
- printf("%s%s", this->arg1_3 != "" ? " " : "", this->arg1_3);
- printf("%s%s", this->arg1_4 != "" ? " " : "", this->arg1_4);
- printf("%s", this->arg1_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid0, this->uid0, this->gid0, this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("%s", this->arg0_0 != "" ? "\n" : "");
-}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 11, 9:30 PM (2 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25181138
Default Alt Text
D10006.id26472.diff (127 KB)
Attached To
Mode
D10006: Add dwatch(8) for watching processes as they trigger dtrace probe
Attached
Detach File
Event Timeline
Log In to Comment