mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-25 07:49:18 +00:00
Introduce dwatch(1) as a tool for making DTrace more useful
Reviewed by: markj, gnn, bdrewery (earlier version) Relnotes: yes Sponsored by: Smule, Inc. Differential Revision: https://reviews.freebsd.org/D10006
This commit is contained in:
parent
b3e8ee5d05
commit
5bf5ca772c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=330559
@ -38,6 +38,10 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20180306: remove DTrace scripts made obsolete by dwatch(1)
|
||||
OLD_FILES+=usr/share/dtrace/watch_execve
|
||||
OLD_FILES+=usr/share/dtrace/watch_kill
|
||||
OLD_FILES+=usr/share/dtrace/watch_vop_remove
|
||||
# 20180212: move devmatch
|
||||
OLD_FILES+=usr/sbin/devmatch
|
||||
# 20180211: remove usb.conf
|
||||
|
@ -3,6 +3,7 @@
|
||||
.include <src.opts.mk>
|
||||
|
||||
SUBDIR= ${_dtrace} \
|
||||
${_dwatch} \
|
||||
${_lockstat} \
|
||||
${_plockstat} \
|
||||
${_zdb} \
|
||||
@ -23,6 +24,7 @@ _zfsd= zfsd
|
||||
|
||||
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
|
||||
_dtrace= dtrace
|
||||
_dwatch= dwatch
|
||||
_lockstat= lockstat
|
||||
_plockstat= plockstat
|
||||
.endif
|
||||
@ -30,15 +32,18 @@ _plockstat= plockstat
|
||||
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
|
||||
${MACHINE_CPUARCH} == "riscv"
|
||||
_dtrace= dtrace
|
||||
_dwatch= dwatch
|
||||
_lockstat= lockstat
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "mips"
|
||||
_dtrace= dtrace
|
||||
_dwatch= dwatch
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "powerpc"
|
||||
_dtrace= dtrace
|
||||
_dwatch= dwatch
|
||||
_lockstat= lockstat
|
||||
.endif
|
||||
|
||||
|
15
cddl/usr.sbin/dwatch/Makefile
Normal file
15
cddl/usr.sbin/dwatch/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
SUBDIR= libexec
|
||||
|
||||
.if ${MK_EXAMPLES} != "no"
|
||||
SUBDIR+= examples
|
||||
.endif
|
||||
|
||||
SCRIPTS= dwatch
|
||||
|
||||
MAN= dwatch.1
|
||||
|
||||
.include <bsd.prog.mk>
|
1291
cddl/usr.sbin/dwatch/dwatch
Executable file
1291
cddl/usr.sbin/dwatch/dwatch
Executable file
File diff suppressed because it is too large
Load Diff
766
cddl/usr.sbin/dwatch/dwatch.1
Normal file
766
cddl/usr.sbin/dwatch/dwatch.1
Normal file
@ -0,0 +1,766 @@
|
||||
.\" Copyright (c) 2014-2018 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 February 9, 2018
|
||||
.Dt DWATCH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm dwatch
|
||||
.Nd watch processes as they trigger a particular DTrace probe
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 1defFmnPqRvVwxy
|
||||
.Op Fl B Ar num
|
||||
.Op Fl E Ar code
|
||||
.Op Fl g Ar group
|
||||
.Op Fl j Ar jail
|
||||
.Op Fl k Ar name
|
||||
.Op Fl K Ar num
|
||||
.Op Fl N Ar count
|
||||
.Op Fl o Ar file
|
||||
.Op Fl O Ar cmd
|
||||
.Op Fl p Ar pid
|
||||
.Op Fl r Ar regex
|
||||
.Op Fl t Ar test
|
||||
.Op Fl T Ar time
|
||||
.Op Fl u Ar user
|
||||
.Op Fl X Ar profile
|
||||
.Op Fl z Ar regex
|
||||
.Op Fl -
|
||||
.Op probe[,...]
|
||||
.Op args ...
|
||||
.Nm
|
||||
.Fl l
|
||||
.Op Fl fmnPqy
|
||||
.Op Fl r Ar regex
|
||||
.Op probe ...
|
||||
.Nm
|
||||
.Fl Q
|
||||
.Op Fl 1qy
|
||||
.Op Fl r Ar regex
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility uses
|
||||
.Xr dtrace 1
|
||||
to display process info when a given DTrace probe point is triggered.
|
||||
Only the root user or users with
|
||||
.Xr sudo 8
|
||||
access can run this command.
|
||||
.Pp
|
||||
.Nm
|
||||
automates the process of generating DTrace scripts to coalesce trace output by
|
||||
date/time,
|
||||
process info,
|
||||
and
|
||||
.Op optionally
|
||||
probe-specific data.
|
||||
.Pp
|
||||
Output format without options is:
|
||||
.Pp
|
||||
.Dl date/time uid.gid execname[pid]: psargs
|
||||
.Pp
|
||||
For example,
|
||||
the command
|
||||
.Ql dwatch BEGIN
|
||||
produces:
|
||||
.Pp
|
||||
.Dl INFO Watching 'dtrace:::BEGIN' ...
|
||||
.Dl 2017 May 29 08:23:20 0.0 dtrace[60671]: dtrace -s /dev/stdin
|
||||
.Pp
|
||||
The
|
||||
.Fl F
|
||||
option causes
|
||||
.Nm
|
||||
to instead coalesce trace output by date/time,
|
||||
process info,
|
||||
and probe traversal.
|
||||
.Pp
|
||||
Output format with the
|
||||
.Ql Fl F
|
||||
option is:
|
||||
.Pp
|
||||
.Dl date/time uid.gid execname[pid]: {->,<-, |} prov:mod:func:name ...
|
||||
.Pp
|
||||
For example,
|
||||
the command
|
||||
.Ql dwatch -F BEGIN
|
||||
produces:
|
||||
.Pp
|
||||
.Dl INFO Watching 'dtrace:::BEGIN' ...
|
||||
.Dl 2017 May 29 21:34:41 0.0 dtrace[86593]: | dtrace:::BEGIN ...
|
||||
.Pp
|
||||
The
|
||||
.Fl R
|
||||
option causes
|
||||
.Nm
|
||||
to display a process tree containing the parent,
|
||||
grandparent,
|
||||
and ancestor process info.
|
||||
.Pp
|
||||
Output format with the
|
||||
.Ql Fl R
|
||||
option is:
|
||||
.Pp
|
||||
.Dl date/time uid0.gid0 execname[pid0]: psargs0
|
||||
.Dl " -+= pid3 uid3.gid3 psargs3"
|
||||
.Dl " \e\\-+= pid2 uid2.gid2 psargs2"
|
||||
.Dl " \e\\-+= pid1 uid1.gid1 psargs1"
|
||||
.Dl " \e\\-+= pid0 uid0.guid0 psargs0"
|
||||
.Pp
|
||||
For example,
|
||||
the command
|
||||
.Ql dwatch -R BEGIN
|
||||
produces:
|
||||
.Pp
|
||||
.Dl INFO Watching 'dtrace:::BEGIN' ...
|
||||
.Dl 2017 May 29 21:38:54 0.0 dtrace[86899]: dtrace -s /dev/stdin
|
||||
.Dl " -+= 86855 604.604 -bash"
|
||||
.Dl " \e\\-+= 86857 604.604 /bin/sh /usr/sbin/dwatch -R BEGIN"
|
||||
.Dl " \e\\-+= 86897 0.0 sudo dtrace -s /dev/stdin"
|
||||
.Dl " \e\\-+= 86899 0.0 dtrace -s /dev/stdin"
|
||||
.Pp
|
||||
Of particular interest is the ability to filter using regular expressions.
|
||||
The
|
||||
.Ql Fl g Ar group ,
|
||||
.Ql Fl p Ar pid ,
|
||||
.Ql Fl r Ar regex ,
|
||||
.Ql Fl u Ar user ,
|
||||
and
|
||||
.Ql Fl z Ar regex
|
||||
options can be combined with
|
||||
.Ql Fl R
|
||||
to match on parent process criteria as well as current process info.
|
||||
.Pp
|
||||
In contrast,
|
||||
the
|
||||
.Ql Fl j Ar jail ,
|
||||
and
|
||||
.Ql Fl k Ar name
|
||||
options apply only to the current process even if
|
||||
.Ql Fl R
|
||||
is given.
|
||||
.Pp
|
||||
The
|
||||
.Ql Fl E Ar code
|
||||
option gives the ability to customize probe-specific data.
|
||||
For example,
|
||||
the command:
|
||||
.Pp
|
||||
.Dl dwatch -E 'printf("%s", copyinstr(arg0))' chdir
|
||||
.Pp
|
||||
displays the path argument sent to
|
||||
.Xr chdir 2
|
||||
calls.
|
||||
.Pp
|
||||
Profiles can be written for more complex routines and/or convenience.
|
||||
To list available profiles use the
|
||||
.Ql Fl Q
|
||||
option.
|
||||
Use the
|
||||
.Ql Fl X Ar profile
|
||||
option to use a particular profile.
|
||||
.Pp
|
||||
For example,
|
||||
the command
|
||||
.Ql dwatch -X kill
|
||||
displays arguments sent to
|
||||
.Xr kill 2 .
|
||||
.Sh OPTIONS
|
||||
If a
|
||||
.Ar probe
|
||||
argument does not contain colon
|
||||
.Pq Qo Li ":" Qc
|
||||
and none of
|
||||
.Ql Fl P ,
|
||||
.Ql Fl m ,
|
||||
.Ql Fl f ,
|
||||
or
|
||||
.Ql Fl n
|
||||
are given,
|
||||
the probe argument is intelligently mapped to its most-likely value.
|
||||
Use
|
||||
.Ql Nm Fl l Ar name
|
||||
to see what probes will match a given name.
|
||||
.Pp
|
||||
Multiple probes must be given as a single
|
||||
.Pq quoted
|
||||
argument,
|
||||
separated by comma and/or whitespace.
|
||||
Any/all arguments following said probes will be passed to
|
||||
.Xr dtrace 1
|
||||
unmodified.
|
||||
.Bl -tag -width "-c count"
|
||||
.It Fl 1
|
||||
Print one line per process/profile
|
||||
.Pq Default; disables Ql Fl R .
|
||||
.It Fl B Ar num
|
||||
Maximum number of arguments to display
|
||||
.Pq Default 64 .
|
||||
.It Fl d
|
||||
Debug.
|
||||
Send
|
||||
.Xr dtrace 1
|
||||
script to stdout instead of executing.
|
||||
.It Fl e
|
||||
Exit after compiling request but prior to enabling probes.
|
||||
.It Fl E Ar code
|
||||
DTrace
|
||||
.Ar code
|
||||
for event details.
|
||||
If `-',
|
||||
read from stdin.
|
||||
This allows customization of what is printed after date/time and process info.
|
||||
By default,
|
||||
the name and arguments of the program triggering the probe are shown.
|
||||
Can be specified multiple times.
|
||||
.It Fl f
|
||||
Enable probes matching the specified function names.
|
||||
.It Fl F
|
||||
Coalesce trace output by probe.
|
||||
.It Fl g Ar group
|
||||
Group filter.
|
||||
Only show processes matching
|
||||
.Ar group
|
||||
name/gid.
|
||||
This can be an
|
||||
.Xr awk 1
|
||||
regular expression to match a numerical gid.
|
||||
.It Fl j Ar jail
|
||||
Jail filter.
|
||||
Only show processes matching
|
||||
.Ar jail
|
||||
name/jid.
|
||||
.It Fl k Ar name
|
||||
Only show processes matching
|
||||
.Ar name .
|
||||
Can also be of the format
|
||||
.Ql Li name*
|
||||
to indicate
|
||||
.Dq Li begins with ,
|
||||
.Ql Li *name
|
||||
to indicate
|
||||
.Dq Li ends with ,
|
||||
or
|
||||
.Ql Li *name*
|
||||
to indicate
|
||||
.Dq Li contains .
|
||||
Can be specified multiple times.
|
||||
.It Fl K Ar num
|
||||
Maximum directory depth to display
|
||||
.Pq Default 64 .
|
||||
.It Fl l
|
||||
List available probes on standard output and exit.
|
||||
.It Fl m
|
||||
Enable probes matching the specified module names.
|
||||
.It Fl X Ar profile
|
||||
Load profile from DWATCH_PROFILES_PATH.
|
||||
.It Fl n
|
||||
Enable probes matching the specified probe names.
|
||||
.It Fl N Ar count
|
||||
Exit after
|
||||
.Ar count
|
||||
matching entries
|
||||
.Pq Default 0 for disabled .
|
||||
.It Fl o Ar file
|
||||
Set output file.
|
||||
If
|
||||
.Ql Li - ,
|
||||
the path
|
||||
.Ql Li /dev/stdout
|
||||
is used.
|
||||
.It Fl O Ar cmd
|
||||
Execute
|
||||
.Ar cmd
|
||||
for each event.
|
||||
This can be any valid
|
||||
.Xr sh 1
|
||||
command.
|
||||
The environment variables
|
||||
.Ql Li $TAG
|
||||
and
|
||||
.Ql Li $DETAILS
|
||||
are set for the given
|
||||
.Ar cmd .
|
||||
.It Fl p Ar pid
|
||||
Process id filter.
|
||||
Only show processes with matching
|
||||
.Ar pid .
|
||||
This can be an
|
||||
.Xr awk 1
|
||||
regular expression.
|
||||
.It Fl P
|
||||
Enable probe matching the specified provider name.
|
||||
.It Fl q
|
||||
Quiet.
|
||||
Hide informational messages and all dtrace(1) errors.
|
||||
.It Fl Q
|
||||
List available profiles in DWATCH_PROFILES_PATH and exit.
|
||||
.It Fl r Ar regex
|
||||
Filter.
|
||||
Only show blocks matching
|
||||
.Xr awk 1
|
||||
regular expression.
|
||||
.It Fl R
|
||||
Show parent,
|
||||
grandparent,
|
||||
and ancestor of process.
|
||||
.It Fl t Ar test
|
||||
Test clause
|
||||
.Pq predicate
|
||||
to limit events
|
||||
.Pq Default none .
|
||||
Can be specified multiple times.
|
||||
.It Fl T Ar time
|
||||
Timeout.
|
||||
The format is
|
||||
.Ql Li #[smhd]
|
||||
or just
|
||||
.Ql Li #
|
||||
for seconds.
|
||||
.It Fl u Ar user
|
||||
User filter.
|
||||
Only show processes matching
|
||||
.Ar user
|
||||
name/uid.
|
||||
This can be an
|
||||
.Xr awk 1
|
||||
regular expression to match a numerical UID.
|
||||
.It Fl v
|
||||
Verbose.
|
||||
Show all errors from
|
||||
.Xr dtrace 1 .
|
||||
.It Fl V
|
||||
Report
|
||||
.Nm
|
||||
version on standard output and exit.
|
||||
.It Fl w
|
||||
Permit destructive actions
|
||||
.Pq copyout*, stop, panic, etc. .
|
||||
.It Fl x
|
||||
Trace.
|
||||
Print
|
||||
.Ql Li <probe-id>
|
||||
when a probe is triggered.
|
||||
.It Fl y
|
||||
Always treat stdout as console
|
||||
.Pq enable colors/columns/etc. .
|
||||
.It Fl z Ar regex
|
||||
Only show processes matching
|
||||
.Xr awk 1
|
||||
regular expression.
|
||||
.El
|
||||
.Sh PROFILES
|
||||
Profiles customize the data printed during events.
|
||||
Profiles are loaded from a colon-separated list of directories in
|
||||
.Ev DWATCH_PROFILES_PATH .
|
||||
This is an incomplete list of profiles with basic descriptions:
|
||||
.Bl -tag -width "vop_readdir"
|
||||
.It chmod
|
||||
Print mode and path from
|
||||
.Xr chmod 2 ,
|
||||
.Xr lchmod 2 ,
|
||||
.Xr fchmodat 2
|
||||
.It errno
|
||||
Print non-zero errno results from system calls
|
||||
.It io
|
||||
Print disk I/O details provided by
|
||||
.Xr dtrace_io 4
|
||||
.It ip
|
||||
Print IPv4 and IPv6 details provided by
|
||||
.Xr dtrace_ip 4
|
||||
.It kill
|
||||
Print signal and pid from
|
||||
.Xr kill 2
|
||||
.It nanosleep
|
||||
Print requested time from
|
||||
.Xr nanosleep 2
|
||||
.It open
|
||||
Print path from
|
||||
.Xr open 2 ,
|
||||
.Xr openat 2
|
||||
.It proc
|
||||
Print process execution details provided by
|
||||
.Xr dtrace_proc 4
|
||||
.It proc-signal
|
||||
Print process signal details provided by
|
||||
.Xr dtrace_proc 4
|
||||
.It rw
|
||||
Print buffer contents from
|
||||
.Xr read 2 ,
|
||||
.Xr write 2
|
||||
.It sched
|
||||
Print CPU scheduling details provided by
|
||||
.Xr dtrace_sched 4
|
||||
.It tcp
|
||||
Print TCP address/port details provided by
|
||||
.Xr dtrace_tcp 4
|
||||
.It tcp-io
|
||||
Print TCP I/O details provided by
|
||||
.Xr dtrace_tcp 4
|
||||
.It udp
|
||||
Print UDP I/O details provided by
|
||||
.Xr dtrace_udp 4
|
||||
.It vop_create
|
||||
Print filesystem paths being created by
|
||||
.Xr VOP_CREATE 9
|
||||
.It vop_lookup
|
||||
Print filesystem paths being looked-up by
|
||||
.Xr VOP_LOOKUP 9
|
||||
.It vop_mkdir
|
||||
Print directory paths being created by
|
||||
.Xr VOP_MKDIR 9
|
||||
.It vop_mknod
|
||||
Print device node paths being created by
|
||||
.Xr VOP_MKNOD 9
|
||||
.It vop_readdir
|
||||
Print directory paths being read by
|
||||
.Xr VOP_READDIR 9
|
||||
.It vop_remove
|
||||
Print filesystem paths being removed by
|
||||
.Xr VOP_REMOVE 9
|
||||
.It vop_rename
|
||||
Print filesystem paths being renamed by
|
||||
.Xr VOP_RENAME 9
|
||||
.It vop_rmdir
|
||||
Print directory paths being removed by
|
||||
.Xr VOP_RMDIR 9
|
||||
.It vop_symlink
|
||||
Print symlink paths being created by
|
||||
.Xr VOP_SYMLINK 9
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
These environment variables affect the execution of
|
||||
.Nm :
|
||||
.Bl -tag -width "DWATCH_PROFILES_PATH"
|
||||
.It Ev DWATCH_PROFILES_PATH
|
||||
If
|
||||
.Ev DWATCH_PROFILES_PATH
|
||||
is set,
|
||||
.Nm
|
||||
searches for profiles in the colon-separated list of directories in that
|
||||
variable instead of the default
|
||||
.Ql Li /usr/libexec/dwatch:/usr/local/libexec/dwatch .
|
||||
If set to NULL,
|
||||
profiles are not loaded.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh EXAMPLES
|
||||
Watch processes entering system CPU scheduler.
|
||||
.Bd -literal -offset indent
|
||||
dwatch on-cpu
|
||||
.Ed
|
||||
.Pp
|
||||
List available profiles,
|
||||
one line per profile.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -1 -Q
|
||||
.Ed
|
||||
.Pp
|
||||
Do not execute
|
||||
.Xr dtrace 1
|
||||
but display script on stdout and exit.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -d fsync
|
||||
.Ed
|
||||
.Pp
|
||||
Compile and test but do not execute code generated with given probe.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -e test_probe
|
||||
.Ed
|
||||
.Pp
|
||||
Print argument one being passed to each call of zfs_sync().
|
||||
.Bd -literal -offset indent
|
||||
dwatch -E 'printf("%i", arg1)' zfs_sync
|
||||
.Ed
|
||||
.Pp
|
||||
Watch all functions named
|
||||
.Ql Li read .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -f read
|
||||
.Ed
|
||||
.Pp
|
||||
Watch all probe traversal.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -F :
|
||||
.Ed
|
||||
.Pp
|
||||
Watch syscall probe traversal.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -F syscall
|
||||
.Ed
|
||||
.Pp
|
||||
Display only processes belonging to wheel super-group.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -g wheel execve
|
||||
.Ed
|
||||
.Pp
|
||||
Display only processes belonging to groups
|
||||
.Ql Li daemon
|
||||
or
|
||||
.Ql Li nobody .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -g '1|65534' execve
|
||||
.Ed
|
||||
.Pp
|
||||
Ignore jails,
|
||||
displaying only base system processes.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -j 0 execve
|
||||
.Ed
|
||||
.Pp
|
||||
Display only processes running inside the jail named
|
||||
.Ql Li myjail .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -j myjail execve
|
||||
.Ed
|
||||
.Pp
|
||||
Watch syscall traversal by ruby processes.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -k 'ruby*' -F syscall
|
||||
.Ed
|
||||
.Pp
|
||||
Watch syscall traversal by processes containing
|
||||
.Ql Li daemon
|
||||
in their name.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -k '*daemon*' -F syscall
|
||||
.Ed
|
||||
.Pp
|
||||
Watch signals being passed to
|
||||
.Xr kill 2 .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -X kill
|
||||
.Ed
|
||||
.Pp
|
||||
Watch signals being passed between
|
||||
.Xr bash 1
|
||||
and
|
||||
.Xr vi 1 .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -k bash -k vi -X kill
|
||||
.Ed
|
||||
.Pp
|
||||
Display a list of unique functions available.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -l -f
|
||||
.Ed
|
||||
.Pp
|
||||
List available probes for functions ending in
|
||||
.Ql Li read .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -l -f '*read'
|
||||
.Ed
|
||||
.Pp
|
||||
List available probes ending in
|
||||
.Dq Li read .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -l -r 'read$'
|
||||
.Ed
|
||||
.Pp
|
||||
Display a list of unique providers.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -l -P
|
||||
.Ed
|
||||
.Pp
|
||||
Watch paths being removed by
|
||||
.Xr VOP_REMOVE 9 .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -X vop_remove
|
||||
.Ed
|
||||
.Pp
|
||||
Watch the name
|
||||
.Ql Li read
|
||||
instead of the function
|
||||
.Ql Li read .
|
||||
The
|
||||
.Nm
|
||||
selection algorithm will commonly favor the function named
|
||||
.Ql Li read
|
||||
when not given a type
|
||||
.Pq using So Fl P Sc , So Fl m Sc , So Fl f Sc , or So Fl n Sc
|
||||
because there are more probes matching the function named
|
||||
.Ql Li read
|
||||
than probes matching
|
||||
.Ql Li read
|
||||
for any other type.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -n read
|
||||
.Ed
|
||||
.Pp
|
||||
Display the first process to call
|
||||
.Xr kill 2
|
||||
and then exit.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -N 1 kill
|
||||
.Ed
|
||||
.Pp
|
||||
Watch processes forked by pid 1234.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -p 1234 execve
|
||||
.Ed
|
||||
.Pp
|
||||
Watch processes forked by either pid 1234 or pid 5678.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -p '1234|5678' execve
|
||||
.Ed
|
||||
.Pp
|
||||
Watch the provider
|
||||
.Ql Li random
|
||||
instead of the function
|
||||
.Ql Li random .
|
||||
The
|
||||
.Nm
|
||||
selection algorithm will commonly favor the function named
|
||||
.Ql Li random
|
||||
when not given a type
|
||||
.Pq using So Fl P Sc , So Fl m Sc , So Fl f Sc , or So Fl n Sc
|
||||
because there are more probes matching the function named
|
||||
.Ql Li random
|
||||
than probes matching the provider named
|
||||
.Ql Li random .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -P random
|
||||
.Ed
|
||||
.Pp
|
||||
Display available profiles matching
|
||||
.Ql Li vop .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -Q -r vop
|
||||
.Ed
|
||||
.Pp
|
||||
Watch
|
||||
.Xr VOP_LOOKUP 9
|
||||
paths containing
|
||||
.Ql Li /lib/ .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -r /lib/ -X vop_lookup
|
||||
.Ed
|
||||
.Pp
|
||||
Show process tree for each command as it is executed.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -R execve
|
||||
.Ed
|
||||
.Pp
|
||||
Watch processes forked by pid 1234 or children thereof.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -R -p 1234 execve
|
||||
.Ed
|
||||
.Pp
|
||||
Display processes calling
|
||||
.Xr write 2
|
||||
with
|
||||
.Dq nbytes
|
||||
less than 10.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -t 'arg2<10' -E 'printf("%d",arg2)' write
|
||||
.Ed
|
||||
.Pp
|
||||
Display
|
||||
.Xr write 2
|
||||
buffer when
|
||||
.Dq execname
|
||||
is not
|
||||
.Ql Li dtrace
|
||||
and
|
||||
.Dq nbytes
|
||||
is less than 10.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -X write -t 'execname != "dtrace" && this->nbytes < 10'
|
||||
.Ed
|
||||
.Pp
|
||||
Watch
|
||||
.Ql Li statfs
|
||||
for 5 minutes and exit.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -T 5m statfs
|
||||
.Ed
|
||||
.Pp
|
||||
Display only processes belonging to the root super-user.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -u root execve
|
||||
.Ed
|
||||
.Pp
|
||||
Display only processes belonging to users
|
||||
.Ql Li daemon
|
||||
or
|
||||
.Ql Li nobody .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -u '1|65534' execve
|
||||
.Ed
|
||||
.Pp
|
||||
Print version and exit.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -V
|
||||
.Ed
|
||||
.Pp
|
||||
View the first 100 scheduler preemptions.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -y -N 100 preempt | less -R
|
||||
.Ed
|
||||
.Pp
|
||||
Display processes matching either
|
||||
.Dq Li mkdir
|
||||
or
|
||||
.Dq Li rmdir .
|
||||
.Bd -literal -offset indent
|
||||
dwatch -z '(mk|rm)dir' execve
|
||||
.Ed
|
||||
.Pp
|
||||
Run a command and watch network activity only while that command runs.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -X tcp -- -c "nc -zvw10 google.com 22"
|
||||
.Ed
|
||||
.Pp
|
||||
Watch
|
||||
.Xr open 2
|
||||
and
|
||||
.Xr openat 2
|
||||
calls only while pid 1234 is active.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -X open -- -p 1234
|
||||
.Ed
|
||||
.Pp
|
||||
Watch probe traversal for a given command.
|
||||
Note that
|
||||
.Dq Li -c true
|
||||
is passed to
|
||||
.Xr dtrace 1
|
||||
since it appears after the
|
||||
.Nm
|
||||
probe argument.
|
||||
.Bd -literal -offset indent
|
||||
dwatch -F 'pid$target:::entry' -c true
|
||||
.Ed
|
||||
.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
|
6
cddl/usr.sbin/dwatch/examples/Makefile
Normal file
6
cddl/usr.sbin/dwatch/examples/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
FILESDIR= ${SHAREDIR}/examples/dwatch
|
||||
FILES= profile_template
|
||||
|
||||
.include <bsd.prog.mk>
|
74
cddl/usr.sbin/dwatch/examples/profile_template
Normal file
74
cddl/usr.sbin/dwatch/examples/profile_template
Normal file
@ -0,0 +1,74 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) profile for XXX entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# XXX
|
||||
#
|
||||
############################################################ PRAGMAS
|
||||
|
||||
# Optional: You can override the default pragmas (shown below)
|
||||
|
||||
#DTRACE_PRAGMA="
|
||||
# option quiet
|
||||
# option dynvarsize=16m
|
||||
# switchrate=10hz
|
||||
#" # END-QUOTE
|
||||
|
||||
############################################################ PROBE
|
||||
|
||||
# Optional: dwatch(8) initializes this to the expanded probe arguments
|
||||
|
||||
#: ${PROBE:="XXX"}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
# Optional actions to be performed before hitting the final print action
|
||||
|
||||
#exec 9<<EOF
|
||||
#EOF
|
||||
#ACTIONS=$( cat <&9 )
|
||||
#ID=
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
# The default EVENT value is simply `entry'. This is paired with $PROBE.
|
||||
|
||||
#EVENT=
|
||||
|
||||
# Optional predicate which must be true before the event action will run
|
||||
|
||||
#EVENT_TEST=
|
||||
|
||||
############################################################ 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 )
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
# The DETAILS are run after the EVENT_TAG and by default, the program name and
|
||||
# arguments of the process hitting the EVENT 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 EVENT 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
|
||||
################################################################################
|
80
cddl/usr.sbin/dwatch/libexec/Makefile
Normal file
80
cddl/usr.sbin/dwatch/libexec/Makefile
Normal file
@ -0,0 +1,80 @@
|
||||
# $FreeBSD$
|
||||
|
||||
FILESDIR= ${LIBEXECDIR}/dwatch
|
||||
FILES= chmod \
|
||||
errno \
|
||||
io \
|
||||
ip \
|
||||
kill \
|
||||
nanosleep \
|
||||
open \
|
||||
proc \
|
||||
rw \
|
||||
sched \
|
||||
tcp \
|
||||
udp \
|
||||
vop_create \
|
||||
vop_readdir \
|
||||
vop_rename \
|
||||
vop_symlink
|
||||
|
||||
LINKS= ${LIBEXECDIR}/dwatch/chmod ${LIBEXECDIR}/dwatch/fchmodat
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/chmod ${LIBEXECDIR}/dwatch/lchmod
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/io ${LIBEXECDIR}/dwatch/io-done
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/io ${LIBEXECDIR}/dwatch/io-start
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/ip ${LIBEXECDIR}/dwatch/ip-receive
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/ip ${LIBEXECDIR}/dwatch/ip-send
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/open ${LIBEXECDIR}/dwatch/openat
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-create
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exec
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exec-failure
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exec-success
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exit
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal-clear
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal-discard
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal-send
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-status
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/rw ${LIBEXECDIR}/dwatch/read
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/rw ${LIBEXECDIR}/dwatch/write
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-change-pri
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-cpu
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-dequeue
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-enqueue
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-exec
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-lend-pri
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-load-change
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-off-cpu
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-on-cpu
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-preempt
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-pri
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-queue
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-remain-cpu
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-sleep
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-surrender
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-tick
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-wakeup
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-accept
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-accept-established
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-accept-refused
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect-established
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect-refused
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect-request
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-established
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-init
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-io
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-receive
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-refused
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-send
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-state-change
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-status
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/udp ${LIBEXECDIR}/dwatch/udp-receive
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/udp ${LIBEXECDIR}/dwatch/udp-send
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_lookup
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_mkdir
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_mknod
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_remove
|
||||
LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_rmdir
|
||||
|
||||
.include <bsd.prog.mk>
|
63
cddl/usr.sbin/dwatch/libexec/chmod
Normal file
63
cddl/usr.sbin/dwatch/libexec/chmod
Normal file
@ -0,0 +1,63 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for [l]chmod(2), fchmodat(2), or similar entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print mode/path being passed to chmod(2), lchmod(2), fchmodat(2), or similar
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
chmod)
|
||||
: ${PROBE:=$( echo \
|
||||
syscall::chmod:entry, \
|
||||
syscall::lchmod:entry, \
|
||||
syscall::fchmodat:entry )}
|
||||
;;
|
||||
*)
|
||||
: ${PROBE:=syscall::$PROFILE:entry}
|
||||
esac
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this mode_t mode;
|
||||
this string path;
|
||||
this u_char at;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");
|
||||
}
|
||||
/*
|
||||
* Should we expect the first argument to be a file descriptor?
|
||||
* NB: Based on probefunc ending in "at" (e.g., fchmodat(2))
|
||||
*/
|
||||
this->at = strstr(probefunc, "at") ==
|
||||
(probefunc + strlen(probefunc) - 2) ? 1 : 0;
|
||||
|
||||
this->mode = (mode_t)(this->at ? arg2 : arg1);
|
||||
this->path = copyinstr(this->at ? arg1 : arg0);
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print mode/path details
|
||||
*/
|
||||
printf("%04o %s", this->mode, this->path);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
35
cddl/usr.sbin/dwatch/libexec/errno
Normal file
35
cddl/usr.sbin/dwatch/libexec/errno
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for syscall errno logging $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print when syscall returns with non-zero errno (default) or other condition.
|
||||
# To override the default test condition, use (for example) `-t errno==2' to
|
||||
# test for specific value or simply `-t 1' to unconditionally show all values.
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=syscall:::return}
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
[ "$CUSTOM_TEST" ] || EVENT_TEST="errno > 0"
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print errno details
|
||||
*/
|
||||
printf("%s: %s (%i)", probefunc, strerror[errno], errno);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
106
cddl/usr.sbin/dwatch/libexec/io
Normal file
106
cddl/usr.sbin/dwatch/libexec/io
Normal file
@ -0,0 +1,106 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for dtrace_io(4) $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display activity related to disk I/O
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
io) : ${PROBE:=io:::start, io:::done} ;;
|
||||
*) : ${PROBE:=io:::${PROFILE#io-}}
|
||||
esac
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
[ "$CUSTOM_TEST" ] || EVENT_TEST='this->devinfo.dev_name != ""'
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this bufinfo_t bufinfo;
|
||||
this devinfo_t devinfo;
|
||||
this int b_flags;
|
||||
this long bio_length;
|
||||
this string bio_cmd;
|
||||
this string bio_flags;
|
||||
this string device_entry;
|
||||
this string device_if;
|
||||
this string device_type;
|
||||
this string flow;
|
||||
|
||||
inline string append_bio_flag[int flags, int flag] = this->bio_flags =
|
||||
strjoin(this->bio_flags,
|
||||
strjoin(this->bio_flags == "" ? "" : (flags & flag) == flag ? "|" : "",
|
||||
bio_flag_string[flags & flag]));
|
||||
|
||||
$PROBE /(struct bio *)args[0] != NULL/ /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");
|
||||
}
|
||||
/*
|
||||
* dtrace_io(4)
|
||||
*/
|
||||
this->flow = probefunc == "done" ? "<-" : "->";
|
||||
|
||||
/*
|
||||
* struct bio *
|
||||
*/
|
||||
this->bufinfo = xlate <bufinfo_t> ((struct bio *)args[0]);
|
||||
this->bio_cmd = bio_cmd_string[(int)this->bufinfo.b_cmd];
|
||||
this->b_flags = (int)this->bufinfo.b_flags;
|
||||
this->bio_flags = bio_flag_string[this->b_flags & BIO_ERROR];
|
||||
this->bio_flags = strjoin(this->bio_flags, this->bufinfo.b_error ?
|
||||
strjoin(this->bio_flags == "" ?
|
||||
bio_flag_string[BIO_ERROR] : "",
|
||||
strjoin("#", lltostr(this->bufinfo.b_error))) :
|
||||
"");
|
||||
append_bio_flag[this->b_flags, BIO_DONE];
|
||||
append_bio_flag[this->b_flags, BIO_ONQUEUE];
|
||||
append_bio_flag[this->b_flags, BIO_ORDERED];
|
||||
append_bio_flag[this->b_flags, BIO_UNMAPPED];
|
||||
append_bio_flag[this->b_flags, BIO_TRANSIENT_MAPPING];
|
||||
append_bio_flag[this->b_flags, BIO_VLIST];
|
||||
this->bio_flags = this->bio_flags == "" ? "-" : this->bio_flags;
|
||||
this->bio_length = (long)this->bufinfo.b_bcount;
|
||||
|
||||
/*
|
||||
* struct devstat *
|
||||
*/
|
||||
this->devinfo = xlate <devinfo_t> ((struct devstat *)args[1]);
|
||||
this->device_type = device_type[(int)this->devinfo.dev_type];
|
||||
this->device_if = device_if[(int)this->devinfo.dev_type];
|
||||
this->device_entry = strjoin(this->devinfo.dev_name,
|
||||
lltostr(this->devinfo.dev_minor));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print disk I/O details
|
||||
*/
|
||||
printf("%s %s %s %s %s %s %d byte%s",
|
||||
this->flow,
|
||||
this->device_type,
|
||||
this->device_if,
|
||||
this->device_entry,
|
||||
this->bio_cmd,
|
||||
this->bio_flags,
|
||||
this->bio_length,
|
||||
this->bio_length == 1 ? "" : "s");
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
95
cddl/usr.sbin/dwatch/libexec/ip
Normal file
95
cddl/usr.sbin/dwatch/libexec/ip
Normal file
@ -0,0 +1,95 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for dtrace_ip(4) $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display interface name and bytes sent/received when IP I/O occurs
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
ip) : ${PROBE:=ip:::send, ip:::receive} ;;
|
||||
*) : ${PROBE:=ip:::${PROFILE#ip-}}
|
||||
esac
|
||||
|
||||
############################################################ GLOBALS
|
||||
|
||||
#
|
||||
# This profile does not support these dwatch features
|
||||
# NB: They are disabled here so they have no effect when profile is loaded
|
||||
#
|
||||
unset EXECNAME # -k name
|
||||
unset EXECREGEX # -z regex
|
||||
unset GROUP # -g group
|
||||
unset PID # -p pid
|
||||
unset PSARGS # affects -d
|
||||
unset PSTREE # -R
|
||||
unset USER # -u user
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this string flow;
|
||||
this string if_name;
|
||||
this string local;
|
||||
this string remote;
|
||||
this u_char recv;
|
||||
this uint32_t length;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");
|
||||
}
|
||||
/*
|
||||
* dtrace_ip(4)
|
||||
*/
|
||||
this->recv = probename == "receive" ? 1 : 0;
|
||||
this->flow = this->recv ? "<-" : "->";
|
||||
|
||||
/*
|
||||
* ipinfo_t *
|
||||
*/
|
||||
this->length = (uint32_t)args[2]->ip_plength;
|
||||
this->local = this->recv ? args[2]->ip_daddr : args[2]->ip_saddr;
|
||||
this->remote = this->recv ? args[2]->ip_saddr : args[2]->ip_daddr;
|
||||
|
||||
/*
|
||||
* ifinfo_t *
|
||||
*/
|
||||
this->if_name = args[3]->if_name;
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT TAG
|
||||
|
||||
exec 9<<EOF
|
||||
printf("%s: ", "$PROFILE");
|
||||
EOF
|
||||
EVENT_TAG=$( cat <&9 )
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print network I/O details
|
||||
*/
|
||||
printf("%s %s %s %s %u byte%s",
|
||||
this->if_name,
|
||||
this->local,
|
||||
this->flow,
|
||||
this->remote,
|
||||
this->length,
|
||||
this->length == 1 ? "" : "s");
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
45
cddl/usr.sbin/dwatch/libexec/kill
Normal file
45
cddl/usr.sbin/dwatch/libexec/kill
Normal file
@ -0,0 +1,45 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for kill(2) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print arguments being passed to kill(2) [or similar]
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=syscall::$PROFILE:entry}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this int sig;
|
||||
this pid_t pid;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
this->pid = (pid_t)arg0;
|
||||
this->sig = (int)arg1;
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print signal/pid details
|
||||
*/
|
||||
printf("signal %i to pid %d", this->sig, this->pid);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
52
cddl/usr.sbin/dwatch/libexec/nanosleep
Normal file
52
cddl/usr.sbin/dwatch/libexec/nanosleep
Normal file
@ -0,0 +1,52 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for nanosleep(2) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print arguments being passed to nanosleep(2) [or similar]
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=syscall::$PROFILE:entry}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this struct timespec * rqtp;
|
||||
this time_t requested_sec;
|
||||
this long requested_nsec;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
print("<$ID>");
|
||||
}
|
||||
/*
|
||||
* const struct timespec *
|
||||
*/
|
||||
this->rqtp = (struct timespec *)copyin(arg0, sizeof(struct timespec));
|
||||
this->requested_sec = (time_t)this->rqtp->tv_sec;
|
||||
this->requested_nsec = (long)this->rqtp->tv_nsec;
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Dump nanosleep(2) arguments
|
||||
*/
|
||||
printf("%d.%d seconds",
|
||||
this->requested_sec, this->requested_nsec / 100000);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
55
cddl/usr.sbin/dwatch/libexec/open
Normal file
55
cddl/usr.sbin/dwatch/libexec/open
Normal file
@ -0,0 +1,55 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for open[at](2) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print path being passed to open(2), openat(2), or similar
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
open) : ${PROBE:=syscall::open:entry, syscall::openat:entry} ;;
|
||||
*) : ${PROBE:=syscall::$PROFILE:entry}
|
||||
esac
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this string path;
|
||||
this u_char at;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");
|
||||
}
|
||||
/*
|
||||
* Should we expect the first argument to be a file descriptor?
|
||||
* NB: Based on probefunc ending in "at" (e.g., openat(2))
|
||||
*/
|
||||
this->at = strstr(probefunc, "at") ==
|
||||
(probefunc + strlen(probefunc) - 2) ? 1 : 0;
|
||||
|
||||
this->path = copyinstr(this->at ? arg1 : arg0);
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print path details
|
||||
*/
|
||||
printf("%s", this->path);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
162
cddl/usr.sbin/dwatch/libexec/proc
Normal file
162
cddl/usr.sbin/dwatch/libexec/proc
Normal file
@ -0,0 +1,162 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for dtrace_proc(4) activity $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display process activity
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
proc)
|
||||
: ${PROBE:=$( echo \
|
||||
proc:::create, \
|
||||
proc:::exec, \
|
||||
proc:::exec-failure, \
|
||||
proc:::exec-success, \
|
||||
proc:::exit, \
|
||||
proc:::signal-clear, \
|
||||
proc:::signal-discard, \
|
||||
proc:::signal-send )}
|
||||
;;
|
||||
proc-signal)
|
||||
: ${PROBE:=$( echo \
|
||||
proc:::signal-clear, \
|
||||
proc:::signal-discard, \
|
||||
proc:::signal-send )}
|
||||
;;
|
||||
proc-status)
|
||||
: ${PROBE:=$( echo \
|
||||
proc:::create, \
|
||||
proc:::exec, \
|
||||
proc:::exec-failure, \
|
||||
proc:::exec-success, \
|
||||
proc:::exit )}
|
||||
;;
|
||||
*)
|
||||
: ${PROBE:=proc:::${PROFILE#proc-}}
|
||||
esac
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this int sig;
|
||||
this pid_t pid;
|
||||
this string details;
|
||||
this string exec_arg0;
|
||||
|
||||
inline string probealias[string name] =
|
||||
name == "create" ? "FORK" :
|
||||
name == "exec" ? "EXEC" :
|
||||
name == "exec-failure" ? "FAIL" :
|
||||
name == "exec-success" ? "INIT" :
|
||||
name == "exit" ? "EXIT" :
|
||||
name == "signal-clear" ? "CLEAR" :
|
||||
name == "signal-discard" ? "DISCARD" :
|
||||
name == "signal-send" ? "SEND" :
|
||||
name;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
this->details = "";
|
||||
}
|
||||
|
||||
proc:::create /* probe ID $(( $ID + 1 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");
|
||||
}
|
||||
$( pproc -P _create "(struct proc *)args[0]" )
|
||||
|
||||
/* details = "pid <pid of args[0]> -- <proc args of args[0]>" */
|
||||
this->details = strjoin(
|
||||
strjoin("pid ", lltostr(this->pid_create)),
|
||||
strjoin(" -- ", this->args_create));
|
||||
}
|
||||
|
||||
proc:::exec /* probe ID $(( $ID + 2 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))");}
|
||||
this->details = this->exec_arg0 = stringof(arg0);
|
||||
}
|
||||
|
||||
proc:::exec-failure /* probe ID $(( $ID + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");
|
||||
}
|
||||
/* details = "<arg0 from proc:::exec>: <strerror of arg0> (<arg0>)" */
|
||||
this->details = strjoin(
|
||||
strjoin(this->exec_arg0, ": "),
|
||||
strjoin(strerror[(int)arg0],
|
||||
strjoin(" (", strjoin(lltostr((int)arg0), ")"))));
|
||||
}
|
||||
|
||||
proc:::exec-success /* probe ID $(( $ID + 4 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 4 ))>");}
|
||||
this->details = this->args0;
|
||||
}
|
||||
|
||||
proc:::exit /* probe ID $(( $ID + 5 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 5 ))>");}
|
||||
this->details = child_signal_string[(int)arg0];
|
||||
}
|
||||
|
||||
proc:::signal-clear /* probe ID $(( $ID + 6 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 6 ))>");}
|
||||
this->pid = (pid_t)((ksiginfo_t *)args[1])->ksi_info.si_pid;
|
||||
this->sig = (int)arg0;
|
||||
}
|
||||
|
||||
proc:::signal-discard, proc:::signal-send /* probe ID $(( $ID + 7 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 7 ))>");}
|
||||
this->pid = (pid_t)((struct proc *)args[1])->p_pid;
|
||||
this->sig = (int)arg2;
|
||||
}
|
||||
|
||||
proc:::signal-clear,
|
||||
proc:::signal-discard,
|
||||
proc:::signal-send /* probe ID $(( $ID + 8 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 8 ))>");
|
||||
}
|
||||
/* details = "<signal>[<num>] pid <pid>" */
|
||||
this->details = strjoin(strjoin(signal_string[this->sig], "["),
|
||||
strjoin(strjoin(lltostr(this->sig), "] pid "),
|
||||
lltostr(this->pid)));
|
||||
}
|
||||
|
||||
proc:::signal-send, proc:::signal-discard /* probe ID $(( $ID + 9 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 9 ))>");
|
||||
}
|
||||
$( pproc -P _signal "(struct proc *)args[1]" )
|
||||
|
||||
this->details = strjoin(this->details,
|
||||
strjoin(" -- ", this->args_signal));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 10 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print details
|
||||
*/
|
||||
printf("%s %s", probealias[probename], this->details);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
72
cddl/usr.sbin/dwatch/libexec/rw
Normal file
72
cddl/usr.sbin/dwatch/libexec/rw
Normal file
@ -0,0 +1,72 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for read(2), write(2), or similar entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display data sent/received when read(2)/write(2) occurs
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
rw) : ${PROBE:=syscall::read:entry, syscall::write:entry} ;;
|
||||
*) : ${PROBE:=syscall::$PROFILE:entry}
|
||||
esac
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this size_t nbytes;
|
||||
this string bufstr;
|
||||
this string flow;
|
||||
this void * buf;
|
||||
this void * data;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");
|
||||
}
|
||||
/*
|
||||
* R/W
|
||||
*/
|
||||
this->flow = probefunc == "read" ? "<-" : "->";
|
||||
this->buf = (void *)arg1;
|
||||
this->nbytes = (size_t)arg2;
|
||||
|
||||
/*
|
||||
* Allocate temporary memory for, copy, and NUL-terminate the data
|
||||
*/
|
||||
this->data = alloca(this->nbytes + 1);
|
||||
copyinto((uintptr_t)this->buf, this->nbytes, this->data);
|
||||
bcopy("\0", (void *)((uintptr_t)this->data + this->nbytes), 1);
|
||||
|
||||
/*
|
||||
* Extract string from temporary memory
|
||||
*/
|
||||
this->bufstr = stringof(this->data);
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print read/write details
|
||||
*/
|
||||
printf("%s \"%s\" %d byte%s",
|
||||
this->flow,
|
||||
this->bufstr,
|
||||
this->nbytes,
|
||||
this->nbytes == 1 ? "" : "s");
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
107
cddl/usr.sbin/dwatch/libexec/sched
Normal file
107
cddl/usr.sbin/dwatch/libexec/sched
Normal file
@ -0,0 +1,107 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for dtrace_sched(4) $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display CPU scheduling activity
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
sched)
|
||||
: ${PROBE:=sched:::} ;;
|
||||
sched-cpu)
|
||||
: ${PROBE:=sched:::off-cpu, sched:::on-cpu, sched:::remain-cpu} ;;
|
||||
sched-exec)
|
||||
: ${PROBE:=sched:::sleep, sched:::wakeup} ;;
|
||||
sched-pri)
|
||||
: ${PROBE:=sched:::change-pri, sched:::lend-pri} ;;
|
||||
sched-queue)
|
||||
: ${PROBE:=sched:::dequeue, sched:::enqueue, sched:::load-change} ;;
|
||||
*)
|
||||
: ${PROBE:=sched:::${PROFILE#sched-}}
|
||||
esac
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this pid_t pid;
|
||||
this string args;
|
||||
this string details;
|
||||
this u_char curprio;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
this->args = this->args0;
|
||||
this->details = "";
|
||||
this->pid = this->pid0;
|
||||
}
|
||||
|
||||
sched:::change-pri, sched:::dequeue, sched:::enqueue,
|
||||
sched:::lend-pri, sched:::off-cpu, sched:::surrender,
|
||||
sched:::tick, sched:::wakeup /* probe ID $(( $ID + 1 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");}
|
||||
this->curprio = (u_char)((struct thread *)args[0])->td_priority;
|
||||
|
||||
$( pproc -P _sched "(struct proc *)args[1]" )
|
||||
|
||||
this->args = this->args_sched;
|
||||
this->pid = this->pid_sched;
|
||||
}
|
||||
|
||||
sched:::enqueue /* probe ID $(( $ID + 2 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))>");}
|
||||
/* details = "head" or "tail" */
|
||||
this->details = (int)arg3 == 0 ? "tail" : "head";
|
||||
}
|
||||
|
||||
sched:::change-pri, sched:::lend-pri /* probe ID $(( $ID + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");}
|
||||
/* details = "<curprio> -> arg2" */
|
||||
this->details = strjoin(lltostr(this->curprio),
|
||||
strjoin("->", lltostr((uint8_t)arg2)));
|
||||
}
|
||||
|
||||
sched:::load-change /* probe ID $(( $ID + 4 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 4 ))>");}
|
||||
/* details = "CPU<arg0> queue <arg1>" */
|
||||
this->details = strjoin(strjoin("CPU", lltostr((int)arg0)),
|
||||
strjoin(" queue ", lltostr((int)arg1)));
|
||||
}
|
||||
|
||||
$PROBE /* probe ID $(( $ID + 5 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 5 ))>");}
|
||||
/* details += " pid <pid> -- <proc args of pid>" */
|
||||
this->details = strjoin(this->details, this->details == "" ? "" : " ");
|
||||
this->details = strjoin(this->details, strjoin(
|
||||
strjoin("pid ", lltostr(this->pid_sched)),
|
||||
strjoin(" -- ", this->args)));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 6 ))
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print scheduling details
|
||||
*/
|
||||
printf("%s %s", probename, this->details);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
229
cddl/usr.sbin/dwatch/libexec/tcp
Normal file
229
cddl/usr.sbin/dwatch/libexec/tcp
Normal file
@ -0,0 +1,229 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for dtrace_tcp(4) connections $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display local/remote TCP addresses/ports and bytes sent/received for TCP I/O
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
tcp)
|
||||
: ${PROBE:=$( echo \
|
||||
tcp:::accept-established, \
|
||||
tcp:::accept-refused, \
|
||||
tcp:::connect-established, \
|
||||
tcp:::connect-refused, \
|
||||
tcp:::connect-request, \
|
||||
tcp:::receive, \
|
||||
tcp:::send, \
|
||||
tcp:::state-change )} ;;
|
||||
tcp-accept)
|
||||
: ${PROBE:=tcp:::accept-established, tcp:::accept-refused} ;;
|
||||
tcp-connect)
|
||||
: ${PROBE:=$( echo \
|
||||
tcp:::connect-established, \
|
||||
tcp:::connect-refused, \
|
||||
tcp:::connect-request )} ;;
|
||||
tcp-established)
|
||||
: ${PROBE:=tcp:::accept-established, tcp:::connect-established} ;;
|
||||
tcp-init)
|
||||
: ${PROBE:=$( echo \
|
||||
tcp:::accept-established, \
|
||||
tcp:::accept-refused, \
|
||||
tcp:::connect-established, \
|
||||
tcp:::connect-refused, \
|
||||
tcp:::connect-request )} ;;
|
||||
tcp-io)
|
||||
: ${PROBE:=tcp:::send, tcp:::receive} ;;
|
||||
tcp-refused)
|
||||
: ${PROBE:=tcp:::accept-refused, tcp:::connect-refused} ;;
|
||||
tcp-status)
|
||||
: ${PROBE:=$( echo \
|
||||
tcp:::accept-established, \
|
||||
tcp:::accept-refused, \
|
||||
tcp:::connect-established, \
|
||||
tcp:::connect-refused, \
|
||||
tcp:::connect-request, \
|
||||
tcp:::state-change )} ;;
|
||||
*)
|
||||
: ${PROBE:=tcp:::${PROFILE#tcp-}}
|
||||
esac
|
||||
|
||||
############################################################ GLOBALS
|
||||
|
||||
#
|
||||
# This profile does not support these dwatch features
|
||||
# NB: They are disabled here so they have no effect when profile is loaded
|
||||
#
|
||||
unset EXECNAME # -k name
|
||||
unset EXECREGEX # -z regex
|
||||
unset GROUP # -g group
|
||||
unset PID # -p pid
|
||||
unset PSARGS # affects -d
|
||||
unset PSTREE # -R
|
||||
unset USER # -u user
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this int32_t from_state;
|
||||
this int32_t to_state;
|
||||
this string details;
|
||||
this string flow;
|
||||
this string local;
|
||||
this string remote;
|
||||
this u_char local6;
|
||||
this u_char remote6;
|
||||
this u_char slocal;
|
||||
this uint16_t lport;
|
||||
this uint16_t rport;
|
||||
this uint32_t length;
|
||||
|
||||
inline string probeflow[string name] =
|
||||
name == "accept-established" ? "<-" :
|
||||
name == "accept-refused" ? "X-" :
|
||||
name == "connect-refused" ? "-X" :
|
||||
name == "connect-request" ? "-?" :
|
||||
name == "receive" ? "<-" :
|
||||
"->";
|
||||
|
||||
inline u_char srclocal[string name] =
|
||||
name == "accept-refused" ? 1 :
|
||||
name == "connect-request" ? 1 :
|
||||
name == "send" ? 1 :
|
||||
0;
|
||||
|
||||
/*
|
||||
* TCPSTATES from <sys/netinet/tcp_fsm.h> used by netstat(1)
|
||||
*/
|
||||
inline string tcpstate[int32_t state] =
|
||||
state == TCPS_CLOSED ? "CLOSED" :
|
||||
state == TCPS_LISTEN ? "LISTEN" :
|
||||
state == TCPS_SYN_SENT ? "SYN_SENT" :
|
||||
state == TCPS_SYN_RECEIVED ? "SYN_RCVD" :
|
||||
state == TCPS_ESTABLISHED ? "ESTABLISHED" :
|
||||
state == TCPS_CLOSE_WAIT ? "CLOSE_WAIT" :
|
||||
state == TCPS_FIN_WAIT_1 ? "FIN_WAIT_1" :
|
||||
state == TCPS_CLOSING ? "CLOSING" :
|
||||
state == TCPS_LAST_ACK ? "LAST_ACK" :
|
||||
state == TCPS_FIN_WAIT_2 ? "FIN_WAIT_2" :
|
||||
state == TCPS_TIME_WAIT ? "TIME_WAIT" :
|
||||
strjoin("UNKNOWN(", strjoin(lltostr(state), ")"));
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
this->details = "";
|
||||
|
||||
/*
|
||||
* dtrace_tcp(4)
|
||||
*/
|
||||
this->flow = probeflow[probename];
|
||||
}
|
||||
|
||||
tcp:::accept-established,
|
||||
tcp:::accept-refused,
|
||||
tcp:::connect-established,
|
||||
tcp:::connect-refused,
|
||||
tcp:::connect-request,
|
||||
tcp:::receive,
|
||||
tcp:::send /* probe ID $(( $ID + 1 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");
|
||||
}
|
||||
/*
|
||||
* dtrace_tcp(4)
|
||||
*/
|
||||
this->slocal = srclocal[probename];
|
||||
|
||||
/*
|
||||
* ipinfo_t *
|
||||
*/
|
||||
this->local = this->slocal ? args[2]->ip_saddr : args[2]->ip_daddr;
|
||||
this->remote = this->slocal ? args[2]->ip_daddr : args[2]->ip_saddr;
|
||||
|
||||
/*
|
||||
* tcpinfo_t *
|
||||
*/
|
||||
this->lport = this->slocal ? args[4]->tcp_sport : args[4]->tcp_dport;
|
||||
this->rport = this->slocal ? args[4]->tcp_dport : args[4]->tcp_sport;
|
||||
|
||||
/*
|
||||
* IPv6 support
|
||||
*/
|
||||
this->local6 = strstr(this->local, ":") != NULL ? 1 : 0;
|
||||
this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0;
|
||||
this->local = strjoin(strjoin(this->local6 ? "[" : "",
|
||||
this->local), this->local6 ? "]" : "");
|
||||
this->remote = strjoin(strjoin(this->remote6 ? "[" : "",
|
||||
this->remote), this->remote6 ? "]" : "");
|
||||
}
|
||||
|
||||
tcp:::state-change /* probe ID $(( $ID + 2 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))>");
|
||||
}
|
||||
/*
|
||||
* tcpsinfo_t *
|
||||
*/
|
||||
this->local = args[3]->tcps_laddr;
|
||||
this->lport = (uint16_t)args[3]->tcps_lport;
|
||||
this->remote = args[3]->tcps_raddr;
|
||||
this->rport = (uint16_t)args[3]->tcps_rport;
|
||||
this->to_state = (int32_t)args[3]->tcps_state;
|
||||
|
||||
/*
|
||||
* tcplsinfo_t *
|
||||
*/
|
||||
this->from_state = (int32_t)args[5]->tcps_state;
|
||||
|
||||
/* flow = "[from state]->[to state]" */
|
||||
this->flow = strjoin(tcpstate[this->from_state],
|
||||
strjoin("->", tcpstate[this->to_state]));
|
||||
}
|
||||
|
||||
tcp:::send, tcp:::receive /* pribe ID $(( $ID + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");}
|
||||
this->length = (uint32_t)args[2]->ip_plength -
|
||||
(uint8_t)args[4]->tcp_offset;
|
||||
|
||||
/* details = " <length> byte<s>" */
|
||||
this->details = strjoin(
|
||||
strjoin(" ", lltostr(this->length)),
|
||||
strjoin(" byte", this->length == 1 ? "" : "s"));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 4 ))
|
||||
|
||||
############################################################ EVENT TAG
|
||||
|
||||
exec 9<<EOF
|
||||
printf("%s: ", "$PROFILE");
|
||||
EOF
|
||||
EVENT_TAG=$( cat <&9 )
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print details
|
||||
*/
|
||||
printf("%s:%u %s %s:%u%s",
|
||||
this->local, this->lport,
|
||||
this->flow,
|
||||
this->remote, this->rport,
|
||||
this->details);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
108
cddl/usr.sbin/dwatch/libexec/udp
Normal file
108
cddl/usr.sbin/dwatch/libexec/udp
Normal file
@ -0,0 +1,108 @@
|
||||
# -*- tab-width: 4 -*- ;; Emacs
|
||||
# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
|
||||
############################################################ IDENT(1)
|
||||
#
|
||||
# $Title: dwatch(8) module for dtrace_udp(4) $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Display local/remote UDP addresses/ports and bytes sent/received for UDP I/O
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
case "$PROFILE" in
|
||||
udp) : ${PROBE:=udp:::send, udp:::receive} ;;
|
||||
*) : ${PROBE:=udp:::${PROFILE#udp-}}
|
||||
esac
|
||||
|
||||
############################################################ GLOBALS
|
||||
|
||||
#
|
||||
# This profile does not support these dwatch features
|
||||
# NB: They are disabled here so they have no effect when profile is loaded
|
||||
#
|
||||
unset EXECNAME # -k name
|
||||
unset EXECREGEX # -z regex
|
||||
unset GROUP # -g group
|
||||
unset PID # -p pid
|
||||
unset PSARGS # affects -d
|
||||
unset PSTREE # -R
|
||||
unset USER # -u user
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
this string flow;
|
||||
this string local;
|
||||
this string remote;
|
||||
this u_char local6;
|
||||
this u_char recv;
|
||||
this u_char remote6;
|
||||
this uint16_t length;
|
||||
this uint16_t lport;
|
||||
this uint16_t rport;
|
||||
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");
|
||||
}
|
||||
/*
|
||||
* dtrace_udp(4)
|
||||
*/
|
||||
this->recv = probename == "receive" ? 1 : 0;
|
||||
this->flow = this->recv ? "<-" : "->";
|
||||
|
||||
/*
|
||||
* ipinfo_t *
|
||||
*/
|
||||
this->local = this->recv ? args[2]->ip_daddr : args[2]->ip_saddr;
|
||||
this->remote = this->recv ? args[2]->ip_saddr : args[2]->ip_daddr;
|
||||
|
||||
/*
|
||||
* udpinfo_t *
|
||||
*/
|
||||
this->length = (uint16_t)args[4]->udp_length;
|
||||
this->lport = this->recv ? args[4]->udp_dport : args[4]->udp_sport;
|
||||
this->rport = this->recv ? args[4]->udp_sport : args[4]->udp_dport;
|
||||
|
||||
/*
|
||||
* IPv6 support
|
||||
*/
|
||||
this->local6 = strstr(this->local, ":") != NULL ? 1 : 0;
|
||||
this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0;
|
||||
this->local = strjoin(strjoin(this->local6 ? "[" : "",
|
||||
this->local), this->local6 ? "]" : "");
|
||||
this->remote = strjoin(strjoin(this->remote6 ? "[" : "",
|
||||
this->remote), this->remote6 ? "]" : "");
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + 1 ))
|
||||
|
||||
############################################################ EVENT TAG
|
||||
|
||||
exec 9<<EOF
|
||||
printf("%s: ", "$PROFILE");
|
||||
EOF
|
||||
EVENT_TAG=$( cat <&9 )
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print network I/O details
|
||||
*/
|
||||
printf("%s:%u %s %s:%u %d byte%s",
|
||||
this->local, this->lport,
|
||||
this->flow,
|
||||
this->remote, this->rport,
|
||||
this->length,
|
||||
this->length == 1 ? "" : "s");
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
194
cddl/usr.sbin/dwatch/libexec/vop_create
Normal file
194
cddl/usr.sbin/dwatch/libexec/vop_create
Normal file
@ -0,0 +1,194 @@
|
||||
# -*- 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) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print filesystem paths being operated-on by VOP_CREATE(9) [or similar]
|
||||
# NB: All paths are shown even if error prevents operation.
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=vfs:vop:$PROFILE:entry}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
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) : "";
|
||||
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->nameDEPTH = "";
|
||||
EOFDEPTH
|
||||
)
|
||||
}
|
||||
|
||||
$PROBE /this->vp == 0 || this->fi_fs == 0 ||
|
||||
this->fi_fs == "devfs" || this->fi_fs == "" ||
|
||||
this->fi_name == ""/ /* probe ID $(( $ID + 1 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");}
|
||||
this->ncp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))>");}
|
||||
this->dvp = this->ncp->nc_dvp != NULL ?
|
||||
this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->name1 = this->dvp != 0 ? (
|
||||
this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
|
||||
this->fi_fs == "devfs" || this->fi_fs == "" ||
|
||||
this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");}
|
||||
this->dvp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
/*
|
||||
* BEGIN Pathname-depth iterators
|
||||
*/
|
||||
|
||||
$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ buf = buf $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
|
||||
$0 = buf
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
gsub(/IDNUM/, ID++)
|
||||
print
|
||||
}
|
||||
}
|
||||
' <<EOFDEPTH
|
||||
$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
|
||||
{${TRACE:+
|
||||
printf("<IDNUM>");}
|
||||
this->dvp = this->dvp->nc_dvp != NULL ?
|
||||
this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->nameDEPTH = this->dvp != 0 ? (
|
||||
this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
|
||||
this->dvp = this->dvp->nc_dvp != NULL ?
|
||||
this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
|
||||
this->dvp->nc_dvp != NULL ? "..." : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
/*
|
||||
* END Pathname-depth iterators
|
||||
*/
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
|
||||
}
|
||||
/*
|
||||
* Join full path
|
||||
* NB: Up-to but not including the parent directory (joined below)
|
||||
*/
|
||||
this->path = this->fi_mount;
|
||||
this->path = strjoin(this->path, this->fi_mount != 0 ? (
|
||||
this->fi_mount == "/" ? "" : "/"
|
||||
) : "/");
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (N = MAX_DEPTH + 1; N > 0; N--) {
|
||||
gsub(/N/, N)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->path = strjoin(this->path,
|
||||
\ strjoin(this->nameN, this->nameN != "" ? "/" : ""));
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
/* Join the parent directory name */
|
||||
this->path = strjoin(this->path, strjoin(this->name =
|
||||
(this->d_name != 0 ? this->d_name : ""),
|
||||
this->name != "" ? "/" : ""));
|
||||
|
||||
/* Join the entry name */
|
||||
this->path = strjoin(this->path,
|
||||
this->name = (this->fi_name != 0 ? this->fi_name : ""));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + $MAX_DEPTH + 5 ))
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
EVENT_TEST="this->fi_mount != 0"
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print full path
|
||||
*/
|
||||
printf("%s", this->path);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
186
cddl/usr.sbin/dwatch/libexec/vop_readdir
Normal file
186
cddl/usr.sbin/dwatch/libexec/vop_readdir
Normal file
@ -0,0 +1,186 @@
|
||||
# -*- 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) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print directory paths being read by VOP_READDIR(9) [or similar]
|
||||
# NB: All paths are shown even if error prevents their reading.
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=vfs:vop:$PROFILE:entry}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
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) : "";
|
||||
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->nameDEPTH = "";
|
||||
EOFDEPTH
|
||||
)
|
||||
}
|
||||
|
||||
$PROBE /this->vp == 0 || this->fi_fs == 0 ||
|
||||
this->fi_fs == "devfs" || this->fi_fs == ""/ /* probe ID $((
|
||||
$ID + 1
|
||||
)) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");}
|
||||
this->ncp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))>");}
|
||||
this->dvp = this->ncp->nc_dvp != NULL ?
|
||||
this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->name1 = this->dvp != 0 ? (
|
||||
this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
|
||||
this->fi_fs == "devfs" || this->fi_fs == "" ||
|
||||
this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");}
|
||||
this->dvp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
/*
|
||||
* BEGIN Pathname-depth iterators
|
||||
*/
|
||||
|
||||
$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ buf = buf $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
|
||||
$0 = buf
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
gsub(/IDNUM/, ID++)
|
||||
print
|
||||
}
|
||||
}
|
||||
' <<EOFDEPTH
|
||||
$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
|
||||
{${TRACE:+
|
||||
printf("<IDNUM>");}
|
||||
this->dvp = this->dvp->nc_dvp != NULL ?
|
||||
this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->nameDEPTH = this->dvp != 0 ? (
|
||||
this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
|
||||
this->dvp = this->dvp->nc_dvp != NULL ?
|
||||
this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
|
||||
this->dvp->nc_dvp != NULL ? "..." : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
/*
|
||||
* END Pathname-depth iterators
|
||||
*/
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
|
||||
}
|
||||
/*
|
||||
* Join full path
|
||||
* NB: Up-to but not including the parent directory (joined below)
|
||||
*/
|
||||
this->path = this->fi_mount;
|
||||
this->path = strjoin(this->path, this->fi_mount != 0 ? (
|
||||
this->fi_mount == "/" ? "" : "/"
|
||||
) : "/");
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (N = MAX_DEPTH + 1; N > 0; N--) {
|
||||
gsub(/N/, N)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->path = strjoin(this->path,
|
||||
\ strjoin(this->nameN, this->nameN != "" ? "/" : ""));
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
/* Join the parent directory name */
|
||||
this->path = strjoin(this->path, strjoin(this->name =
|
||||
(this->d_name != 0 ? this->d_name : ""),
|
||||
this->name != "" ? "/" : ""));
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + $MAX_DEPTH + 5 ))
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
EVENT_TEST="this->fi_mount != 0"
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print full path
|
||||
*/
|
||||
printf("%s", this->path);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
300
cddl/usr.sbin/dwatch/libexec/vop_rename
Normal file
300
cddl/usr.sbin/dwatch/libexec/vop_rename
Normal file
@ -0,0 +1,300 @@
|
||||
# -*- 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) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print filesystem paths being renamed by VOP_RENAME(9) [or similar]
|
||||
# NB: All paths are shown even if error prevents their rename.
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=vfs:vop:$PROFILE:entry}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
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) : ""
|
||||
) : "";
|
||||
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->fnameDEPTH = this->tnameDEPTH = "";
|
||||
EOFDEPTH
|
||||
)
|
||||
}
|
||||
|
||||
$PROBE /this->fvp == 0 || this->ffi_fs == 0 ||
|
||||
this->ffi_fs == "devfs" || this->ffi_fs == "" ||
|
||||
this->ffi_name == ""/ /* probe ID $(( $ID + 1 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");}
|
||||
this->fncp = 0;
|
||||
}
|
||||
|
||||
$PROBE /this->tvp == 0 || this->tfi_fs == 0 ||
|
||||
this->tfi_fs == "devfs" || this->tfi_fs == "" ||
|
||||
this->tfi_name == ""/ /* probe ID $(( $ID + 2 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))>");}
|
||||
this->tncp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->fncp/ /* probe ID $(( $ID + 3 )) (depth 1) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");}
|
||||
this->fdvp = this->fncp->nc_dvp != NULL ?
|
||||
this->fncp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->fname1 = this->fdvp != 0 ? (
|
||||
this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
$PROBE /this->tncp/ /* probe ID $(( $ID + 4 )) (depth 1) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 4 ))>");}
|
||||
this->tdvp = this->tncp->nc_dvp != NULL ?
|
||||
this->tncp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->tname1 = this->tdvp != 0 ? (
|
||||
this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
$PROBE /this->fname1 == 0 || this->ffi_fs == 0 ||
|
||||
this->ffi_fs == "devfs" || this->ffi_fs == "" ||
|
||||
this->fname1 == "/" || this->fname1 == ""/ /* probe ID $((
|
||||
$ID + 5
|
||||
)) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 5 ))>");}
|
||||
this->fdvp = 0;
|
||||
}
|
||||
|
||||
$PROBE /this->tname1 == 0 || this->tfi_fs == 0 ||
|
||||
this->tfi_fs == "devfs" || this->tfi_fs == "" ||
|
||||
this->tname1 == "/" || this->tname1 == ""/ /* probe ID $((
|
||||
$ID + 6
|
||||
)) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 6 ))>");}
|
||||
this->tdvp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
/*
|
||||
* BEGIN Pathname-depth iterators
|
||||
*/
|
||||
|
||||
$( awk -v ID=$(( $ID + 7 )) -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ buf = buf $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
|
||||
$0 = buf
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
gsub(/IDNUM1/, ID)
|
||||
gsub(/IDNUM2/, ID + 1)
|
||||
print
|
||||
ID = ID + 2
|
||||
}
|
||||
}
|
||||
' <<EOFDEPTH
|
||||
$PROBE /this->fdvp/ /* probe ID IDNUM1 (depth DEPTH) */
|
||||
{${TRACE:+
|
||||
printf("<IDNUM1>");}
|
||||
this->fdvp = this->fdvp->nc_dvp != NULL ?
|
||||
this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->fnameDEPTH = this->fdvp != 0 ? (
|
||||
this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
$PROBE /this->tdvp/ /* probe ID IDNUM2 (depth DEPTH) */
|
||||
{${TRACE:+
|
||||
printf("<IDNUM2>");}
|
||||
this->tdvp = this->tdvp->nc_dvp != NULL ?
|
||||
this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->tnameDEPTH = this->tdvp != 0 ? (
|
||||
this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
$PROBE /this->fdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 5 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH * 2 + 5 ))>");}
|
||||
this->fdvp = this->fdvp->nc_dvp != NULL ?
|
||||
this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->fname$(( $MAX_DEPTH + 1 )) = this->fdvp != 0 ? (
|
||||
this->fdvp->nc_dvp != NULL ? "..." : ""
|
||||
) : "";
|
||||
}
|
||||
$PROBE /this->tdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 6 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH * 2 + 6 ))>");}
|
||||
this->tdvp = this->tdvp->nc_dvp != NULL ?
|
||||
this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->tname$(( $MAX_DEPTH + 1 )) = this->tdvp != 0 ? (
|
||||
this->tdvp->nc_dvp != NULL ? "..." : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
/*
|
||||
* END Pathname-depth iterators
|
||||
*/
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->ffi_mount != 0 && this->tfi_mount != 0/ /* probe ID $((
|
||||
$ID + $MAX_DEPTH * 2 + 7
|
||||
)) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH * 2 + 7 ))>");
|
||||
}
|
||||
/*
|
||||
* Join 'from' full path
|
||||
* NB: Up-to but not including the parent directory (joined below)
|
||||
*/
|
||||
this->fpath = this->ffi_mount;
|
||||
this->fpath = strjoin(this->fpath, this->ffi_mount != 0 ? (
|
||||
this->ffi_mount == "/" ? "" : "/"
|
||||
) : "/");
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (N = MAX_DEPTH + 1; N > 0; N--) {
|
||||
gsub(/N/, N)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->fpath = strjoin(this->fpath,
|
||||
\ strjoin(this->fnameN, this->fnameN != "" ? "/" : ""));
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
/* Join the 'from' parent directory name */
|
||||
this->fpath = strjoin(this->fpath, strjoin(this->fname =
|
||||
(this->fd_name != 0 ? this->fd_name : ""),
|
||||
this->fname != "" ? "/" : ""));
|
||||
|
||||
/* Join the 'from' entry name */
|
||||
this->fpath = strjoin(this->fpath,
|
||||
this->fname = (this->ffi_name != 0 ? this->ffi_name : ""));
|
||||
|
||||
/*
|
||||
* Join 'to' full path
|
||||
* NB: Up-to but not including the parent directory (joined below)
|
||||
*/
|
||||
this->tpath = this->tfi_mount;
|
||||
this->tpath = strjoin(this->tpath, this->tfi_mount != 0 ? (
|
||||
this->tfi_mount == "/" ? "" : "/"
|
||||
) : "/");
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (N = MAX_DEPTH + 1; N > 0; N--) {
|
||||
gsub(/N/, N)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->tpath = strjoin(this->tpath,
|
||||
\ strjoin(this->tnameN, this->tnameN != "" ? "/" : ""));
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
/* Join the 'to' parent directory name */
|
||||
this->tpath = strjoin(this->tpath, strjoin(this->tname =
|
||||
(this->td_name != 0 ? this->td_name : ""),
|
||||
this->tname != "" ? "/" : ""));
|
||||
|
||||
/* Join the 'to' entry name */
|
||||
this->tpath = strjoin(this->tpath,
|
||||
this->tname = (this->tfi_name != 0 ? this->tfi_name : ""));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + $MAX_DEPTH * 2 + 8 ))
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
EVENT_TEST="this->ffi_mount != 0 && this->tfi_mount != 0"
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print 'from' and 'to' full paths
|
||||
*/
|
||||
printf("%s -> %s", this->fpath, this->tpath);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
195
cddl/usr.sbin/dwatch/libexec/vop_symlink
Normal file
195
cddl/usr.sbin/dwatch/libexec/vop_symlink
Normal file
@ -0,0 +1,195 @@
|
||||
# -*- 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) [or similar] entry $
|
||||
# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
|
||||
# $FreeBSD$
|
||||
#
|
||||
############################################################ DESCRIPTION
|
||||
#
|
||||
# Print symlink paths being created by VOP_SYMLINK(9) [or similar]
|
||||
# NB: All paths are shown even if error prevents their creation.
|
||||
#
|
||||
############################################################ PROBE
|
||||
|
||||
: ${PROBE:=vfs:vop:$PROFILE:entry}
|
||||
|
||||
############################################################ ACTIONS
|
||||
|
||||
exec 9<<EOF
|
||||
$PROBE /* probe ID $ID */
|
||||
{${TRACE:+
|
||||
printf("<$ID>");}
|
||||
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) : "";
|
||||
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->nameDEPTH = "";
|
||||
EOFDEPTH
|
||||
)
|
||||
}
|
||||
|
||||
$PROBE /this->vp == 0 || this->fi_fs == 0 ||
|
||||
this->fi_fs == "devfs" || this->fi_fs == "" ||
|
||||
this->fi_name == ""/ /* probe ID $(( $ID + 1 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 1 ))>");}
|
||||
this->ncp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 2 ))>");}
|
||||
this->dvp = this->ncp->nc_dvp != NULL ?
|
||||
this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->name1 = this->dvp != 0 ? (
|
||||
this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
|
||||
this->fi_fs == "devfs" || this->fi_fs == "" ||
|
||||
this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + 3 ))>");}
|
||||
this->dvp = 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
/*
|
||||
* BEGIN Pathname-depth iterators
|
||||
*/
|
||||
|
||||
$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ buf = buf $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
|
||||
$0 = buf
|
||||
gsub(/DEPTH/, DEPTH)
|
||||
gsub(/IDNUM/, ID++)
|
||||
print
|
||||
}
|
||||
}
|
||||
' <<EOFDEPTH
|
||||
$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
|
||||
{${TRACE:+
|
||||
printf("<IDNUM>");}
|
||||
this->dvp = this->dvp->nc_dvp != NULL ?
|
||||
this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->nameDEPTH = this->dvp != 0 ? (
|
||||
this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
|
||||
this->dvp = this->dvp->nc_dvp != NULL ?
|
||||
this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
|
||||
this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
|
||||
this->dvp->nc_dvp != NULL ? "..." : ""
|
||||
) : "";
|
||||
}
|
||||
|
||||
/*
|
||||
* END Pathname-depth iterators
|
||||
*/
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
|
||||
{${TRACE:+
|
||||
printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
|
||||
}
|
||||
/*
|
||||
* Join full path
|
||||
* NB: Up-to but not including the parent directory (joined below)
|
||||
*/
|
||||
this->path = this->fi_mount;
|
||||
this->path = strjoin(this->path, this->fi_mount != 0 ? (
|
||||
this->fi_mount == "/" ? "" : "/"
|
||||
) : "/");
|
||||
$( awk -v MAX_DEPTH=$MAX_DEPTH '
|
||||
{ sub(/^\\\t/, "\t") }
|
||||
{ buf = buf "\t" $0 "\n" }
|
||||
END {
|
||||
sub(/\n$/, "", buf)
|
||||
$0 = buf
|
||||
sub(/^[[:space:]]*/, "")
|
||||
for (N = MAX_DEPTH + 1; N > 0; N--) {
|
||||
gsub(/N/, N)
|
||||
print
|
||||
$0 = buf
|
||||
}
|
||||
}
|
||||
' <<-EOFDEPTH
|
||||
this->path = strjoin(this->path,
|
||||
\ strjoin(this->nameN, this->nameN != "" ? "/" : ""));
|
||||
EOFDEPTH
|
||||
)
|
||||
|
||||
/* Join the parent directory name */
|
||||
this->path = strjoin(this->path, strjoin(this->name =
|
||||
(this->d_name != 0 ? this->d_name : ""),
|
||||
this->name != "" ? "/" : ""));
|
||||
|
||||
/* Join the entry name */
|
||||
this->path = strjoin(this->path,
|
||||
this->name = (this->fi_name != 0 ? this->fi_name : ""));
|
||||
}
|
||||
EOF
|
||||
ACTIONS=$( cat <&9 )
|
||||
ID=$(( $ID + $MAX_DEPTH + 5 ))
|
||||
|
||||
############################################################ EVENT ACTION
|
||||
|
||||
EVENT_TEST="this->fi_mount != 0"
|
||||
|
||||
############################################################ EVENT DETAILS
|
||||
|
||||
exec 9<<EOF
|
||||
/*
|
||||
* Print full path and target
|
||||
*/
|
||||
printf("%s -> %s", this->path, this->target);
|
||||
EOF
|
||||
EVENT_DETAILS=$( cat <&9 )
|
||||
|
||||
################################################################################
|
||||
# END
|
||||
################################################################################
|
@ -122,6 +122,8 @@
|
||||
..
|
||||
bsdinstall
|
||||
..
|
||||
dwatch
|
||||
..
|
||||
hyperv
|
||||
..
|
||||
lpr
|
||||
@ -237,6 +239,8 @@
|
||||
..
|
||||
drivers
|
||||
..
|
||||
dwatch
|
||||
..
|
||||
etc
|
||||
defaults
|
||||
..
|
||||
|
@ -17,10 +17,7 @@ SCRIPTS= blocking \
|
||||
tcpdebug \
|
||||
tcpstate \
|
||||
tcptrack \
|
||||
udptrack \
|
||||
watch_execve \
|
||||
watch_kill \
|
||||
watch_vop_remove
|
||||
udptrack
|
||||
|
||||
SCRIPTSDIR= ${SHAREDIR}/dtrace
|
||||
|
||||
|
@ -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" : "");
|
||||
}
|
@ -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" : "");
|
||||
}
|
@ -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" : "");
|
||||
}
|
Loading…
Reference in New Issue
Block a user