1 /* $NetBSD: opdump.c,v 1.37 2014/10/31 13:56:04 manu Exp $ */
4 * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
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.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
32 /* Pretty-printing helper routines for VFS/VOP request contents */
34 /* yes, this is pretty much a mess */
36 #include <sys/cdefs.h>
38 __RCSID("$NetBSD: opdump.c,v 1.37 2014/10/31 13:56:04 manu Exp $");
41 #include <sys/types.h>
45 #include <puffsdump.h>
49 #include "puffs_priv.h"
53 const char *puffsdump_vfsop_revmap
[] = {
67 "PUFFS_VFS_EXTATTRCTL",
70 size_t puffsdump_vfsop_count
= __arraycount(puffsdump_vfsop_revmap
);
72 const char *puffsdump_vnop_revmap
[] = {
114 "PUFFS_VN_GETEXTATTR",
115 "PUFFS_VN_LISTEXTATTR",
116 "PUFFS_VN_OPENEXTATTR",
117 "PUFFS_VN_DELETEEXTATTR",
118 "PUFFS_VN_SETEXTATTR",
119 "PUFFS_VN_CLOSEEXTATTR",
120 "PUFFS_VN_FALLOCATE",
123 size_t puffsdump_vnop_count
= __arraycount(puffsdump_vnop_revmap
);
126 const char *puffsdump_cacheop_revmap
[] = {
130 const char *puffsdump_errnot_revmap
[] = {
132 "PUFFS_ERR_MAKENODE",
135 "PUFFS_ERR_READLINK",
139 "PUFFS_ERR_GETEXTATTR",
140 "PUFFS_ERR_LISTEXTATTR",
142 size_t puffsdump_errnot_count
= __arraycount(puffsdump_errnot_revmap
);
144 const char *puffsdump_flush_revmap
[] = {
145 "PUFFS_INVAL_NAMECACHE_NODE",
146 "PUFFS_INVAL_NAMECACHE_DIR",
147 "PUFFS_INVAL_NAMECACHE_ALL",
148 "PUFFS_INVAL_PAGECACHE_NODE_RANGE",
149 "PUFFS_FLUSH_PAGECACHE_NODE_RANGE",
151 size_t puffsdump_flush_count
= __arraycount(puffsdump_flush_revmap
);
153 static __printflike(1, 2) void
154 mydprintf(const char *fmt
, ...)
159 vfprintf(stderr
, fmt
, ap
);
164 puffsdump_req(struct puffs_req
*preq
)
167 static struct timeval tv_prev
;
168 struct timeval tv_now
, tv
;
172 int opclass
, isvn
= 0;
174 mydprintf("reqid: %" PRIu64
", ", preq
->preq_id
);
175 opclass
= PUFFSOP_OPCLASS(preq
->preq_opclass
);
178 map
= puffsdump_vfsop_revmap
;
179 maxhandle
= puffsdump_vfsop_count
;
182 map
= puffsdump_vnop_revmap
;
183 maxhandle
= puffsdump_vnop_count
;
187 map
= puffsdump_cacheop_revmap
;
188 maxhandle
= __arraycount(puffsdump_cacheop_revmap
);
191 map
= puffsdump_errnot_revmap
;
192 maxhandle
= puffsdump_errnot_count
;
195 map
= puffsdump_flush_revmap
;
196 maxhandle
= puffsdump_flush_count
;
199 mydprintf("unhandled opclass %d\n", opclass
);
203 if (preq
->preq_optype
< maxhandle
) {
204 optype
= map
[preq
->preq_optype
];
206 snprintf(buf
, sizeof(buf
), "UNKNOWN (%d)", preq
->preq_optype
);
210 mydprintf("opclass %d%s, optype: %s, "
211 "cookie: %p,\n" DINT
"aux: %p, auxlen: %zu, pid: %d, lwpid: %d\n",
212 opclass
, PUFFSOP_WANTREPLY(preq
->preq_opclass
) ? "" : " (FAF)",
213 optype
, preq
->preq_cookie
,
214 preq
->preq_buf
, preq
->preq_buflen
,
215 preq
->preq_pid
, preq
->preq_lid
);
218 switch (preq
->preq_optype
) {
219 case PUFFS_VN_LOOKUP
:
220 puffsdump_lookup(preq
);
224 puffsdump_readwrite(preq
);
227 puffsdump_open(preq
);
229 case PUFFS_VN_REMOVE
:
232 puffsdump_targ(preq
);
234 case PUFFS_VN_READDIR
:
235 puffsdump_readdir(preq
);
237 case PUFFS_VN_CREATE
:
240 case PUFFS_VN_SYMLINK
:
241 puffsdump_create(preq
);
243 case PUFFS_VN_SETATTR
:
244 puffsdump_attr(preq
);
252 gettimeofday(&tv_now
, NULL
);
253 timersub(&tv_now
, &tv_prev
, &tv
);
254 mydprintf(DINT
"since previous call: %lld.%06ld\n",
255 (long long)tv
.tv_sec
, (long)tv
.tv_usec
);
256 gettimeofday(&tv_prev
, NULL
);
261 puffsdump_rv(struct puffs_req
*preq
)
264 if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VN
) {
265 switch (preq
->preq_optype
) {
266 case PUFFS_VN_LOOKUP
:
267 puffsdump_lookup_rv(preq
);
269 case PUFFS_VN_CREATE
:
272 case PUFFS_VN_SYMLINK
:
273 puffsdump_create_rv(preq
);
277 puffsdump_readwrite_rv(preq
);
279 case PUFFS_VN_READDIR
:
280 puffsdump_readdir_rv(preq
);
282 case PUFFS_VN_GETATTR
:
283 puffsdump_attr(preq
);
290 mydprintf("RV reqid: %" PRIu64
", result: %d %s\n",
291 preq
->preq_id
, preq
->preq_rv
,
292 preq
->preq_rv
? strerror(preq
->preq_rv
) : "");
296 * Slightly tedious print-routine so that we get a nice NOVAL instead
297 * of some tedious output representations for -1, especially (uint64_t)-1
299 * We use typecasting to make this work beyond time_t/dev_t size changes.
302 dumpattr(struct vattr
*vap
)
304 const char * const vtypes
[] = { VNODE_TYPES
};
307 /* XXX: better readability. and this is debug, so no cycle-sweat */
308 #define DEFAULTBUF() snprintf(buf, sizeof(buf), "NOVAL")
310 mydprintf(DINT
"vattr:\n");
311 mydprintf(DINT DINT
"type: %s, ", vtypes
[vap
->va_type
]);
314 if (vap
->va_mode
!= (mode_t
)PUFFS_VNOVAL
)
315 snprintf(buf
, sizeof(buf
), "0%o", vap
->va_mode
);
316 mydprintf("mode: %s, ", buf
);
319 if (vap
->va_nlink
!= (nlink_t
)PUFFS_VNOVAL
)
320 snprintf(buf
, sizeof(buf
), "%d", vap
->va_nlink
);
321 mydprintf("nlink: %s, ", buf
);
324 if (vap
->va_uid
!= (uid_t
)PUFFS_VNOVAL
)
325 snprintf(buf
, sizeof(buf
), "%d", vap
->va_uid
);
326 mydprintf("uid: %s, ", buf
);
329 if (vap
->va_gid
!= (gid_t
)PUFFS_VNOVAL
)
330 snprintf(buf
, sizeof(buf
), "%d", vap
->va_gid
);
331 mydprintf("gid: %s\n", buf
);
334 if ((unsigned long long)vap
->va_fsid
!=(unsigned long long)PUFFS_VNOVAL
)
335 snprintf(buf
, sizeof(buf
), "0x%llx",
336 (unsigned long long)vap
->va_fsid
);
337 mydprintf(DINT DINT
"fsid: %s, ", buf
);
340 if (vap
->va_fileid
!= (ino_t
)PUFFS_VNOVAL
)
341 snprintf(buf
, sizeof(buf
), "%" PRIu64
, vap
->va_fileid
);
342 mydprintf("ino: %s, ", buf
);
345 if (vap
->va_size
!= (u_quad_t
)PUFFS_VNOVAL
)
346 snprintf(buf
, sizeof(buf
), "%" PRIu64
, vap
->va_size
);
347 mydprintf("size: %s, ", buf
);
350 if (vap
->va_blocksize
!= (long)PUFFS_VNOVAL
)
351 snprintf(buf
, sizeof(buf
), "%ld", vap
->va_blocksize
);
352 mydprintf("bsize: %s\n", buf
);
355 if (vap
->va_atime
.tv_sec
!= (time_t)PUFFS_VNOVAL
)
356 snprintf(buf
, sizeof(buf
), "%lld",
357 (long long)vap
->va_atime
.tv_sec
);
358 mydprintf(DINT DINT
"a.s: %s, ", buf
);
361 if (vap
->va_atime
.tv_nsec
!= (long)PUFFS_VNOVAL
)
362 snprintf(buf
, sizeof(buf
), "%ld", vap
->va_atime
.tv_nsec
);
363 mydprintf("a.ns: %s, ", buf
);
366 if (vap
->va_mtime
.tv_sec
!= (time_t)PUFFS_VNOVAL
)
367 snprintf(buf
, sizeof(buf
), "%lld",
368 (long long)vap
->va_mtime
.tv_sec
);
369 mydprintf("m.s: %s, ", buf
);
372 if (vap
->va_mtime
.tv_nsec
!= (long)PUFFS_VNOVAL
)
373 snprintf(buf
, sizeof(buf
), "%ld", vap
->va_mtime
.tv_nsec
);
374 mydprintf("m.ns: %s\n", buf
);
377 if (vap
->va_ctime
.tv_sec
!= (time_t)PUFFS_VNOVAL
)
378 snprintf(buf
, sizeof(buf
), "%lld",
379 (long long)vap
->va_ctime
.tv_sec
);
380 mydprintf(DINT DINT
"c.s: %s, ", buf
);
383 if (vap
->va_ctime
.tv_nsec
!= (long)PUFFS_VNOVAL
)
384 snprintf(buf
, sizeof(buf
), "%ld", vap
->va_ctime
.tv_nsec
);
385 mydprintf("c.ns: %s, ", buf
);
388 if (vap
->va_birthtime
.tv_sec
!= (time_t)PUFFS_VNOVAL
)
389 snprintf(buf
, sizeof(buf
), "%lld",
390 (long long)vap
->va_birthtime
.tv_sec
);
391 mydprintf("b.s: %s, ", buf
);
394 if (vap
->va_birthtime
.tv_nsec
!= (long)PUFFS_VNOVAL
)
395 snprintf(buf
, sizeof(buf
), "%ld", vap
->va_birthtime
.tv_nsec
);
396 mydprintf("b.ns: %s\n", buf
);
399 if (vap
->va_gen
!= (u_long
)PUFFS_VNOVAL
)
400 snprintf(buf
, sizeof(buf
), "%lu", vap
->va_gen
);
401 mydprintf(DINT DINT
"gen: %s, ", buf
);
404 if (vap
->va_flags
!= (u_long
)PUFFS_VNOVAL
)
405 snprintf(buf
, sizeof(buf
), "0x%lx", vap
->va_flags
);
406 mydprintf("flags: %s, ", buf
);
409 if (vap
->va_rdev
!= (dev_t
)PUFFS_VNOVAL
)
410 snprintf(buf
, sizeof(buf
), "0x%llx",
411 (unsigned long long)vap
->va_rdev
);
412 mydprintf("rdev: %s\n", buf
);
415 if (vap
->va_bytes
!= (u_quad_t
)PUFFS_VNOVAL
)
416 snprintf(buf
, sizeof(buf
), "%" PRIu64
, vap
->va_bytes
);
417 mydprintf(DINT DINT
"bytes: %s, ", buf
);
419 snprintf(buf
, sizeof(buf
), "%" PRIu64
, vap
->va_filerev
);
420 mydprintf("filerev: %s, ", buf
);
422 snprintf(buf
, sizeof(buf
), "0x%x", vap
->va_vaflags
);
423 mydprintf("vaflags: %s\n", buf
);
427 puffsdump_cookie(puffs_cookie_t c
, const char *cookiename
)
430 mydprintf("%scookie: at %p\n", cookiename
, c
);
433 static const char *cn_opnames
[] = {
441 puffsdump_cn(struct puffs_kcn
*pkcn
)
444 mydprintf(DINT
"puffs_cn: \"%s\", len %zu op %s (flags 0x%x)\n",
445 pkcn
->pkcn_name
, pkcn
->pkcn_namelen
,
446 cn_opnames
[pkcn
->pkcn_nameiop
& NAMEI_OPMASK
],
451 puffsdump_lookup(struct puffs_req
*preq
)
453 struct puffs_vnmsg_lookup
*lookup_msg
= (void *)preq
;
455 puffsdump_cn(&lookup_msg
->pvnr_cn
);
459 puffsdump_lookup_rv(struct puffs_req
*preq
)
461 struct puffs_vnmsg_lookup
*lookup_msg
= (void *)preq
;
463 mydprintf(DINT
"new %p, type 0x%x, size 0x%"PRIu64
", dev 0x%llx\n",
464 lookup_msg
->pvnr_newnode
, lookup_msg
->pvnr_vtype
,
465 lookup_msg
->pvnr_size
, (unsigned long long)lookup_msg
->pvnr_rdev
);
469 puffsdump_create(struct puffs_req
*preq
)
471 /* XXX: wrong type, but we know it fits the slot */
472 struct puffs_vnmsg_create
*create_msg
= (void *)preq
;
474 dumpattr(&create_msg
->pvnr_va
);
478 puffsdump_create_rv(struct puffs_req
*preq
)
480 /* XXX: wrong type, but we know it fits the slot */
481 struct puffs_vnmsg_create
*create_msg
= (void *)preq
;
483 mydprintf(DINT
"new %p\n", create_msg
->pvnr_newnode
);
487 puffsdump_readwrite(struct puffs_req
*preq
)
489 struct puffs_vnmsg_rw
*rw_msg
= (void *)preq
;
491 mydprintf(DINT
"offset: %" PRId64
", resid %zu, ioflag 0x%x\n",
492 rw_msg
->pvnr_offset
, rw_msg
->pvnr_resid
, rw_msg
->pvnr_ioflag
);
496 puffsdump_readwrite_rv(struct puffs_req
*preq
)
498 struct puffs_vnmsg_rw
*rw_msg
= (void *)preq
;
500 mydprintf(DINT
"resid after op: %zu\n", rw_msg
->pvnr_resid
);
504 puffsdump_readdir_rv(struct puffs_req
*preq
)
506 struct puffs_vnmsg_readdir
*readdir_msg
= (void *)preq
;
508 mydprintf(DINT
"resid after op: %zu, eofflag %d\n",
509 readdir_msg
->pvnr_resid
, readdir_msg
->pvnr_eofflag
);
513 puffsdump_open(struct puffs_req
*preq
)
515 struct puffs_vnmsg_open
*open_msg
= (void *)preq
;
517 mydprintf(DINT
"mode: 0x%x\n", open_msg
->pvnr_mode
);
521 puffsdump_targ(struct puffs_req
*preq
)
523 struct puffs_vnmsg_remove
*remove_msg
= (void *)preq
; /* XXX! */
525 mydprintf(DINT
"target cookie: %p\n", remove_msg
->pvnr_cookie_targ
);
529 puffsdump_readdir(struct puffs_req
*preq
)
531 struct puffs_vnmsg_readdir
*readdir_msg
= (void *)preq
;
533 mydprintf(DINT
"read offset: %" PRId64
"\n", readdir_msg
->pvnr_offset
);
537 puffsdump_attr(struct puffs_req
*preq
)
539 struct puffs_vnmsg_setgetattr
*attr_msg
= (void *)preq
;
541 dumpattr(&attr_msg
->pvnr_va
);