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_RENAME(9) [or similar] entry $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# $FreeBSD$ 8# 9############################################################ DESCRIPTION 10# 11# Print filesystem paths being renamed by VOP_RENAME(9) [or similar] 12# NB: All paths are shown even if error prevents their rename. 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->fvp = args[1] ? args[1]->a_fdvp : NULL; 25 this->fncp = this->fvp != NULL ? 26 this->fvp->v_cache_dst.tqh_first : 0; 27 this->ffi_name = args[1] ? ( 28 args[1]->a_fcnp != NULL ? 29 stringof(args[1]->a_fcnp->cn_nameptr) : "" 30 ) : ""; 31 this->fmount = this->fvp != NULL ? 32 this->fvp->v_mount : NULL; /* ptr to vfs we are in */ 33 this->ffi_fs = this->fmount != NULL ? 34 stringof(this->fmount->mnt_stat.f_fstypename) : ""; 35 this->ffi_mount = this->fmount != NULL ? 36 stringof(this->fmount->mnt_stat.f_mntonname) : ""; 37 this->fd_name = args[0]->v_cache_dd != NULL ? 38 stringof(args[0]->v_cache_dd->nc_name) : ""; 39 40 this->tvp = args[1] ? args[1]->a_tdvp : NULL; 41 this->tncp = this->tvp != NULL ? 42 this->tvp->v_cache_dst.tqh_first : 0; 43 this->tfi_name = args[1] ? ( 44 args[1]->a_tcnp != NULL ? 45 stringof(args[1]->a_tcnp->cn_nameptr) : "" 46 ) : ""; 47 this->tmount = this->tvp != NULL ? 48 this->tvp->v_mount : NULL; /* ptr to vfs we are in */ 49 this->tfi_fs = this->tmount != NULL ? 50 stringof(this->tmount->mnt_stat.f_fstypename) : ""; 51 this->tfi_mount = this->tmount != NULL ? 52 stringof(this->tmount->mnt_stat.f_mntonname) : ""; 53 this->td_name = this->tvp != NULL ? ( 54 this->tvp->v_cache_dd != NULL ? 55 stringof(this->tvp->v_cache_dd->nc_name) : "" 56 ) : ""; 57 58 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 59 { sub(/^\\\t/, "\t") } 60 { buf = buf "\t" $0 "\n" } 61 END { 62 sub(/\n$/, "", buf) 63 $0 = buf 64 sub(/^[[:space:]]*/, "") 65 for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) { 66 gsub(/DEPTH/, DEPTH) 67 print 68 $0 = buf 69 } 70 } 71 ' <<-EOFDEPTH 72 this->fnameDEPTH = this->tnameDEPTH = ""; 73 EOFDEPTH 74 ) 75} 76 77$PROBE /this->fvp == 0 || this->ffi_fs == 0 || 78 this->ffi_fs == "devfs" || this->ffi_fs == "" || 79 this->ffi_name == ""/ /* probe ID $(( $ID + 1 )) */ 80{${TRACE:+ 81 printf("<$(( $ID + 1 ))>");} 82 this->fncp = 0; 83} 84 85$PROBE /this->tvp == 0 || this->tfi_fs == 0 || 86 this->tfi_fs == "devfs" || this->tfi_fs == "" || 87 this->tfi_name == ""/ /* probe ID $(( $ID + 2 )) */ 88{${TRACE:+ 89 printf("<$(( $ID + 2 ))>");} 90 this->tncp = 0; 91} 92 93/*********************************************************/ 94 95$PROBE /this->fncp/ /* probe ID $(( $ID + 3 )) (depth 1) */ 96{${TRACE:+ 97 printf("<$(( $ID + 3 ))>");} 98 this->fdvp = this->fncp->nc_dvp != NULL ? 99 this->fncp->nc_dvp->v_cache_dst.tqh_first : 0; 100 this->fname1 = this->fdvp != 0 ? ( 101 this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : "" 102 ) : ""; 103} 104 105$PROBE /this->tncp/ /* probe ID $(( $ID + 4 )) (depth 1) */ 106{${TRACE:+ 107 printf("<$(( $ID + 4 ))>");} 108 this->tdvp = this->tncp->nc_dvp != NULL ? 109 this->tncp->nc_dvp->v_cache_dst.tqh_first : 0; 110 this->tname1 = this->tdvp != 0 ? ( 111 this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : "" 112 ) : ""; 113} 114 115$PROBE /this->fname1 == 0 || this->ffi_fs == 0 || 116 this->ffi_fs == "devfs" || this->ffi_fs == "" || 117 this->fname1 == "/" || this->fname1 == ""/ /* probe ID $(( 118 $ID + 5 119 )) */ 120{${TRACE:+ 121 printf("<$(( $ID + 5 ))>");} 122 this->fdvp = 0; 123} 124 125$PROBE /this->tname1 == 0 || this->tfi_fs == 0 || 126 this->tfi_fs == "devfs" || this->tfi_fs == "" || 127 this->tname1 == "/" || this->tname1 == ""/ /* probe ID $(( 128 $ID + 6 129 )) */ 130{${TRACE:+ 131 printf("<$(( $ID + 6 ))>");} 132 this->tdvp = 0; 133} 134 135/*********************************************************/ 136 137/* 138 * BEGIN Pathname-depth iterators 139 */ 140 141$( awk -v ID=$(( $ID + 7 )) -v MAX_DEPTH=$MAX_DEPTH ' 142 { buf = buf $0 "\n" } 143 END { 144 sub(/\n$/, "", buf) 145 for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) { 146 $0 = buf 147 gsub(/DEPTH/, DEPTH) 148 gsub(/IDNUM1/, ID) 149 gsub(/IDNUM2/, ID + 1) 150 print 151 ID = ID + 2 152 } 153 } 154' <<EOFDEPTH 155$PROBE /this->fdvp/ /* probe ID IDNUM1 (depth DEPTH) */ 156{${TRACE:+ 157 printf("<IDNUM1>");} 158 this->fdvp = this->fdvp->nc_dvp != NULL ? 159 this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0; 160 this->fnameDEPTH = this->fdvp != 0 ? ( 161 this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : "" 162 ) : ""; 163} 164$PROBE /this->tdvp/ /* probe ID IDNUM2 (depth DEPTH) */ 165{${TRACE:+ 166 printf("<IDNUM2>");} 167 this->tdvp = this->tdvp->nc_dvp != NULL ? 168 this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0; 169 this->tnameDEPTH = this->tdvp != 0 ? ( 170 this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : "" 171 ) : ""; 172} 173 174EOFDEPTH 175) 176 177$PROBE /this->fdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 5 )) */ 178{${TRACE:+ 179 printf("<$(( $ID + $MAX_DEPTH * 2 + 5 ))>");} 180 this->fdvp = this->fdvp->nc_dvp != NULL ? 181 this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0; 182 this->fname$(( $MAX_DEPTH + 1 )) = this->fdvp != 0 ? ( 183 this->fdvp->nc_dvp != NULL ? "..." : "" 184 ) : ""; 185} 186$PROBE /this->tdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 6 )) */ 187{${TRACE:+ 188 printf("<$(( $ID + $MAX_DEPTH * 2 + 6 ))>");} 189 this->tdvp = this->tdvp->nc_dvp != NULL ? 190 this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0; 191 this->tname$(( $MAX_DEPTH + 1 )) = this->tdvp != 0 ? ( 192 this->tdvp->nc_dvp != NULL ? "..." : "" 193 ) : ""; 194} 195 196/* 197 * END Pathname-depth iterators 198 */ 199 200/*********************************************************/ 201 202$PROBE /this->ffi_mount != 0 && this->tfi_mount != 0/ /* probe ID $(( 203 $ID + $MAX_DEPTH * 2 + 7 204)) */ 205{${TRACE:+ 206 printf("<$(( $ID + $MAX_DEPTH * 2 + 7 ))>"); 207} 208 /* 209 * Join 'from' full path 210 * NB: Up-to but not including the parent directory (joined below) 211 */ 212 this->fpath = this->ffi_mount; 213 this->fpath = strjoin(this->fpath, this->ffi_mount != 0 ? ( 214 this->ffi_mount == "/" ? "" : "/" 215 ) : "/"); 216 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 217 { sub(/^\\\t/, "\t") } 218 { buf = buf "\t" $0 "\n" } 219 END { 220 sub(/\n$/, "", buf) 221 $0 = buf 222 sub(/^[[:space:]]*/, "") 223 for (N = MAX_DEPTH + 1; N > 0; N--) { 224 gsub(/N/, N) 225 print 226 $0 = buf 227 } 228 } 229 ' <<-EOFDEPTH 230 this->fpath = strjoin(this->fpath, 231 \ strjoin(this->fnameN, this->fnameN != "" ? "/" : "")); 232 EOFDEPTH 233 ) 234 235 /* Join the 'from' parent directory name */ 236 this->fpath = strjoin(this->fpath, strjoin(this->fname = 237 (this->fd_name != 0 ? this->fd_name : ""), 238 this->fname != "" ? "/" : "")); 239 240 /* Join the 'from' entry name */ 241 this->fpath = strjoin(this->fpath, 242 this->fname = (this->ffi_name != 0 ? this->ffi_name : "")); 243 244 /* 245 * Join 'to' full path 246 * NB: Up-to but not including the parent directory (joined below) 247 */ 248 this->tpath = this->tfi_mount; 249 this->tpath = strjoin(this->tpath, this->tfi_mount != 0 ? ( 250 this->tfi_mount == "/" ? "" : "/" 251 ) : "/"); 252 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 253 { sub(/^\\\t/, "\t") } 254 { buf = buf "\t" $0 "\n" } 255 END { 256 sub(/\n$/, "", buf) 257 $0 = buf 258 sub(/^[[:space:]]*/, "") 259 for (N = MAX_DEPTH + 1; N > 0; N--) { 260 gsub(/N/, N) 261 print 262 $0 = buf 263 } 264 } 265 ' <<-EOFDEPTH 266 this->tpath = strjoin(this->tpath, 267 \ strjoin(this->tnameN, this->tnameN != "" ? "/" : "")); 268 EOFDEPTH 269 ) 270 271 /* Join the 'to' parent directory name */ 272 this->tpath = strjoin(this->tpath, strjoin(this->tname = 273 (this->td_name != 0 ? this->td_name : ""), 274 this->tname != "" ? "/" : "")); 275 276 /* Join the 'to' entry name */ 277 this->tpath = strjoin(this->tpath, 278 this->tname = (this->tfi_name != 0 ? this->tfi_name : "")); 279} 280EOF 281ACTIONS=$( cat <&9 ) 282ID=$(( $ID + $MAX_DEPTH * 2 + 8 )) 283 284############################################################ EVENT ACTION 285 286EVENT_TEST="this->ffi_mount != 0 && this->tfi_mount != 0" 287 288############################################################ EVENT DETAILS 289 290exec 9<<EOF 291 /* 292 * Print 'from' and 'to' full paths 293 */ 294 printf("%s -> %s", this->fpath, this->tpath); 295EOF 296EVENT_DETAILS=$( cat <&9 ) 297 298################################################################################ 299# END 300################################################################################ 301