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 VOP_READDIR(9) [or similar] entry $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# $FreeBSD$ 8# 9############################################################ DESCRIPTION 10# 11# Print directory paths being read by VOP_READDIR(9) [or similar] 12# NB: All paths are shown even if error prevents their reading. 13# 14############################################################ PROBE 15 16: ${PROBE:=vfs:vop:$PROFILE:entry} 17 18############################################################ ACTIONS 19 20exec 9<<EOF 21$PROBE /* probe ID $ID */ 22{${TRACE:+ 23 printf("<$ID>");} 24 this->vp = (struct vnode *)arg0; 25 this->ncp = this->vp != NULL ? 26 this->vp->v_cache_dst.tqh_first : 0; 27 this->mount = this->vp != NULL ? 28 this->vp->v_mount : NULL; /* ptr to vfs we are in */ 29 this->fi_fs = this->mount != NULL ? 30 stringof(this->mount->mnt_stat.f_fstypename) : ""; 31 this->fi_mount = this->mount != NULL ? 32 stringof(this->mount->mnt_stat.f_mntonname) : ""; 33 this->d_name = args[0]->v_cache_dd != NULL ? 34 stringof(args[0]->v_cache_dd->nc_name) : ""; 35 36 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 37 { sub(/^\\\t/, "\t") } 38 { buf = buf "\t" $0 "\n" } 39 END { 40 sub(/\n$/, "", buf) 41 $0 = buf 42 sub(/^[[:space:]]*/, "") 43 for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) { 44 gsub(/DEPTH/, DEPTH) 45 print 46 $0 = buf 47 } 48 } 49 ' <<-EOFDEPTH 50 this->nameDEPTH = ""; 51 EOFDEPTH 52 ) 53} 54 55$PROBE /this->vp == 0 || this->fi_fs == 0 || 56 this->fi_fs == "devfs" || this->fi_fs == ""/ /* probe ID $(( 57 $ID + 1 58 )) */ 59{${TRACE:+ 60 printf("<$(( $ID + 1 ))>");} 61 this->ncp = 0; 62} 63 64/*********************************************************/ 65 66$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */ 67{${TRACE:+ 68 printf("<$(( $ID + 2 ))>");} 69 this->dvp = this->ncp->nc_dvp != NULL ? 70 this->ncp->nc_dvp->v_cache_dst.tqh_first : 0; 71 this->name1 = this->dvp != 0 ? ( 72 this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : "" 73 ) : ""; 74} 75 76$PROBE /this->name1 == 0 || this->fi_fs == 0 || 77 this->fi_fs == "devfs" || this->fi_fs == "" || 78 this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */ 79{${TRACE:+ 80 printf("<$(( $ID + 3 ))>");} 81 this->dvp = 0; 82} 83 84/*********************************************************/ 85 86/* 87 * BEGIN Pathname-depth iterators 88 */ 89 90$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH ' 91 { buf = buf $0 "\n" } 92 END { 93 sub(/\n$/, "", buf) 94 for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) { 95 $0 = buf 96 gsub(/DEPTH/, DEPTH) 97 gsub(/IDNUM/, ID++) 98 print 99 } 100 } 101' <<EOFDEPTH 102$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */ 103{${TRACE:+ 104 printf("<IDNUM>");} 105 this->dvp = this->dvp->nc_dvp != NULL ? 106 this->dvp->nc_dvp->v_cache_dst.tqh_first : 0; 107 this->nameDEPTH = this->dvp != 0 ? ( 108 this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : "" 109 ) : ""; 110} 111 112EOFDEPTH 113) 114 115$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */ 116{${TRACE:+ 117 printf("<$(( $ID + $MAX_DEPTH + 3 ))>");} 118 this->dvp = this->dvp->nc_dvp != NULL ? 119 this->dvp->nc_dvp->v_cache_dst.tqh_first : 0; 120 this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? ( 121 this->dvp->nc_dvp != NULL ? "..." : "" 122 ) : ""; 123} 124 125/* 126 * END Pathname-depth iterators 127 */ 128 129/*********************************************************/ 130 131$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */ 132{${TRACE:+ 133 printf("<$(( $ID + $MAX_DEPTH + 4 ))>"); 134} 135 /* 136 * Join full path 137 * NB: Up-to but not including the parent directory (joined below) 138 */ 139 this->path = this->fi_mount; 140 this->path = strjoin(this->path, this->fi_mount != 0 ? ( 141 this->fi_mount == "/" ? "" : "/" 142 ) : "/"); 143 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 144 { sub(/^\\\t/, "\t") } 145 { buf = buf "\t" $0 "\n" } 146 END { 147 sub(/\n$/, "", buf) 148 $0 = buf 149 sub(/^[[:space:]]*/, "") 150 for (N = MAX_DEPTH + 1; N > 0; N--) { 151 gsub(/N/, N) 152 print 153 $0 = buf 154 } 155 } 156 ' <<-EOFDEPTH 157 this->path = strjoin(this->path, 158 \ strjoin(this->nameN, this->nameN != "" ? "/" : "")); 159 EOFDEPTH 160 ) 161 162 /* Join the parent directory name */ 163 this->path = strjoin(this->path, strjoin(this->name = 164 (this->d_name != 0 ? this->d_name : ""), 165 this->name != "" ? "/" : "")); 166} 167EOF 168ACTIONS=$( cat <&9 ) 169ID=$(( $ID + $MAX_DEPTH + 5 )) 170 171############################################################ EVENT ACTION 172 173EVENT_TEST="this->fi_mount != 0" 174 175############################################################ EVENT DETAILS 176 177if [ ! "$CUSTOM_DETAILS" ]; then 178exec 9<<EOF 179 /* 180 * Print full path 181 */ 182 printf("%s", this->path); 183EOF 184EVENT_DETAILS=$( cat <&9 ) 185fi 186 187################################################################################ 188# END 189################################################################################ 190