xref: /freebsd/cddl/usr.sbin/dwatch/libexec/namei (revision 434283fda99e89af20c3fe95fde427624ae96d04)
1# -*- tab-width: 4 -*- ;; Emacs
2# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
3############################################################ IDENT(1)
4#
5# $Title: dwatch(8) module for namei(9) pathname resolution $
6# $Copyright: 2026 Devin Teske. All rights reserved. $
7#
8############################################################ DESCRIPTION
9#
10# Print pathnames given to namei(9) for resolution, exactly as the process
11# requested them, together with the lookup result. Unlike the vop_lookup
12# profile, which reconstructs paths from the name cache one component at a
13# time, this rides the vfs:namei:lookup probes and so sees the whole path
14# in one piece. Use namei-failure to show only failed lookups or
15# namei-enoent to hunt file-not-found storms (the single most common
16# use of truss(1), without stopping the victim).
17#
18############################################################ PROBE
19
20case "$PROFILE" in
21namei|namei-enoent|namei-failure)
22	: ${PROBE:=vfs:namei:lookup:return} ;;
23namei-entry)
24	: ${PROBE:=vfs:namei:lookup:entry} ;;
25*)
26	: ${PROBE:=vfs:namei:lookup:${PROFILE#namei-}}
27esac
28
29############################################################ EVENT ACTION
30
31[ "$CUSTOM_TEST" ] || case "$PROFILE" in
32namei-enoent)	EVENT_TEST="this->namei_error == ENOENT" ;;
33namei-failure)	EVENT_TEST="this->namei_error != 0" ;;
34esac
35
36############################################################ ACTIONS
37
38exec 9<<EOF
39self string	namei_path;
40this int	namei_error;
41this string	namei_pathstr;
42
43vfs:namei:lookup:entry /* probe ID $ID */
44{${TRACE:+
45	printf("<$ID>");
46}
47	/*
48	 * char * (kernel copy of the path being resolved)
49	 */
50	this->namei_pathstr = self->namei_path = stringof(arg1);
51	this->namei_error = 0;
52}
53
54vfs:namei:lookup:return /* probe ID $(( $ID + 1 )) */
55{${TRACE:+
56	printf("<$(( $ID + 1 ))>");
57}
58	/* NB: path was recorded at entry by the clause above */
59	this->namei_pathstr = self->namei_path;
60	this->namei_error = (int)arg0;
61	self->namei_path = 0;
62}
63EOF
64ACTIONS=$( cat <&9 )
65ID=$(( $ID + 2 ))
66
67############################################################ EVENT DETAILS
68
69if [ ! "$CUSTOM_DETAILS" ]; then
70exec 9<<EOF
71	/*
72	 * Print pathname resolution details
73	 */
74	printf("%s%s", this->namei_pathstr,
75		this->namei_error == 0 ? "" : strjoin(": ",
76		strjoin(strerror[this->namei_error],
77		strjoin(" (", strjoin(lltostr(this->namei_error), ")")))));
78EOF
79EVENT_DETAILS=$( cat <&9 )
80fi
81
82################################################################################
83# END
84################################################################################
85