xref: /dragonfly/test/debug/vnodeinfo.c (revision aa560c07)
1fa12c626SMatthew Dillon /*
2fa12c626SMatthew Dillon  * VNODEINFO.C
3fa12c626SMatthew Dillon  *
4fa12c626SMatthew Dillon  * cc -I/usr/src/sys vnodeinfo.c -o /usr/local/bin/vnodeinfo -lkvm
5fa12c626SMatthew Dillon  *
6fa12c626SMatthew Dillon  * vnodeinfo
7fa12c626SMatthew Dillon  *
8fa12c626SMatthew Dillon  * Dump the mountlist and related vnodes.
9fa12c626SMatthew Dillon  *
105c8e2a54SMatthew Dillon  *
115c8e2a54SMatthew Dillon  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
125c8e2a54SMatthew Dillon  *
135c8e2a54SMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
145c8e2a54SMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
155c8e2a54SMatthew Dillon  *
165c8e2a54SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
175c8e2a54SMatthew Dillon  * modification, are permitted provided that the following conditions
185c8e2a54SMatthew Dillon  * are met:
195c8e2a54SMatthew Dillon  *
205c8e2a54SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
215c8e2a54SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
225c8e2a54SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
235c8e2a54SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
245c8e2a54SMatthew Dillon  *    the documentation and/or other materials provided with the
255c8e2a54SMatthew Dillon  *    distribution.
265c8e2a54SMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
275c8e2a54SMatthew Dillon  *    contributors may be used to endorse or promote products derived
285c8e2a54SMatthew Dillon  *    from this software without specific, prior written permission.
295c8e2a54SMatthew Dillon  *
305c8e2a54SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
315c8e2a54SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
325c8e2a54SMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
335c8e2a54SMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
345c8e2a54SMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
355c8e2a54SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
365c8e2a54SMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
375c8e2a54SMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
385c8e2a54SMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
395c8e2a54SMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
405c8e2a54SMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
415c8e2a54SMatthew Dillon  * SUCH DAMAGE.
425c8e2a54SMatthew Dillon  *
43fa12c626SMatthew Dillon  */
44fa12c626SMatthew Dillon 
4578465ba9SMatthew Dillon #define _KERNEL_STRUCTURES
46fa12c626SMatthew Dillon #include <sys/param.h>
47fa12c626SMatthew Dillon #include <sys/user.h>
48fa12c626SMatthew Dillon #include <sys/malloc.h>
49fa12c626SMatthew Dillon #include <sys/signalvar.h>
50bb87550cSMatthew Dillon #include <sys/namecache.h>
51fa12c626SMatthew Dillon #include <sys/mount.h>
52fa12c626SMatthew Dillon #include <sys/vnode.h>
53af456e64SMatthew Dillon #include <sys/buf.h>
54fa12c626SMatthew Dillon 
55fa12c626SMatthew Dillon #include <vm/vm.h>
56fa12c626SMatthew Dillon #include <vm/vm_page.h>
57fa12c626SMatthew Dillon #include <vm/vm_kern.h>
5817ba2e5aSMatthew Dillon #include <vm/vm_object.h>
59fa12c626SMatthew Dillon #include <vm/swap_pager.h>
60fa12c626SMatthew Dillon #include <vm/vnode_pager.h>
61fa12c626SMatthew Dillon 
623661e25dSMatthew Dillon #include <vfs/ufs/quota.h>
633661e25dSMatthew Dillon #include <vfs/ufs/inode.h>
643661e25dSMatthew Dillon 
65fa12c626SMatthew Dillon #include <stdio.h>
66fa12c626SMatthew Dillon #include <stdlib.h>
67fa12c626SMatthew Dillon #include <string.h>
68fa12c626SMatthew Dillon #include <fcntl.h>
69fa12c626SMatthew Dillon #include <kvm.h>
70fa12c626SMatthew Dillon #include <nlist.h>
71fa12c626SMatthew Dillon #include <getopt.h>
72fa12c626SMatthew Dillon 
73fa12c626SMatthew Dillon struct nlist Nl[] = {
74fa12c626SMatthew Dillon     { "_mountlist" },
75fd25e126SAntonio Huete Jimenez     { "_vnode_list_hash" },
76*aa560c07SAntonio Huete Jimenez     { "_ncpus" },
77fa12c626SMatthew Dillon     { NULL }
78fa12c626SMatthew Dillon };
79fa12c626SMatthew Dillon 
80fa12c626SMatthew Dillon static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
81fa12c626SMatthew Dillon static struct mount *dumpmount(kvm_t *kd, struct mount *mp);
825e105359SAntonio Huete Jimenez static struct vnode *dumpvp(kvm_t *kd, struct vnode *vp, int whichlist, char *vfc_name);
83af456e64SMatthew Dillon static void dumpbufs(kvm_t *kd, void *bufp, const char *id);
843661e25dSMatthew Dillon static void dumplocks(kvm_t *kd, struct lockf *lockf);
853661e25dSMatthew Dillon static void dumplockinfo(kvm_t *kd, struct lockf_range *item);
8617ba2e5aSMatthew Dillon static int getobjpages(kvm_t *kd, struct vm_object *obj);
87ada41611SMatthew Dillon static int getobjvnpsize(kvm_t *kd, struct vm_object *obj);
88fa12c626SMatthew Dillon 
895e105359SAntonio Huete Jimenez static const struct dump_private_data {
905e105359SAntonio Huete Jimenez 	char vfc_name[MFSNAMELEN];
915e105359SAntonio Huete Jimenez 	void (*dumpfn)(kvm_t *, void *);
925e105359SAntonio Huete Jimenez } dumplist[] = {
935e105359SAntonio Huete Jimenez 	{ "", NULL }
945e105359SAntonio Huete Jimenez };
955e105359SAntonio Huete Jimenez 
96af456e64SMatthew Dillon int tracebufs = 0;
973661e25dSMatthew Dillon int tracelocks = 0;
98bb87550cSMatthew Dillon int withnames = 0;
995e105359SAntonio Huete Jimenez int fsprivate = 0;
100af456e64SMatthew Dillon 
101af456e64SMatthew Dillon int
main(int ac,char ** av)102fa12c626SMatthew Dillon main(int ac, char **av)
103fa12c626SMatthew Dillon {
104fa12c626SMatthew Dillon     struct mount *mp;
105*aa560c07SAntonio Huete Jimenez     struct vnode_index *vib;
106*aa560c07SAntonio Huete Jimenez     struct vnode_index vni;
107fa12c626SMatthew Dillon     kvm_t *kd;
108fa12c626SMatthew Dillon     int ch;
109*aa560c07SAntonio Huete Jimenez     int ncpus = 0;
110fa12c626SMatthew Dillon     const char *corefile = NULL;
111fa12c626SMatthew Dillon     const char *sysfile = NULL;
112fa12c626SMatthew Dillon 
1135e105359SAntonio Huete Jimenez     while ((ch = getopt(ac, av, "alnbM:N:p")) != -1) {
114fa12c626SMatthew Dillon 	switch(ch) {
115af456e64SMatthew Dillon 	case 'b':
116af456e64SMatthew Dillon 	    tracebufs = 1;
117af456e64SMatthew Dillon 	    break;
118bb87550cSMatthew Dillon 	case 'n':
119bb87550cSMatthew Dillon 	    withnames = 1;
120bb87550cSMatthew Dillon 	    break;
1213661e25dSMatthew Dillon 	case 'l':
1223661e25dSMatthew Dillon 	    tracelocks = 1;
1233661e25dSMatthew Dillon 	    break;
124bb87550cSMatthew Dillon 	case 'a':
125bb87550cSMatthew Dillon 	    tracebufs = 1;
1263661e25dSMatthew Dillon 	    tracelocks = 1;
127bb87550cSMatthew Dillon 	    withnames = 1;
1285e105359SAntonio Huete Jimenez 	    fsprivate = 1;
1295e105359SAntonio Huete Jimenez 	    break;
1305e105359SAntonio Huete Jimenez 	case 'p':
1315e105359SAntonio Huete Jimenez 	    fsprivate = 1;
132bb87550cSMatthew Dillon 	    break;
133fa12c626SMatthew Dillon 	case 'M':
134fa12c626SMatthew Dillon 	    corefile = optarg;
135fa12c626SMatthew Dillon 	    break;
136fa12c626SMatthew Dillon 	case 'N':
137fa12c626SMatthew Dillon 	    sysfile = optarg;
138fa12c626SMatthew Dillon 	    break;
139fa12c626SMatthew Dillon 	default:
1405e105359SAntonio Huete Jimenez 	    fprintf(stderr, "%s [-pbnla] [-M core] [-N system]\n", av[0]);
141fa12c626SMatthew Dillon 	    exit(1);
142fa12c626SMatthew Dillon 	}
143fa12c626SMatthew Dillon     }
144fa12c626SMatthew Dillon 
145fa12c626SMatthew Dillon     if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
146fa12c626SMatthew Dillon 	perror("kvm_open");
147fa12c626SMatthew Dillon 	exit(1);
148fa12c626SMatthew Dillon     }
149fa12c626SMatthew Dillon     if (kvm_nlist(kd, Nl) != 0) {
150fa12c626SMatthew Dillon 	perror("kvm_nlist");
151fa12c626SMatthew Dillon 	exit(1);
152fa12c626SMatthew Dillon     }
153*aa560c07SAntonio Huete Jimenez 
154*aa560c07SAntonio Huete Jimenez     /* Mount points and their private data */
155fa12c626SMatthew Dillon     kkread(kd, Nl[0].n_value, &mp, sizeof(mp));
156fa12c626SMatthew Dillon     while (mp)
157fa12c626SMatthew Dillon 	mp = dumpmount(kd, mp);
158*aa560c07SAntonio Huete Jimenez 
159*aa560c07SAntonio Huete Jimenez     /*
160*aa560c07SAntonio Huete Jimenez      * Get ncpus for the vnode lists, we could get it with a sysctl
161*aa560c07SAntonio Huete Jimenez      * but since we're reading kernel memory, take advantage of it.
162*aa560c07SAntonio Huete Jimenez      * Also read the base address of vnode_list_hash.
163*aa560c07SAntonio Huete Jimenez      */
164*aa560c07SAntonio Huete Jimenez     kkread(kd, Nl[1].n_value, &vib, sizeof(vib));
165*aa560c07SAntonio Huete Jimenez     kkread(kd, Nl[2].n_value, &ncpus, sizeof(ncpus));
166*aa560c07SAntonio Huete Jimenez 
167*aa560c07SAntonio Huete Jimenez     /* Per-CPU list of inactive vnodes */
168ee173d09SSascha Wildner     printf("INACTIVELIST {\n");
169*aa560c07SAntonio Huete Jimenez 
170*aa560c07SAntonio Huete Jimenez     for (int i = 0; i < ncpus; i++) {
171*aa560c07SAntonio Huete Jimenez 	    struct vnode *vp;
172*aa560c07SAntonio Huete Jimenez 
173*aa560c07SAntonio Huete Jimenez 	    kkread(kd, (u_long)(vib + i), &vni, sizeof(vni));
174*aa560c07SAntonio Huete Jimenez 	    vp = vni.inactive_list.tqh_first;
175*aa560c07SAntonio Huete Jimenez 	    for (; vp != NULL;)
176*aa560c07SAntonio Huete Jimenez 		    vp = dumpvp(kd, vp, 0, NULL);
177*aa560c07SAntonio Huete Jimenez     }
178ee173d09SSascha Wildner     printf("}\n");
179*aa560c07SAntonio Huete Jimenez 
180*aa560c07SAntonio Huete Jimenez     /* Per-CPU list of active vnodes */
181ee173d09SSascha Wildner     printf("ACTIVELIST {\n");
182*aa560c07SAntonio Huete Jimenez     for (int i = 0; i < ncpus; i++) {
183*aa560c07SAntonio Huete Jimenez 	    struct vnode *vp;
184*aa560c07SAntonio Huete Jimenez 
185*aa560c07SAntonio Huete Jimenez 	    kkread(kd, (u_long)(vib + i), &vni, sizeof(vni));
186*aa560c07SAntonio Huete Jimenez 	    vp = vni.active_list.tqh_first;
187*aa560c07SAntonio Huete Jimenez 	    for (; vp;)
188*aa560c07SAntonio Huete Jimenez 		    vp = dumpvp(kd, vp, 0,
189*aa560c07SAntonio Huete Jimenez 			NULL);
190*aa560c07SAntonio Huete Jimenez     }
191fa12c626SMatthew Dillon     printf("}\n");
192fa12c626SMatthew Dillon     return(0);
193fa12c626SMatthew Dillon }
194fa12c626SMatthew Dillon 
195fa12c626SMatthew Dillon static struct mount *
dumpmount(kvm_t * kd,struct mount * mp)196fa12c626SMatthew Dillon dumpmount(kvm_t *kd, struct mount *mp)
197fa12c626SMatthew Dillon {
198fa12c626SMatthew Dillon     struct mount mnt;
199fa12c626SMatthew Dillon     struct vnode *vp;
2005e105359SAntonio Huete Jimenez     struct vfsconf vfc;
201fa12c626SMatthew Dillon 
202fa12c626SMatthew Dillon     kkread(kd, (u_long)mp, &mnt, sizeof(mnt));
203fa12c626SMatthew Dillon     printf("MOUNTPOINT %s on %s {\n",
204fa12c626SMatthew Dillon 	mnt.mnt_stat.f_mntfromname, mnt.mnt_stat.f_mntonname);
205fd25e126SAntonio Huete Jimenez     printf("    lk_flags %08x count %016jx holder = %p\n",
206c7ef8fe3SMatthew Dillon 	mnt.mnt_lock.lk_flags, mnt.mnt_lock.lk_count,
207fa12c626SMatthew Dillon 	mnt.mnt_lock.lk_lockholder);
208fa12c626SMatthew Dillon     printf("    mnt_flag %08x mnt_kern_flag %08x\n",
209fa12c626SMatthew Dillon 	mnt.mnt_flag, mnt.mnt_kern_flag);
210fa12c626SMatthew Dillon     printf("    mnt_nvnodelistsize %d\n", mnt.mnt_nvnodelistsize);
2117bc16b2dSMatthew Dillon     printf("    mnt_stat.f_fsid %08x %08x\n", mnt.mnt_stat.f_fsid.val[0],
2127bc16b2dSMatthew Dillon 	mnt.mnt_stat.f_fsid.val[1]);
2135e105359SAntonio Huete Jimenez 
2145e105359SAntonio Huete Jimenez     /* Dump fs private node data */
2155e105359SAntonio Huete Jimenez     kkread(kd, (u_long)mnt.mnt_vfc, &vfc, sizeof(vfc));
216fa12c626SMatthew Dillon     vp = mnt.mnt_nvnodelist.tqh_first;
217fa12c626SMatthew Dillon     while (vp)
2185e105359SAntonio Huete Jimenez 	    vp = dumpvp(kd, vp, 1, vfc.vfc_name);
219fa12c626SMatthew Dillon 
220fa12c626SMatthew Dillon     printf("}\n");
221fa12c626SMatthew Dillon 
222fa12c626SMatthew Dillon     return(mnt.mnt_list.tqe_next);
223fa12c626SMatthew Dillon }
224fa12c626SMatthew Dillon 
225fa12c626SMatthew Dillon static const char *
vtype(enum vtype type)226fa12c626SMatthew Dillon vtype(enum vtype type)
227fa12c626SMatthew Dillon {
228fa12c626SMatthew Dillon     static char buf[32];
229fa12c626SMatthew Dillon 
230fa12c626SMatthew Dillon     switch(type) {
231fa12c626SMatthew Dillon     case VNON:
232fa12c626SMatthew Dillon 	return("VNON");
233fa12c626SMatthew Dillon     case VREG:
234fa12c626SMatthew Dillon 	return("VREG");
235fa12c626SMatthew Dillon     case VDIR:
236fa12c626SMatthew Dillon 	return("VDIR");
237fa12c626SMatthew Dillon     case VBLK:
238fa12c626SMatthew Dillon 	return("VBLK");
239fa12c626SMatthew Dillon     case VCHR:
240fa12c626SMatthew Dillon 	return("VCHR");
241fa12c626SMatthew Dillon     case VLNK:
242fa12c626SMatthew Dillon 	return("VLNK");
243fa12c626SMatthew Dillon     case VSOCK:
244fa12c626SMatthew Dillon 	return("VSOCK");
245fa12c626SMatthew Dillon     case VFIFO:
246fa12c626SMatthew Dillon 	return("VFIFO");
247fa12c626SMatthew Dillon     case VBAD:
248fa12c626SMatthew Dillon 	return("VBAD");
249fa12c626SMatthew Dillon     default:
250fa12c626SMatthew Dillon 	break;
251fa12c626SMatthew Dillon     }
252fa12c626SMatthew Dillon     snprintf(buf, sizeof(buf), "%d", (int)type);
253fa12c626SMatthew Dillon     return(buf);
254fa12c626SMatthew Dillon }
255fa12c626SMatthew Dillon 
256fa12c626SMatthew Dillon static struct vnode *
dumpvp(kvm_t * kd,struct vnode * vp,int whichlist,char * vfc_name)2575e105359SAntonio Huete Jimenez dumpvp(kvm_t *kd, struct vnode *vp, int whichlist, char *vfc_name)
258fa12c626SMatthew Dillon {
259fa12c626SMatthew Dillon     struct vnode vn;
260fa12c626SMatthew Dillon 
261fa12c626SMatthew Dillon     kkread(kd, (u_long)vp, &vn, sizeof(vn));
262fa12c626SMatthew Dillon 
263ee173d09SSascha Wildner     printf("    vnode %p.%d refcnt %08x auxcnt %d type=%s flags %08x",
264ee173d09SSascha Wildner 	vp, vn.v_state, vn.v_refcnt, vn.v_auxrefs, vtype(vn.v_type), vn.v_flag);
26517ba2e5aSMatthew Dillon 
26617ba2e5aSMatthew Dillon     if ((vn.v_flag & VOBJBUF) && vn.v_object) {
26717ba2e5aSMatthew Dillon 	int npages = getobjpages(kd, vn.v_object);
268ada41611SMatthew Dillon 	int vnpsize = getobjvnpsize(kd, vn.v_object);
269ada41611SMatthew Dillon 	if (npages || vnpsize)
270ada41611SMatthew Dillon 	    printf(" vmobjpgs=%d vnpsize=%d", npages, vnpsize);
27117ba2e5aSMatthew Dillon     }
27217ba2e5aSMatthew Dillon 
273fa12c626SMatthew Dillon     if (vn.v_flag & VROOT)
27445136f35SMatthew Dillon 	printf(" VROOT");
275fa12c626SMatthew Dillon     if (vn.v_flag & VTEXT)
27645136f35SMatthew Dillon 	printf(" VTEXT");
277fa12c626SMatthew Dillon     if (vn.v_flag & VSYSTEM)
27845136f35SMatthew Dillon 	printf(" VSYSTEM");
279fa12c626SMatthew Dillon     if (vn.v_flag & VISTTY)
28045136f35SMatthew Dillon 	printf(" VISTTY");
28145136f35SMatthew Dillon #ifdef VXLOCK
282fa12c626SMatthew Dillon     if (vn.v_flag & VXLOCK)
28345136f35SMatthew Dillon 	printf(" VXLOCK");
284fa12c626SMatthew Dillon     if (vn.v_flag & VXWANT)
28545136f35SMatthew Dillon 	printf(" VXWANT");
28645136f35SMatthew Dillon #endif
28745136f35SMatthew Dillon #ifdef VRECLAIMED
28845136f35SMatthew Dillon     if (vn.v_flag & VRECLAIMED)
28945136f35SMatthew Dillon 	printf(" VRECLAIMED");
29045136f35SMatthew Dillon     if (vn.v_flag & VINACTIVE)
29145136f35SMatthew Dillon 	printf(" VINACTIVE");
29245136f35SMatthew Dillon #endif
293fa12c626SMatthew Dillon     if (vn.v_flag & VOBJBUF)
29445136f35SMatthew Dillon 	printf(" VOBJBUF");
295aabd5ce8SMatthew Dillon #ifdef VSWAPCACHE
296aabd5ce8SMatthew Dillon     if (vn.v_flag & VSWAPCACHE)
297aabd5ce8SMatthew Dillon 	printf(" VSWAPCACHE");
298aabd5ce8SMatthew Dillon #endif
2990e8bd897SMatthew Dillon     switch(vn.v_flag & (VAGE0 | VAGE1)) {
3000e8bd897SMatthew Dillon     case 0:
3010e8bd897SMatthew Dillon 	printf(" VAGE0");
3020e8bd897SMatthew Dillon 	break;
3030e8bd897SMatthew Dillon     case VAGE0:
3040e8bd897SMatthew Dillon 	printf(" VAGE1");
3050e8bd897SMatthew Dillon 	break;
3060e8bd897SMatthew Dillon     case VAGE1:
3070e8bd897SMatthew Dillon 	printf(" VAGE2");
3080e8bd897SMatthew Dillon 	break;
3090e8bd897SMatthew Dillon     case VAGE0 | VAGE1:
3100e8bd897SMatthew Dillon 	printf(" VAGE3");
3110e8bd897SMatthew Dillon 	break;
3120e8bd897SMatthew Dillon     }
31345136f35SMatthew Dillon #ifdef VDOOMED
314fa12c626SMatthew Dillon     if (vn.v_flag & VDOOMED)
31545136f35SMatthew Dillon 	printf(" VDOOMED");
31645136f35SMatthew Dillon #endif
31745136f35SMatthew Dillon #ifdef VINFREE
318fa12c626SMatthew Dillon     if (vn.v_flag & VINFREE)
31945136f35SMatthew Dillon 	printf(" VINFREE");
32045136f35SMatthew Dillon #endif
321fa12c626SMatthew Dillon     if (vn.v_flag & VONWORKLST)
32245136f35SMatthew Dillon 	printf(" VONWORKLST");
323fa12c626SMatthew Dillon     if (vn.v_flag & VOBJDIRTY)
32445136f35SMatthew Dillon 	printf(" VOBJDIRTY");
3253661e25dSMatthew Dillon     if (vn.v_flag & VMAYHAVELOCKS)
3263661e25dSMatthew Dillon 	printf(" VMAYHAVELOCKS");
32717ba2e5aSMatthew Dillon 
328fa12c626SMatthew Dillon     printf("\n");
329fa12c626SMatthew Dillon 
330fd25e126SAntonio Huete Jimenez     if (vn.v_lock.lk_count || vn.v_lock.lk_lockholder != NULL) {
331fd25e126SAntonio Huete Jimenez 	printf("\tlk_flags %08x count %016jx holder = %p\n",
332c7ef8fe3SMatthew Dillon 	    vn.v_lock.lk_flags, vn.v_lock.lk_count,
333fa12c626SMatthew Dillon 	    vn.v_lock.lk_lockholder);
334fa12c626SMatthew Dillon     }
335fa12c626SMatthew Dillon 
336bb87550cSMatthew Dillon     if (withnames && TAILQ_FIRST(&vn.v_namecache)) {
337bb87550cSMatthew Dillon 	struct namecache ncp;
338bb87550cSMatthew Dillon 	int nlen;
339bb87550cSMatthew Dillon 	char buf[1024];
340bb87550cSMatthew Dillon 
341bb87550cSMatthew Dillon 	kkread(kd, (u_long)TAILQ_FIRST(&vn.v_namecache), &ncp, sizeof(ncp));
342bb87550cSMatthew Dillon 	if ((nlen = ncp.nc_nlen) >= sizeof(buf))
343bb87550cSMatthew Dillon 		nlen = sizeof(buf) - 1;
344bb87550cSMatthew Dillon 	if (nlen < 0)
345bb87550cSMatthew Dillon 		nlen = 0;
346bb87550cSMatthew Dillon 	if (nlen) {
347bb87550cSMatthew Dillon 		kkread(kd, (u_long)ncp.nc_name, buf, nlen);
348bb87550cSMatthew Dillon 		buf[nlen] = 0;
349bb87550cSMatthew Dillon 		printf("\tfilename %s\n", buf);
350bb87550cSMatthew Dillon 	}
351bb87550cSMatthew Dillon     }
352bb87550cSMatthew Dillon 
353af456e64SMatthew Dillon     if (tracebufs) {
354af456e64SMatthew Dillon 	if (vn.v_rbclean_tree.rbh_root) {
355af456e64SMatthew Dillon 	    printf("\tCLEAN BUFFERS\n");
356af456e64SMatthew Dillon 	    dumpbufs(kd, vn.v_rbclean_tree.rbh_root, "ROOT");
357af456e64SMatthew Dillon 	}
358af456e64SMatthew Dillon 	if (vn.v_rbdirty_tree.rbh_root) {
359af456e64SMatthew Dillon 	    printf("\tDIRTY BUFFERS\n");
360af456e64SMatthew Dillon 	    dumpbufs(kd, vn.v_rbdirty_tree.rbh_root, "ROOT");
361af456e64SMatthew Dillon 	}
362af456e64SMatthew Dillon     }
363af456e64SMatthew Dillon 
3643661e25dSMatthew Dillon     if (tracelocks) {
3653661e25dSMatthew Dillon 	if (vn.v_tag == VT_UFS && vn.v_data) {
3663661e25dSMatthew Dillon 	    struct inode *ip = vn.v_data;
3673661e25dSMatthew Dillon 	    struct lockf lockf;
3683661e25dSMatthew Dillon 
3693661e25dSMatthew Dillon 	    kkread(kd, (u_long)&ip->i_lockf, &lockf, sizeof(lockf));
3703661e25dSMatthew Dillon 	    dumplocks(kd, &lockf);
3713661e25dSMatthew Dillon 	}
3723661e25dSMatthew Dillon     }
3733661e25dSMatthew Dillon 
3745e105359SAntonio Huete Jimenez     if (fsprivate && vfc_name) {
3755e105359SAntonio Huete Jimenez 	    /*
3765e105359SAntonio Huete Jimenez 	     * Actually find whether the filesystem can dump
3775e105359SAntonio Huete Jimenez 	     * detailed inode information out of the vnode
3785e105359SAntonio Huete Jimenez 	     */
3795e105359SAntonio Huete Jimenez 	    const struct dump_private_data *dpd;
3805e105359SAntonio Huete Jimenez 
3815e105359SAntonio Huete Jimenez 	    for (dpd = dumplist; dpd->dumpfn != NULL; dpd++) {
3825e105359SAntonio Huete Jimenez 		    if ((strcmp(dpd->vfc_name, vfc_name) == 0) &&
3835e105359SAntonio Huete Jimenez 			vn.v_data != NULL)
3845e105359SAntonio Huete Jimenez 			    dpd->dumpfn(kd, vn.v_data);
3855e105359SAntonio Huete Jimenez 	    }
3865e105359SAntonio Huete Jimenez     }
3873661e25dSMatthew Dillon 
388fa12c626SMatthew Dillon     if (whichlist)
389fa12c626SMatthew Dillon 	return(vn.v_nmntvnodes.tqe_next);
390fa12c626SMatthew Dillon     else
391ee173d09SSascha Wildner 	return(vn.v_list.tqe_next);
392fa12c626SMatthew Dillon }
393fa12c626SMatthew Dillon 
394af456e64SMatthew Dillon static void
dumpbufs(kvm_t * kd,void * bufp,const char * id)395af456e64SMatthew Dillon dumpbufs(kvm_t *kd, void *bufp, const char *id)
396af456e64SMatthew Dillon {
397af456e64SMatthew Dillon 	struct buf buf;
398af456e64SMatthew Dillon 
399af456e64SMatthew Dillon 	kkread(kd, (u_long)bufp, &buf, sizeof(buf));
400b7cb6098SMatthew Dillon 	printf("\t    %-8s %p loffset %012lx/%05x foffset %08lx",
401af456e64SMatthew Dillon 		id, bufp,
402e36e284dSMatthew Dillon 		buf.b_bio1.bio_offset,
403a5ef8e88SMatthew Dillon 		buf.b_bufsize,
404e36e284dSMatthew Dillon 		buf.b_bio2.bio_offset);
405fd25e126SAntonio Huete Jimenez 	printf(" q=%d count=%016jx flags=%08x refs=%08x dep=%p",
406c7ef8fe3SMatthew Dillon 		buf.b_qindex, buf.b_lock.lk_count,
407adcc77efSMatthew Dillon 		buf.b_flags, buf.b_refs, buf.b_dep.lh_first);
408fa06bda9SMatthew Dillon 	printf("\n");
409af456e64SMatthew Dillon 
410af456e64SMatthew Dillon 	if (buf.b_rbnode.rbe_left)
411af456e64SMatthew Dillon 	    dumpbufs(kd, buf.b_rbnode.rbe_left, "LEFT");
412af456e64SMatthew Dillon 	if (buf.b_rbnode.rbe_right)
413af456e64SMatthew Dillon 	    dumpbufs(kd, buf.b_rbnode.rbe_right, "RIGHT");
414af456e64SMatthew Dillon }
415af456e64SMatthew Dillon 
4163661e25dSMatthew Dillon static void
dumplocks(kvm_t * kd,struct lockf * lockf)4173661e25dSMatthew Dillon dumplocks(kvm_t *kd, struct lockf *lockf)
4183661e25dSMatthew Dillon {
4193661e25dSMatthew Dillon 	struct lockf_range item;
4203661e25dSMatthew Dillon 	struct lockf_range *scan;
4213661e25dSMatthew Dillon 
4223661e25dSMatthew Dillon 	if ((scan = TAILQ_FIRST(&lockf->lf_range)) != NULL) {
4233661e25dSMatthew Dillon 		printf("\tLOCKS\n");
4243661e25dSMatthew Dillon 		do {
4253661e25dSMatthew Dillon 			kkread(kd, (u_long)scan, &item, sizeof(item));
4263661e25dSMatthew Dillon 			dumplockinfo(kd, &item);
4273661e25dSMatthew Dillon 		} while ((scan = TAILQ_NEXT(&item, lf_link)) != NULL);
4283661e25dSMatthew Dillon 		printf("\n");
4293661e25dSMatthew Dillon 	}
4303661e25dSMatthew Dillon 	if ((scan = TAILQ_FIRST(&lockf->lf_blocked)) != NULL) {
4313661e25dSMatthew Dillon 		printf("\tBLKED\n");
4323661e25dSMatthew Dillon 		do {
4333661e25dSMatthew Dillon 			kkread(kd, (u_long)scan, &item, sizeof(item));
4343661e25dSMatthew Dillon 			dumplockinfo(kd, &item);
4353661e25dSMatthew Dillon 		} while ((scan = TAILQ_NEXT(&item, lf_link)) != NULL);
4363661e25dSMatthew Dillon 		printf("\n");
4373661e25dSMatthew Dillon 	}
4383661e25dSMatthew Dillon 
4393661e25dSMatthew Dillon }
4403661e25dSMatthew Dillon 
4413661e25dSMatthew Dillon static void
dumplockinfo(kvm_t * kd,struct lockf_range * item)4423661e25dSMatthew Dillon dumplockinfo(kvm_t *kd, struct lockf_range *item)
4433661e25dSMatthew Dillon {
4443661e25dSMatthew Dillon 	int ownerpid;
4453661e25dSMatthew Dillon 
4463661e25dSMatthew Dillon 	if (item->lf_owner && (item->lf_flags & F_POSIX)) {
4473661e25dSMatthew Dillon 		kkread(kd, (u_long)&item->lf_owner->p_pid,
4483661e25dSMatthew Dillon 			&ownerpid, sizeof(ownerpid));
4493661e25dSMatthew Dillon 	} else {
4503661e25dSMatthew Dillon 		ownerpid = -1;
4513661e25dSMatthew Dillon 	}
4523661e25dSMatthew Dillon 
453b7cb6098SMatthew Dillon 	printf("\t    ty=%d flgs=%04x %ld-%ld owner=%d\n",
4543661e25dSMatthew Dillon 		item->lf_type, item->lf_flags,
4553661e25dSMatthew Dillon 		item->lf_start, item->lf_end,
4563661e25dSMatthew Dillon 		ownerpid
4573661e25dSMatthew Dillon 	);
4583661e25dSMatthew Dillon }
4593661e25dSMatthew Dillon 
46017ba2e5aSMatthew Dillon static
46117ba2e5aSMatthew Dillon int
getobjpages(kvm_t * kd,struct vm_object * obj)46217ba2e5aSMatthew Dillon getobjpages(kvm_t *kd, struct vm_object *obj)
46317ba2e5aSMatthew Dillon {
46417ba2e5aSMatthew Dillon 	struct vm_object vmobj;
46517ba2e5aSMatthew Dillon 
46617ba2e5aSMatthew Dillon 	kkread(kd, (u_long)obj, &vmobj, sizeof(vmobj));
46717ba2e5aSMatthew Dillon 	return(vmobj.resident_page_count);
46817ba2e5aSMatthew Dillon }
46917ba2e5aSMatthew Dillon 
470ada41611SMatthew Dillon static
471ada41611SMatthew Dillon int
getobjvnpsize(kvm_t * kd,struct vm_object * obj)472ada41611SMatthew Dillon getobjvnpsize(kvm_t *kd, struct vm_object *obj)
473ada41611SMatthew Dillon {
474ada41611SMatthew Dillon 	struct vm_object vmobj;
475ada41611SMatthew Dillon 
476ada41611SMatthew Dillon 	kkread(kd, (u_long)obj, &vmobj, sizeof(vmobj));
477e36e284dSMatthew Dillon 	return ((int)vmobj.size);
478ada41611SMatthew Dillon }
479ada41611SMatthew Dillon 
48017ba2e5aSMatthew Dillon static void
kkread(kvm_t * kd,u_long addr,void * buf,size_t nbytes)481fa12c626SMatthew Dillon kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
482fa12c626SMatthew Dillon {
483fa12c626SMatthew Dillon     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
484fa12c626SMatthew Dillon         perror("kvm_read");
485fa12c626SMatthew Dillon         exit(1);
486fa12c626SMatthew Dillon     }
487fa12c626SMatthew Dillon }
488