Home | History | Annotate | Line # | Download | only in libpuffs
opdump.c revision 1.33
      1 /*	$NetBSD: opdump.c,v 1.33 2010/05/21 10:43:07 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.33 2010/05/21 10:43:07 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! */
     53 const char *vfsop_revmap[] = {
     54 	"PUFFS_VFS_MOUNT",
     55 	"PUFFS_VFS_START",
     56 	"PUFFS_VFS_UNMOUNT",
     57 	"PUFFS_VFS_ROOT",
     58 	"PUFFS_VFS_QUOTACTL",
     59 	"PUFFS_VFS_STATVFS",
     60 	"PUFFS_VFS_SYNC",
     61 	"PUFFS_VFS_VGET",
     62 	"PUFFS_VFS_FHTOVP",
     63 	"PUFFS_VFS_VPTOFH",
     64 	"PUFFS_VFS_INIT",
     65 	"PUFFS_VFS_DONE",
     66 	"PUFFS_VFS_SNAPSHOT",
     67 	"PUFFS_VFS_EXTATTRCTL",
     68 	"PUFFS_VFS_SUSPEND"
     69 };
     70 /* XXX! */
     71 const char *vnop_revmap[] = {
     72 	"PUFFS_VN_LOOKUP",
     73 	"PUFFS_VN_CREATE",
     74 	"PUFFS_VN_MKNOD",
     75 	"PUFFS_VN_OPEN",
     76 	"PUFFS_VN_CLOSE",
     77 	"PUFFS_VN_ACCESS",
     78 	"PUFFS_VN_GETATTR",
     79 	"PUFFS_VN_SETATTR",
     80 	"PUFFS_VN_READ",
     81 	"PUFFS_VN_WRITE",
     82 	"PUFFS_VN_IOCTL",
     83 	"PUFFS_VN_FCNTL",
     84 	"PUFFS_VN_POLL",
     85 	"PUFFS_VN_KQFILTER",
     86 	"PUFFS_VN_REVOKE",
     87 	"PUFFS_VN_MMAP",
     88 	"PUFFS_VN_FSYNC",
     89 	"PUFFS_VN_SEEK",
     90 	"PUFFS_VN_REMOVE",
     91 	"PUFFS_VN_LINK",
     92 	"PUFFS_VN_RENAME",
     93 	"PUFFS_VN_MKDIR",
     94 	"PUFFS_VN_RMDIR",
     95 	"PUFFS_VN_SYMLINK",
     96 	"PUFFS_VN_READDIR",
     97 	"PUFFS_VN_READLINK",
     98 	"PUFFS_VN_ABORTOP",
     99 	"PUFFS_VN_INACTIVE",
    100 	"PUFFS_VN_RECLAIM",
    101 	"PUFFS_VN_LOCK",
    102 	"PUFFS_VN_UNLOCK",
    103 	"PUFFS_VN_BMAP",
    104 	"PUFFS_VN_STRATEGY",
    105 	"PUFFS_VN_PRINT",
    106 	"PUFFS_VN_ISLOCKED",
    107 	"PUFFS_VN_PATHCONF",
    108 	"PUFFS_VN_ADVLOCK",
    109 	"PUFFS_VN_LEASE",
    110 	"PUFFS_VN_WHITEOUT",
    111 	"PUFFS_VN_GETPAGES",
    112 	"PUFFS_VN_PUTPAGES",
    113 	"PUFFS_VN_GETEXTATTR",
    114 	"PUFFS_VN_LISTEXTATTR",
    115 	"PUFFS_VN_OPENEXTATTR",
    116 	"PUFFS_VN_DELETEEXTATTR",
    117 	"PUFFS_VN_SETEXTATTR",
    118 	"PUFFS_VN_CLOSEEXTATTR",
    119 };
    120 /* XXX! */
    121 const char *cacheop_revmap[] = {
    122 	"PUFFS_CACHE_WRITE"
    123 };
    124 /* XXX! */
    125 const char *errnot_revmap[] = {
    126 	"PUFFS_ERR_ERROR",
    127 	"PUFFS_ERR_MAKENODE",
    128 	"PUFFS_ERR_LOOKUP",
    129 	"PUFFS_ERR_READDIR",
    130 	"PUFFS_ERR_READLINK",
    131 	"PUFFS_ERR_READ",
    132 	"PUFFS_ERR_WRITE",
    133 	"PUFFS_ERR_VPTOFH",
    134 	"PUFFS_ERR_GETEXTATTR",
    135 	"PUFFS_ERR_LISTEXTATTR",
    136 };
    137 /* XXX! */
    138 const char *flush_revmap[] = {
    139 	"PUFFS_INVAL_NAMECACHE_NODE",
    140 	"PUFFS_INVAL_NAMECACHE_DIR",
    141 	"PUFFS_INVAL_NAMECACHE_ALL",
    142 	"PUFFS_INVAL_PAGECACHE_NODE_RANGE",
    143 	"PUFFS_FLUSH_PAGECACHE_NODE_RANGE",
    144 };
    145 
    146 void
    147 puffsdump_req(struct puffs_req *preq)
    148 {
    149 	char buf[128];
    150 	static struct timeval tv_prev;
    151 	struct timeval tv_now, tv;
    152 	const char **map;
    153 	const char *optype;
    154 	size_t maxhandle;
    155 	int opclass, isvn = 0;
    156 
    157 	printf("reqid: %" PRIu64 ", ", preq->preq_id);
    158 	opclass = PUFFSOP_OPCLASS(preq->preq_opclass);
    159 	switch (opclass) {
    160 	case PUFFSOP_VFS:
    161 		map = vfsop_revmap;
    162 		maxhandle = __arraycount(vfsop_revmap);
    163 		break;
    164 	case PUFFSOP_VN:
    165 		map = vnop_revmap;
    166 		maxhandle = __arraycount(vnop_revmap);
    167 		isvn = 1;
    168 		break;
    169 	case PUFFSOP_CACHE:
    170 		map = cacheop_revmap;
    171 		maxhandle = __arraycount(cacheop_revmap);
    172 		break;
    173 	case PUFFSOP_ERROR:
    174 		map = errnot_revmap;
    175 		maxhandle = __arraycount(errnot_revmap);
    176 		break;
    177 	case PUFFSOP_FLUSH:
    178 		map = flush_revmap;
    179 		maxhandle = __arraycount(flush_revmap);
    180 		break;
    181 	default:
    182 		printf("unhandled opclass %d\n", opclass);
    183 		return;
    184 	}
    185 
    186 	if (preq->preq_optype < maxhandle) {
    187 		optype = map[preq->preq_optype];
    188 	} else {
    189 		snprintf(buf, sizeof(buf), "UNKNOWN (%d)", preq->preq_optype);
    190 		optype = buf;
    191 	}
    192 
    193 	printf("opclass %d%s, optype: %s, "
    194 	    "cookie: %p,\n" DINT "aux: %p, auxlen: %zu, pid: %d, lwpid: %d\n",
    195 	    opclass, PUFFSOP_WANTREPLY(preq->preq_opclass) ? "" : " (FAF)",
    196 	    optype, preq->preq_cookie,
    197 	    preq->preq_buf, preq->preq_buflen,
    198 	    preq->preq_pid, preq->preq_lid);
    199 
    200 	if (isvn) {
    201 		switch (preq->preq_optype) {
    202 		case PUFFS_VN_LOOKUP:
    203 			puffsdump_lookup(preq);
    204 			break;
    205 		case PUFFS_VN_READ:
    206 		case PUFFS_VN_WRITE:
    207 			puffsdump_readwrite(preq);
    208 			break;
    209 		case PUFFS_VN_OPEN:
    210 			puffsdump_open(preq);
    211 			break;
    212 		case PUFFS_VN_REMOVE:
    213 		case PUFFS_VN_RMDIR:
    214 		case PUFFS_VN_LINK:
    215 			puffsdump_targ(preq);
    216 			break;
    217 		case PUFFS_VN_READDIR:
    218 			puffsdump_readdir(preq);
    219 			break;
    220 		case PUFFS_VN_CREATE:
    221 		case PUFFS_VN_MKDIR:
    222 		case PUFFS_VN_MKNOD:
    223 		case PUFFS_VN_SYMLINK:
    224 			puffsdump_create(preq);
    225 			break;
    226 		case PUFFS_VN_SETATTR:
    227 			puffsdump_attr(preq);
    228 			break;
    229 		default:
    230 			break;
    231 		}
    232 	}
    233 
    234 	PU_LOCK();
    235 	gettimeofday(&tv_now, NULL);
    236 	timersub(&tv_now, &tv_prev, &tv);
    237 	printf(DINT "since previous call: %lld.%06ld\n",
    238 	    (long long)tv.tv_sec, (long)tv.tv_usec);
    239 	gettimeofday(&tv_prev, NULL);
    240 	PU_UNLOCK();
    241 }
    242 
    243 void
    244 puffsdump_rv(struct puffs_req *preq)
    245 {
    246 
    247 	if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
    248 		switch (preq->preq_optype) {
    249 		case PUFFS_VN_LOOKUP:
    250 			puffsdump_lookup_rv(preq);
    251 			break;
    252 		case PUFFS_VN_CREATE:
    253 		case PUFFS_VN_MKDIR:
    254 		case PUFFS_VN_MKNOD:
    255 		case PUFFS_VN_SYMLINK:
    256 			puffsdump_create_rv(preq);
    257 			break;
    258 		case PUFFS_VN_READ:
    259 		case PUFFS_VN_WRITE:
    260 			puffsdump_readwrite_rv(preq);
    261 			break;
    262 		case PUFFS_VN_READDIR:
    263 			puffsdump_readdir_rv(preq);
    264 			break;
    265 		case PUFFS_VN_GETATTR:
    266 			puffsdump_attr(preq);
    267 			break;
    268 		default:
    269 			break;
    270 		}
    271 	}
    272 
    273 	printf("RV reqid: %" PRIu64 ", result: %d %s\n",
    274 	    preq->preq_id, preq->preq_rv,
    275 	    preq->preq_rv ? strerror(preq->preq_rv) : "");
    276 }
    277 
    278 /*
    279  * Slightly tedious print-routine so that we get a nice NOVAL instead
    280  * of some tedious output representations for -1, especially (uint64_t)-1
    281  *
    282  * We use typecasting to make this work beyond time_t/dev_t size changes.
    283  */
    284 static void
    285 dumpattr(struct vattr *vap)
    286 {
    287 	const char * const vtypes[] = { VNODE_TYPES };
    288 	char buf[128];
    289 
    290 /* XXX: better readability.  and this is debug, so no cycle-sweat */
    291 #define DEFAULTBUF() snprintf(buf, sizeof(buf), "NOVAL")
    292 
    293 	printf(DINT "vattr:\n");
    294 	printf(DINT DINT "type: %s, ", vtypes[vap->va_type]);
    295 
    296 	DEFAULTBUF();
    297 	if (vap->va_mode != (mode_t)PUFFS_VNOVAL)
    298 		snprintf(buf, sizeof(buf), "0%o", vap->va_mode);
    299 	printf("mode: %s, ", buf);
    300 
    301 	DEFAULTBUF();
    302 	if (vap->va_nlink != (nlink_t)PUFFS_VNOVAL)
    303 		snprintf(buf, sizeof(buf), "%d", vap->va_nlink);
    304 	printf("nlink: %s, ", buf);
    305 
    306 	DEFAULTBUF();
    307 	if (vap->va_uid != (uid_t)PUFFS_VNOVAL)
    308 		snprintf(buf, sizeof(buf), "%d", vap->va_uid);
    309 	printf("uid: %s, ", buf);
    310 
    311 	DEFAULTBUF();
    312 	if (vap->va_gid != (gid_t)PUFFS_VNOVAL)
    313 		snprintf(buf, sizeof(buf), "%d", vap->va_gid);
    314 	printf("gid: %s\n", buf);
    315 
    316 	DEFAULTBUF();
    317 	if ((unsigned long long)vap->va_fsid!=(unsigned long long)PUFFS_VNOVAL)
    318 		snprintf(buf, sizeof(buf), "0x%llx",
    319 		    (unsigned long long)vap->va_fsid);
    320 	printf(DINT DINT "fsid: %s, ", buf);
    321 
    322 	DEFAULTBUF();
    323 	if (vap->va_fileid != (ino_t)PUFFS_VNOVAL)
    324 		snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_fileid);
    325 	printf("ino: %s, ", buf);
    326 
    327 	DEFAULTBUF();
    328 	if (vap->va_size != (u_quad_t)PUFFS_VNOVAL)
    329 		snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_size);
    330 	printf("size: %s, ", buf);
    331 
    332 	DEFAULTBUF();
    333 	if (vap->va_blocksize != (long)PUFFS_VNOVAL)
    334 		snprintf(buf, sizeof(buf), "%ld", vap->va_blocksize);
    335 	printf("bsize: %s\n", buf);
    336 
    337 	DEFAULTBUF();
    338 	if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL)
    339 		snprintf(buf, sizeof(buf), "%lld",
    340 		    (long long)vap->va_atime.tv_sec);
    341 	printf(DINT DINT "a.s: %s, ", buf);
    342 
    343 	DEFAULTBUF();
    344 	if (vap->va_atime.tv_nsec != (long)PUFFS_VNOVAL)
    345 		snprintf(buf, sizeof(buf), "%ld", vap->va_atime.tv_nsec);
    346 	printf("a.ns: %s, ", buf);
    347 
    348 	DEFAULTBUF();
    349 	if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL)
    350 		snprintf(buf, sizeof(buf), "%lld",
    351 		    (long long)vap->va_mtime.tv_sec);
    352 	printf("m.s: %s, ", buf);
    353 
    354 	DEFAULTBUF();
    355 	if (vap->va_mtime.tv_nsec != (long)PUFFS_VNOVAL)
    356 		snprintf(buf, sizeof(buf), "%ld", vap->va_mtime.tv_nsec);
    357 	printf("m.ns: %s\n", buf);
    358 
    359 	DEFAULTBUF();
    360 	if (vap->va_ctime.tv_sec != (time_t)PUFFS_VNOVAL)
    361 		snprintf(buf, sizeof(buf), "%lld",
    362 		    (long long)vap->va_ctime.tv_sec);
    363 	printf(DINT DINT "c.s: %s, ", buf);
    364 
    365 	DEFAULTBUF();
    366 	if (vap->va_ctime.tv_nsec != (long)PUFFS_VNOVAL)
    367 		snprintf(buf, sizeof(buf), "%ld", vap->va_ctime.tv_nsec);
    368 	printf("c.ns: %s, ", buf);
    369 
    370 	DEFAULTBUF();
    371 	if (vap->va_birthtime.tv_sec != (time_t)PUFFS_VNOVAL)
    372 		snprintf(buf, sizeof(buf), "%lld",
    373 		    (long long)vap->va_birthtime.tv_sec);
    374 	printf("b.s: %s, ", buf);
    375 
    376 	DEFAULTBUF();
    377 	if (vap->va_birthtime.tv_nsec != (long)PUFFS_VNOVAL)
    378 		snprintf(buf, sizeof(buf), "%ld", vap->va_birthtime.tv_nsec);
    379 	printf("b.ns: %s\n", buf);
    380 
    381 	DEFAULTBUF();
    382 	if (vap->va_gen != (u_long)PUFFS_VNOVAL)
    383 		snprintf(buf, sizeof(buf), "%lu", vap->va_gen);
    384 	printf(DINT DINT "gen: %s, ", buf);
    385 
    386 	DEFAULTBUF();
    387 	if (vap->va_flags != (u_long)PUFFS_VNOVAL)
    388 		snprintf(buf, sizeof(buf), "0x%lx", vap->va_flags);
    389 	printf("flags: %s, ", buf);
    390 
    391 	DEFAULTBUF();
    392 	if (vap->va_rdev != (dev_t)PUFFS_VNOVAL)
    393 		snprintf(buf, sizeof(buf), "0x%llx",
    394 		    (unsigned long long)vap->va_rdev);
    395 	printf("rdev: %s\n", buf);
    396 
    397 	DEFAULTBUF();
    398 	if (vap->va_bytes != (u_quad_t)PUFFS_VNOVAL)
    399 		snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_bytes);
    400 	printf(DINT DINT "bytes: %s, ", buf);
    401 
    402 	snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_filerev);
    403 	printf("filerev: %s, ", buf);
    404 
    405 	snprintf(buf, sizeof(buf), "0x%x", vap->va_vaflags);
    406 	printf("vaflags: %s\n", buf);
    407 }
    408 
    409 void
    410 puffsdump_cookie(puffs_cookie_t c, const char *cookiename)
    411 {
    412 
    413 	printf("%scookie: at %p\n", cookiename, c);
    414 }
    415 
    416 static const char *cn_opnames[] = {
    417 	"LOOKUP",
    418 	"CREATE",
    419 	"DELETE",
    420 	"RENAME"
    421 };
    422 
    423 void
    424 puffsdump_cn(struct puffs_kcn *pkcn)
    425 {
    426 
    427 	printf(DINT "puffs_cn: \"%s\", len %zu op %s (flags 0x%x)\n",
    428 	    pkcn->pkcn_name, pkcn->pkcn_namelen,
    429 	    cn_opnames[pkcn->pkcn_nameiop & NAMEI_OPMASK],
    430 	    pkcn->pkcn_flags);
    431 }
    432 
    433 void
    434 puffsdump_lookup(struct puffs_req *preq)
    435 {
    436 	struct puffs_vnmsg_lookup *lookup_msg = (void *)preq;
    437 
    438 	puffsdump_cn(&lookup_msg->pvnr_cn);
    439 }
    440 
    441 void
    442 puffsdump_lookup_rv(struct puffs_req *preq)
    443 {
    444 	struct puffs_vnmsg_lookup *lookup_msg = (void *)preq;
    445 
    446 	printf(DINT "new %p, type 0x%x, size 0x%"PRIu64", dev 0x%llx\n",
    447 	    lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
    448 	    lookup_msg->pvnr_size, (unsigned long long)lookup_msg->pvnr_rdev);
    449 }
    450 
    451 void
    452 puffsdump_create(struct puffs_req *preq)
    453 {
    454 	/* XXX: wrong type, but we know it fits the slot */
    455 	struct puffs_vnmsg_create *create_msg = (void *)preq;
    456 
    457 	dumpattr(&create_msg->pvnr_va);
    458 }
    459 
    460 void
    461 puffsdump_create_rv(struct puffs_req *preq)
    462 {
    463 	/* XXX: wrong type, but we know it fits the slot */
    464 	struct puffs_vnmsg_create *create_msg = (void *)preq;
    465 
    466 	printf(DINT "new %p\n", create_msg->pvnr_newnode);
    467 }
    468 
    469 void
    470 puffsdump_readwrite(struct puffs_req *preq)
    471 {
    472 	struct puffs_vnmsg_rw *rw_msg = (void *)preq;
    473 
    474 	printf(DINT "offset: %" PRId64 ", resid %zu, ioflag 0x%x\n",
    475 	    rw_msg->pvnr_offset, rw_msg->pvnr_resid, rw_msg->pvnr_ioflag);
    476 }
    477 
    478 void
    479 puffsdump_readwrite_rv(struct puffs_req *preq)
    480 {
    481 	struct puffs_vnmsg_rw *rw_msg = (void *)preq;
    482 
    483 	printf(DINT "resid after op: %zu\n", rw_msg->pvnr_resid);
    484 }
    485 
    486 void
    487 puffsdump_readdir_rv(struct puffs_req *preq)
    488 {
    489 	struct puffs_vnmsg_readdir *readdir_msg = (void *)preq;
    490 
    491 	printf(DINT "resid after op: %zu, eofflag %d\n",
    492 	    readdir_msg->pvnr_resid, readdir_msg->pvnr_eofflag);
    493 }
    494 
    495 void
    496 puffsdump_open(struct puffs_req *preq)
    497 {
    498 	struct puffs_vnmsg_open *open_msg = (void *)preq;
    499 
    500 	printf(DINT "mode: 0x%x\n", open_msg->pvnr_mode);
    501 }
    502 
    503 void
    504 puffsdump_targ(struct puffs_req *preq)
    505 {
    506 	struct puffs_vnmsg_remove *remove_msg = (void *)preq; /* XXX! */
    507 
    508 	printf(DINT "target cookie: %p\n", remove_msg->pvnr_cookie_targ);
    509 }
    510 
    511 void
    512 puffsdump_readdir(struct puffs_req *preq)
    513 {
    514 	struct puffs_vnmsg_readdir *readdir_msg = (void *)preq;
    515 
    516 	printf(DINT "read offset: %" PRId64 "\n", readdir_msg->pvnr_offset);
    517 }
    518 
    519 void
    520 puffsdump_attr(struct puffs_req *preq)
    521 {
    522 	struct puffs_vnmsg_setgetattr *attr_msg = (void *)preq;
    523 
    524 	dumpattr(&attr_msg->pvnr_va);
    525 }
    526