opdump.c revision 1.32
1/* $NetBSD: opdump.c,v 1.32 2010/05/21 08:46:14 pooka Exp $ */ 2 3/* 4 * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. 5 * 6 * Development of this software was supported by the 7 * Google Summer of Code program and the Ulla Tuominen Foundation. 8 * The Google SoC project was mentored by Bill Studenmund. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/* Pretty-printing helper routines for VFS/VOP request contents */ 33 34/* yes, this is pretty much a mess */ 35 36#include <sys/cdefs.h> 37#if !defined(lint) 38__RCSID("$NetBSD: opdump.c,v 1.32 2010/05/21 08:46:14 pooka Exp $"); 39#endif /* !lint */ 40 41#include <sys/types.h> 42#include <sys/time.h> 43 44#include <puffs.h> 45#include <puffsdump.h> 46#include <stdio.h> 47 48#include "puffs_priv.h" 49 50#define DINT " " 51 52/* XXX! */ 53const char *vfsop_revmap[] = { 54 "PUFFS_VFS_MOUNT", 55 "PUFFS_VFS_START", 56 "PUFFS_VFS_UNMOUNT", 57 "PUFFS_VFS_ROOT", 58 "PUFFS_VFS_STATVFS", 59 "PUFFS_VFS_SYNC", 60 "PUFFS_VFS_VGET", 61 "PUFFS_VFS_FHTOVP", 62 "PUFFS_VFS_VPTOFH", 63 "PUFFS_VFS_INIT", 64 "PUFFS_VFS_DONE", 65 "PUFFS_VFS_SNAPSHOT", 66 "PUFFS_VFS_EXTATTRCTL", 67 "PUFFS_VFS_SUSPEND" 68}; 69/* XXX! */ 70const char *vnop_revmap[] = { 71 "PUFFS_VN_LOOKUP", 72 "PUFFS_VN_CREATE", 73 "PUFFS_VN_MKNOD", 74 "PUFFS_VN_OPEN", 75 "PUFFS_VN_CLOSE", 76 "PUFFS_VN_ACCESS", 77 "PUFFS_VN_GETATTR", 78 "PUFFS_VN_SETATTR", 79 "PUFFS_VN_READ", 80 "PUFFS_VN_WRITE", 81 "PUFFS_VN_IOCTL", 82 "PUFFS_VN_FCNTL", 83 "PUFFS_VN_POLL", 84 "PUFFS_VN_KQFILTER", 85 "PUFFS_VN_REVOKE", 86 "PUFFS_VN_MMAP", 87 "PUFFS_VN_FSYNC", 88 "PUFFS_VN_SEEK", 89 "PUFFS_VN_REMOVE", 90 "PUFFS_VN_LINK", 91 "PUFFS_VN_RENAME", 92 "PUFFS_VN_MKDIR", 93 "PUFFS_VN_RMDIR", 94 "PUFFS_VN_SYMLINK", 95 "PUFFS_VN_READDIR", 96 "PUFFS_VN_READLINK", 97 "PUFFS_VN_ABORTOP", 98 "PUFFS_VN_INACTIVE", 99 "PUFFS_VN_RECLAIM", 100 "PUFFS_VN_LOCK", 101 "PUFFS_VN_UNLOCK", 102 "PUFFS_VN_BMAP", 103 "PUFFS_VN_STRATEGY", 104 "PUFFS_VN_PRINT", 105 "PUFFS_VN_ISLOCKED", 106 "PUFFS_VN_PATHCONF", 107 "PUFFS_VN_ADVLOCK", 108 "PUFFS_VN_LEASE", 109 "PUFFS_VN_WHITEOUT", 110 "PUFFS_VN_GETPAGES", 111 "PUFFS_VN_PUTPAGES", 112 "PUFFS_VN_GETEXTATTR", 113 "PUFFS_VN_LISTEXTATTR", 114 "PUFFS_VN_OPENEXTATTR", 115 "PUFFS_VN_DELETEEXTATTR", 116 "PUFFS_VN_SETEXTATTR", 117}; 118/* XXX! */ 119const char *cacheop_revmap[] = { 120 "PUFFS_CACHE_WRITE" 121}; 122/* XXX! */ 123const char *errnot_revmap[] = { 124 "PUFFS_ERR_MAKENODE", 125 "PUFFS_ERR_LOOKUP", 126 "PUFFS_ERR_READDIR", 127 "PUFFS_ERR_READLINK", 128 "PUFFS_ERR_READ", 129 "PUFFS_ERR_WRITE", 130 "PUFFS_ERR_VPTOFH" 131}; 132/* XXX! */ 133const char *flush_revmap[] = { 134 "PUFFS_INVAL_NAMECACHE_NODE", 135 "PUFFS_INVAL_NAMECACHE_DIR", 136 "PUFFS_INVAL_NAMECACHE_ALL", 137 "PUFFS_INVAL_PAGECACHE_NODE_RANGE", 138 "PUFFS_FLUSH_PAGECACHE_NODE_RANGE", 139}; 140 141void 142puffsdump_req(struct puffs_req *preq) 143{ 144 char buf[128]; 145 static struct timeval tv_prev; 146 struct timeval tv_now, tv; 147 const char **map; 148 const char *optype; 149 size_t maxhandle; 150 int opclass, isvn = 0; 151 152 printf("reqid: %" PRIu64 ", ", preq->preq_id); 153 opclass = PUFFSOP_OPCLASS(preq->preq_opclass); 154 switch (opclass) { 155 case PUFFSOP_VFS: 156 map = vfsop_revmap; 157 maxhandle = __arraycount(vfsop_revmap); 158 break; 159 case PUFFSOP_VN: 160 map = vnop_revmap; 161 maxhandle = __arraycount(vnop_revmap); 162 isvn = 1; 163 break; 164 case PUFFSOP_CACHE: 165 map = cacheop_revmap; 166 maxhandle = __arraycount(cacheop_revmap); 167 break; 168 case PUFFSOP_ERROR: 169 map = errnot_revmap; 170 maxhandle = __arraycount(errnot_revmap); 171 break; 172 case PUFFSOP_FLUSH: 173 map = flush_revmap; 174 maxhandle = __arraycount(flush_revmap); 175 break; 176 default: 177 printf("unhandled opclass %d\n", opclass); 178 return; 179 } 180 181 if (preq->preq_optype < maxhandle) { 182 optype = map[preq->preq_optype]; 183 } else { 184 snprintf(buf, sizeof(buf), "UNKNOWN (%d)", preq->preq_optype); 185 optype = buf; 186 } 187 188 printf("opclass %d%s, optype: %s, " 189 "cookie: %p,\n" DINT "aux: %p, auxlen: %zu, pid: %d, lwpid: %d\n", 190 opclass, PUFFSOP_WANTREPLY(preq->preq_opclass) ? "" : " (FAF)", 191 optype, preq->preq_cookie, 192 preq->preq_buf, preq->preq_buflen, 193 preq->preq_pid, preq->preq_lid); 194 195 if (isvn) { 196 switch (preq->preq_optype) { 197 case PUFFS_VN_LOOKUP: 198 puffsdump_lookup(preq); 199 break; 200 case PUFFS_VN_READ: 201 case PUFFS_VN_WRITE: 202 puffsdump_readwrite(preq); 203 break; 204 case PUFFS_VN_OPEN: 205 puffsdump_open(preq); 206 break; 207 case PUFFS_VN_REMOVE: 208 case PUFFS_VN_RMDIR: 209 case PUFFS_VN_LINK: 210 puffsdump_targ(preq); 211 break; 212 case PUFFS_VN_READDIR: 213 puffsdump_readdir(preq); 214 break; 215 case PUFFS_VN_CREATE: 216 case PUFFS_VN_MKDIR: 217 case PUFFS_VN_MKNOD: 218 case PUFFS_VN_SYMLINK: 219 puffsdump_create(preq); 220 break; 221 case PUFFS_VN_SETATTR: 222 puffsdump_attr(preq); 223 break; 224 default: 225 break; 226 } 227 } 228 229 PU_LOCK(); 230 gettimeofday(&tv_now, NULL); 231 timersub(&tv_now, &tv_prev, &tv); 232 printf(DINT "since previous call: %lld.%06ld\n", 233 (long long)tv.tv_sec, (long)tv.tv_usec); 234 gettimeofday(&tv_prev, NULL); 235 PU_UNLOCK(); 236} 237 238void 239puffsdump_rv(struct puffs_req *preq) 240{ 241 242 if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { 243 switch (preq->preq_optype) { 244 case PUFFS_VN_LOOKUP: 245 puffsdump_lookup_rv(preq); 246 break; 247 case PUFFS_VN_CREATE: 248 case PUFFS_VN_MKDIR: 249 case PUFFS_VN_MKNOD: 250 case PUFFS_VN_SYMLINK: 251 puffsdump_create_rv(preq); 252 break; 253 case PUFFS_VN_READ: 254 case PUFFS_VN_WRITE: 255 puffsdump_readwrite_rv(preq); 256 break; 257 case PUFFS_VN_READDIR: 258 puffsdump_readdir_rv(preq); 259 break; 260 case PUFFS_VN_GETATTR: 261 puffsdump_attr(preq); 262 break; 263 default: 264 break; 265 } 266 } 267 268 printf("RV reqid: %" PRIu64 ", result: %d %s\n", 269 preq->preq_id, preq->preq_rv, 270 preq->preq_rv ? strerror(preq->preq_rv) : ""); 271} 272 273/* 274 * Slightly tedious print-routine so that we get a nice NOVAL instead 275 * of some tedious output representations for -1, especially (uint64_t)-1 276 * 277 * We use typecasting to make this work beyond time_t/dev_t size changes. 278 */ 279static void 280dumpattr(struct vattr *vap) 281{ 282 const char * const vtypes[] = { VNODE_TYPES }; 283 char buf[128]; 284 285/* XXX: better readability. and this is debug, so no cycle-sweat */ 286#define DEFAULTBUF() snprintf(buf, sizeof(buf), "NOVAL") 287 288 printf(DINT "vattr:\n"); 289 printf(DINT DINT "type: %s, ", vtypes[vap->va_type]); 290 291 DEFAULTBUF(); 292 if (vap->va_mode != (mode_t)PUFFS_VNOVAL) 293 snprintf(buf, sizeof(buf), "0%o", vap->va_mode); 294 printf("mode: %s, ", buf); 295 296 DEFAULTBUF(); 297 if (vap->va_nlink != (nlink_t)PUFFS_VNOVAL) 298 snprintf(buf, sizeof(buf), "%d", vap->va_nlink); 299 printf("nlink: %s, ", buf); 300 301 DEFAULTBUF(); 302 if (vap->va_uid != (uid_t)PUFFS_VNOVAL) 303 snprintf(buf, sizeof(buf), "%d", vap->va_uid); 304 printf("uid: %s, ", buf); 305 306 DEFAULTBUF(); 307 if (vap->va_gid != (gid_t)PUFFS_VNOVAL) 308 snprintf(buf, sizeof(buf), "%d", vap->va_gid); 309 printf("gid: %s\n", buf); 310 311 DEFAULTBUF(); 312 if ((unsigned long long)vap->va_fsid!=(unsigned long long)PUFFS_VNOVAL) 313 snprintf(buf, sizeof(buf), "0x%llx", 314 (unsigned long long)vap->va_fsid); 315 printf(DINT DINT "fsid: %s, ", buf); 316 317 DEFAULTBUF(); 318 if (vap->va_fileid != (ino_t)PUFFS_VNOVAL) 319 snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_fileid); 320 printf("ino: %s, ", buf); 321 322 DEFAULTBUF(); 323 if (vap->va_size != (u_quad_t)PUFFS_VNOVAL) 324 snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_size); 325 printf("size: %s, ", buf); 326 327 DEFAULTBUF(); 328 if (vap->va_blocksize != (long)PUFFS_VNOVAL) 329 snprintf(buf, sizeof(buf), "%ld", vap->va_blocksize); 330 printf("bsize: %s\n", buf); 331 332 DEFAULTBUF(); 333 if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL) 334 snprintf(buf, sizeof(buf), "%lld", 335 (long long)vap->va_atime.tv_sec); 336 printf(DINT DINT "a.s: %s, ", buf); 337 338 DEFAULTBUF(); 339 if (vap->va_atime.tv_nsec != (long)PUFFS_VNOVAL) 340 snprintf(buf, sizeof(buf), "%ld", vap->va_atime.tv_nsec); 341 printf("a.ns: %s, ", buf); 342 343 DEFAULTBUF(); 344 if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL) 345 snprintf(buf, sizeof(buf), "%lld", 346 (long long)vap->va_mtime.tv_sec); 347 printf("m.s: %s, ", buf); 348 349 DEFAULTBUF(); 350 if (vap->va_mtime.tv_nsec != (long)PUFFS_VNOVAL) 351 snprintf(buf, sizeof(buf), "%ld", vap->va_mtime.tv_nsec); 352 printf("m.ns: %s\n", buf); 353 354 DEFAULTBUF(); 355 if (vap->va_ctime.tv_sec != (time_t)PUFFS_VNOVAL) 356 snprintf(buf, sizeof(buf), "%lld", 357 (long long)vap->va_ctime.tv_sec); 358 printf(DINT DINT "c.s: %s, ", buf); 359 360 DEFAULTBUF(); 361 if (vap->va_ctime.tv_nsec != (long)PUFFS_VNOVAL) 362 snprintf(buf, sizeof(buf), "%ld", vap->va_ctime.tv_nsec); 363 printf("c.ns: %s, ", buf); 364 365 DEFAULTBUF(); 366 if (vap->va_birthtime.tv_sec != (time_t)PUFFS_VNOVAL) 367 snprintf(buf, sizeof(buf), "%lld", 368 (long long)vap->va_birthtime.tv_sec); 369 printf("b.s: %s, ", buf); 370 371 DEFAULTBUF(); 372 if (vap->va_birthtime.tv_nsec != (long)PUFFS_VNOVAL) 373 snprintf(buf, sizeof(buf), "%ld", vap->va_birthtime.tv_nsec); 374 printf("b.ns: %s\n", buf); 375 376 DEFAULTBUF(); 377 if (vap->va_gen != (u_long)PUFFS_VNOVAL) 378 snprintf(buf, sizeof(buf), "%lu", vap->va_gen); 379 printf(DINT DINT "gen: %s, ", buf); 380 381 DEFAULTBUF(); 382 if (vap->va_flags != (u_long)PUFFS_VNOVAL) 383 snprintf(buf, sizeof(buf), "0x%lx", vap->va_flags); 384 printf("flags: %s, ", buf); 385 386 DEFAULTBUF(); 387 if (vap->va_rdev != (dev_t)PUFFS_VNOVAL) 388 snprintf(buf, sizeof(buf), "0x%llx", 389 (unsigned long long)vap->va_rdev); 390 printf("rdev: %s\n", buf); 391 392 DEFAULTBUF(); 393 if (vap->va_bytes != (u_quad_t)PUFFS_VNOVAL) 394 snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_bytes); 395 printf(DINT DINT "bytes: %s, ", buf); 396 397 snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_filerev); 398 printf("filerev: %s, ", buf); 399 400 snprintf(buf, sizeof(buf), "0x%x", vap->va_vaflags); 401 printf("vaflags: %s\n", buf); 402} 403 404void 405puffsdump_cookie(puffs_cookie_t c, const char *cookiename) 406{ 407 408 printf("%scookie: at %p\n", cookiename, c); 409} 410 411static const char *cn_opnames[] = { 412 "LOOKUP", 413 "CREATE", 414 "DELETE", 415 "RENAME" 416}; 417 418void 419puffsdump_cn(struct puffs_kcn *pkcn) 420{ 421 422 printf(DINT "puffs_cn: \"%s\", len %zu op %s (flags 0x%x)\n", 423 pkcn->pkcn_name, pkcn->pkcn_namelen, 424 cn_opnames[pkcn->pkcn_nameiop & NAMEI_OPMASK], 425 pkcn->pkcn_flags); 426} 427 428void 429puffsdump_lookup(struct puffs_req *preq) 430{ 431 struct puffs_vnmsg_lookup *lookup_msg = (void *)preq; 432 433 puffsdump_cn(&lookup_msg->pvnr_cn); 434} 435 436void 437puffsdump_lookup_rv(struct puffs_req *preq) 438{ 439 struct puffs_vnmsg_lookup *lookup_msg = (void *)preq; 440 441 printf(DINT "new %p, type 0x%x, size 0x%"PRIu64", dev 0x%llx\n", 442 lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype, 443 lookup_msg->pvnr_size, (unsigned long long)lookup_msg->pvnr_rdev); 444} 445 446void 447puffsdump_create(struct puffs_req *preq) 448{ 449 /* XXX: wrong type, but we know it fits the slot */ 450 struct puffs_vnmsg_create *create_msg = (void *)preq; 451 452 dumpattr(&create_msg->pvnr_va); 453} 454 455void 456puffsdump_create_rv(struct puffs_req *preq) 457{ 458 /* XXX: wrong type, but we know it fits the slot */ 459 struct puffs_vnmsg_create *create_msg = (void *)preq; 460 461 printf(DINT "new %p\n", create_msg->pvnr_newnode); 462} 463 464void 465puffsdump_readwrite(struct puffs_req *preq) 466{ 467 struct puffs_vnmsg_rw *rw_msg = (void *)preq; 468 469 printf(DINT "offset: %" PRId64 ", resid %zu, ioflag 0x%x\n", 470 rw_msg->pvnr_offset, rw_msg->pvnr_resid, rw_msg->pvnr_ioflag); 471} 472 473void 474puffsdump_readwrite_rv(struct puffs_req *preq) 475{ 476 struct puffs_vnmsg_rw *rw_msg = (void *)preq; 477 478 printf(DINT "resid after op: %zu\n", rw_msg->pvnr_resid); 479} 480 481void 482puffsdump_readdir_rv(struct puffs_req *preq) 483{ 484 struct puffs_vnmsg_readdir *readdir_msg = (void *)preq; 485 486 printf(DINT "resid after op: %zu, eofflag %d\n", 487 readdir_msg->pvnr_resid, readdir_msg->pvnr_eofflag); 488} 489 490void 491puffsdump_open(struct puffs_req *preq) 492{ 493 struct puffs_vnmsg_open *open_msg = (void *)preq; 494 495 printf(DINT "mode: 0x%x\n", open_msg->pvnr_mode); 496} 497 498void 499puffsdump_targ(struct puffs_req *preq) 500{ 501 struct puffs_vnmsg_remove *remove_msg = (void *)preq; /* XXX! */ 502 503 printf(DINT "target cookie: %p\n", remove_msg->pvnr_cookie_targ); 504} 505 506void 507puffsdump_readdir(struct puffs_req *preq) 508{ 509 struct puffs_vnmsg_readdir *readdir_msg = (void *)preq; 510 511 printf(DINT "read offset: %" PRId64 "\n", readdir_msg->pvnr_offset); 512} 513 514void 515puffsdump_attr(struct puffs_req *preq) 516{ 517 struct puffs_vnmsg_setgetattr *attr_msg = (void *)preq; 518 519 dumpattr(&attr_msg->pvnr_va); 520} 521