Page MenuHomeFreeBSD

D10006.id26472.diff
No OneTemporary

D10006.id26472.diff

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

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)

Event Timeline