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