xref: /dragonfly/test/debug/vnodeinfo.c (revision 5c8e2a54)
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  *
10*5c8e2a54SMatthew Dillon  *
11*5c8e2a54SMatthew Dillon  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
12*5c8e2a54SMatthew Dillon  *
13*5c8e2a54SMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
14*5c8e2a54SMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
15*5c8e2a54SMatthew Dillon  *
16*5c8e2a54SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
17*5c8e2a54SMatthew Dillon  * modification, are permitted provided that the following conditions
18*5c8e2a54SMatthew Dillon  * are met:
19*5c8e2a54SMatthew Dillon  *
20*5c8e2a54SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
21*5c8e2a54SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
22*5c8e2a54SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
23*5c8e2a54SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
24*5c8e2a54SMatthew Dillon  *    the documentation and/or other materials provided with the
25*5c8e2a54SMatthew Dillon  *    distribution.
26*5c8e2a54SMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
27*5c8e2a54SMatthew Dillon  *    contributors may be used to endorse or promote products derived
28*5c8e2a54SMatthew Dillon  *    from this software without specific, prior written permission.
29*5c8e2a54SMatthew Dillon  *
30*5c8e2a54SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31*5c8e2a54SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32*5c8e2a54SMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33*5c8e2a54SMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
34*5c8e2a54SMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35*5c8e2a54SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
36*5c8e2a54SMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37*5c8e2a54SMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
38*5c8e2a54SMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39*5c8e2a54SMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
40*5c8e2a54SMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41*5c8e2a54SMatthew Dillon  * SUCH DAMAGE.
42*5c8e2a54SMatthew Dillon  *
43*5c8e2a54SMatthew Dillon  * $DragonFly: src/test/debug/vnodeinfo.c,v 1.3 2004/10/08 18:32:58 dillon Exp $
44fa12c626SMatthew Dillon  */
45fa12c626SMatthew Dillon 
46fa12c626SMatthew Dillon #define _KERNEL_STRUCTURES_
47fa12c626SMatthew Dillon #include <sys/param.h>
48fa12c626SMatthew Dillon #include <sys/user.h>
49fa12c626SMatthew Dillon #include <sys/malloc.h>
50fa12c626SMatthew Dillon #include <sys/signalvar.h>
51fa12c626SMatthew Dillon #include <sys/mount.h>
52fa12c626SMatthew Dillon #include <sys/vnode.h>
53fa12c626SMatthew Dillon 
54fa12c626SMatthew Dillon #include <vm/vm.h>
55fa12c626SMatthew Dillon #include <vm/vm_page.h>
56fa12c626SMatthew Dillon #include <vm/vm_kern.h>
57fa12c626SMatthew Dillon #include <vm/swap_pager.h>
58fa12c626SMatthew Dillon #include <vm/vnode_pager.h>
59fa12c626SMatthew Dillon 
60fa12c626SMatthew Dillon #include <stdio.h>
61fa12c626SMatthew Dillon #include <stdlib.h>
62fa12c626SMatthew Dillon #include <string.h>
63fa12c626SMatthew Dillon #include <fcntl.h>
64fa12c626SMatthew Dillon #include <kvm.h>
65fa12c626SMatthew Dillon #include <nlist.h>
66fa12c626SMatthew Dillon #include <getopt.h>
67fa12c626SMatthew Dillon 
68fa12c626SMatthew Dillon struct nlist Nl[] = {
69fa12c626SMatthew Dillon     { "_mountlist" },
70fa12c626SMatthew Dillon     { "_vnode_free_list" },
71fa12c626SMatthew Dillon     { NULL }
72fa12c626SMatthew Dillon };
73fa12c626SMatthew Dillon 
74fa12c626SMatthew Dillon static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
75fa12c626SMatthew Dillon static struct mount *dumpmount(kvm_t *kd, struct mount *mp);
76fa12c626SMatthew Dillon static struct vnode *dumpvp(kvm_t *kd, struct vnode *vp, int whichlist);
77fa12c626SMatthew Dillon 
78fa12c626SMatthew Dillon main(int ac, char **av)
79fa12c626SMatthew Dillon {
80fa12c626SMatthew Dillon     struct mount *mp;
81fa12c626SMatthew Dillon     struct vnode *vp;
82fa12c626SMatthew Dillon     kvm_t *kd;
83fa12c626SMatthew Dillon     int i;
84fa12c626SMatthew Dillon     int ch;
85fa12c626SMatthew Dillon     const char *corefile = NULL;
86fa12c626SMatthew Dillon     const char *sysfile = NULL;
87fa12c626SMatthew Dillon 
88fa12c626SMatthew Dillon     while ((ch = getopt(ac, av, "M:N:")) != -1) {
89fa12c626SMatthew Dillon 	switch(ch) {
90fa12c626SMatthew Dillon 	case 'M':
91fa12c626SMatthew Dillon 	    corefile = optarg;
92fa12c626SMatthew Dillon 	    break;
93fa12c626SMatthew Dillon 	case 'N':
94fa12c626SMatthew Dillon 	    sysfile = optarg;
95fa12c626SMatthew Dillon 	    break;
96fa12c626SMatthew Dillon 	default:
97fa12c626SMatthew Dillon 	    fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
98fa12c626SMatthew Dillon 	    exit(1);
99fa12c626SMatthew Dillon 	}
100fa12c626SMatthew Dillon     }
101fa12c626SMatthew Dillon 
102fa12c626SMatthew Dillon     if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
103fa12c626SMatthew Dillon 	perror("kvm_open");
104fa12c626SMatthew Dillon 	exit(1);
105fa12c626SMatthew Dillon     }
106fa12c626SMatthew Dillon     if (kvm_nlist(kd, Nl) != 0) {
107fa12c626SMatthew Dillon 	perror("kvm_nlist");
108fa12c626SMatthew Dillon 	exit(1);
109fa12c626SMatthew Dillon     }
110fa12c626SMatthew Dillon     kkread(kd, Nl[0].n_value, &mp, sizeof(mp));
111fa12c626SMatthew Dillon     while (mp)
112fa12c626SMatthew Dillon 	mp = dumpmount(kd, mp);
113fa12c626SMatthew Dillon     kkread(kd, Nl[1].n_value, &vp, sizeof(vp));
114fa12c626SMatthew Dillon     printf("VNODEFREELIST {\n");
115fa12c626SMatthew Dillon     while (vp)
116fa12c626SMatthew Dillon 	vp = dumpvp(kd, vp, 0);
117fa12c626SMatthew Dillon     printf("}\n");
118fa12c626SMatthew Dillon     return(0);
119fa12c626SMatthew Dillon }
120fa12c626SMatthew Dillon 
121fa12c626SMatthew Dillon static struct mount *
122fa12c626SMatthew Dillon dumpmount(kvm_t *kd, struct mount *mp)
123fa12c626SMatthew Dillon {
124fa12c626SMatthew Dillon     struct mount mnt;
125fa12c626SMatthew Dillon     struct vnode *vp;
126fa12c626SMatthew Dillon 
127fa12c626SMatthew Dillon     kkread(kd, (u_long)mp, &mnt, sizeof(mnt));
128fa12c626SMatthew Dillon     printf("MOUNTPOINT %s on %s {\n",
129fa12c626SMatthew Dillon 	mnt.mnt_stat.f_mntfromname, mnt.mnt_stat.f_mntonname);
130fa12c626SMatthew Dillon     printf("    lk_flags %08x share %d wait %d excl %d holder = %p\n",
131fa12c626SMatthew Dillon 	mnt.mnt_lock.lk_flags, mnt.mnt_lock.lk_sharecount,
132fa12c626SMatthew Dillon 	mnt.mnt_lock.lk_waitcount, mnt.mnt_lock.lk_exclusivecount,
133fa12c626SMatthew Dillon 	mnt.mnt_lock.lk_lockholder);
134fa12c626SMatthew Dillon     printf("    mnt_flag %08x mnt_kern_flag %08x\n",
135fa12c626SMatthew Dillon 	mnt.mnt_flag, mnt.mnt_kern_flag);
136fa12c626SMatthew Dillon     printf("    mnt_nvnodelistsize %d\n", mnt.mnt_nvnodelistsize);
137fa12c626SMatthew Dillon     vp = mnt.mnt_nvnodelist.tqh_first;
138fa12c626SMatthew Dillon     while (vp)
139fa12c626SMatthew Dillon 	vp = dumpvp(kd, vp, 1);
140fa12c626SMatthew Dillon 
141fa12c626SMatthew Dillon     printf("}\n");
142fa12c626SMatthew Dillon 
143fa12c626SMatthew Dillon     return(mnt.mnt_list.tqe_next);
144fa12c626SMatthew Dillon }
145fa12c626SMatthew Dillon 
146fa12c626SMatthew Dillon static const char *
147fa12c626SMatthew Dillon vtype(enum vtype type)
148fa12c626SMatthew Dillon {
149fa12c626SMatthew Dillon     static char buf[32];
150fa12c626SMatthew Dillon 
151fa12c626SMatthew Dillon     switch(type) {
152fa12c626SMatthew Dillon     case VNON:
153fa12c626SMatthew Dillon 	return("VNON");
154fa12c626SMatthew Dillon     case VREG:
155fa12c626SMatthew Dillon 	return("VREG");
156fa12c626SMatthew Dillon     case VDIR:
157fa12c626SMatthew Dillon 	return("VDIR");
158fa12c626SMatthew Dillon     case VBLK:
159fa12c626SMatthew Dillon 	return("VBLK");
160fa12c626SMatthew Dillon     case VCHR:
161fa12c626SMatthew Dillon 	return("VCHR");
162fa12c626SMatthew Dillon     case VLNK:
163fa12c626SMatthew Dillon 	return("VLNK");
164fa12c626SMatthew Dillon     case VSOCK:
165fa12c626SMatthew Dillon 	return("VSOCK");
166fa12c626SMatthew Dillon     case VFIFO:
167fa12c626SMatthew Dillon 	return("VFIFO");
168fa12c626SMatthew Dillon     case VBAD:
169fa12c626SMatthew Dillon 	return("VBAD");
170fa12c626SMatthew Dillon     default:
171fa12c626SMatthew Dillon 	break;
172fa12c626SMatthew Dillon     }
173fa12c626SMatthew Dillon     snprintf(buf, sizeof(buf), "%d", (int)type);
174fa12c626SMatthew Dillon     return(buf);
175fa12c626SMatthew Dillon }
176fa12c626SMatthew Dillon 
177fa12c626SMatthew Dillon static struct vnode *
178fa12c626SMatthew Dillon dumpvp(kvm_t *kd, struct vnode *vp, int whichlist)
179fa12c626SMatthew Dillon {
180fa12c626SMatthew Dillon     struct vnode vn;
181fa12c626SMatthew Dillon 
182fa12c626SMatthew Dillon     kkread(kd, (u_long)vp, &vn, sizeof(vn));
183fa12c626SMatthew Dillon 
184fa12c626SMatthew Dillon     printf("    vnode %p usecnt %d holdcnt %d type=%s flags %08x",
185fa12c626SMatthew Dillon 	vp, vn.v_usecount, vn.v_holdcnt, vtype(vn.v_type), vn.v_flag);
186fa12c626SMatthew Dillon     if (vn.v_flag & VROOT)
18745136f35SMatthew Dillon 	printf(" VROOT");
188fa12c626SMatthew Dillon     if (vn.v_flag & VTEXT)
18945136f35SMatthew Dillon 	printf(" VTEXT");
190fa12c626SMatthew Dillon     if (vn.v_flag & VSYSTEM)
19145136f35SMatthew Dillon 	printf(" VSYSTEM");
192fa12c626SMatthew Dillon     if (vn.v_flag & VISTTY)
19345136f35SMatthew Dillon 	printf(" VISTTY");
19445136f35SMatthew Dillon #ifdef VXLOCK
195fa12c626SMatthew Dillon     if (vn.v_flag & VXLOCK)
19645136f35SMatthew Dillon 	printf(" VXLOCK");
197fa12c626SMatthew Dillon     if (vn.v_flag & VXWANT)
19845136f35SMatthew Dillon 	printf(" VXWANT");
19945136f35SMatthew Dillon #endif
20045136f35SMatthew Dillon #ifdef VRECLAIMED
20145136f35SMatthew Dillon     if (vn.v_flag & VRECLAIMED)
20245136f35SMatthew Dillon 	printf(" VRECLAIMED");
20345136f35SMatthew Dillon     if (vn.v_flag & VINACTIVE)
20445136f35SMatthew Dillon 	printf(" VINACTIVE");
20545136f35SMatthew Dillon #endif
206fa12c626SMatthew Dillon     if (vn.v_flag & VBWAIT)
20745136f35SMatthew Dillon 	printf(" VBWAIT");
208fa12c626SMatthew Dillon     if (vn.v_flag & VOBJBUF)
20945136f35SMatthew Dillon 	printf(" VOBJBUF");
210fa12c626SMatthew Dillon     if (vn.v_flag & VAGE)
21145136f35SMatthew Dillon 	printf(" VAGE");
212fa12c626SMatthew Dillon     if (vn.v_flag & VOLOCK)
21345136f35SMatthew Dillon 	printf(" VOLOCK");
214fa12c626SMatthew Dillon     if (vn.v_flag & VOWANT)
21545136f35SMatthew Dillon 	printf(" VOWANT");
21645136f35SMatthew Dillon #ifdef VDOOMED
217fa12c626SMatthew Dillon     if (vn.v_flag & VDOOMED)
21845136f35SMatthew Dillon 	printf(" VDOOMED");
21945136f35SMatthew Dillon #endif
220fa12c626SMatthew Dillon     if (vn.v_flag & VFREE)
22145136f35SMatthew Dillon 	printf(" VFREE");
22245136f35SMatthew Dillon #ifdef VINFREE
223fa12c626SMatthew Dillon     if (vn.v_flag & VINFREE)
22445136f35SMatthew Dillon 	printf(" VINFREE");
22545136f35SMatthew Dillon #endif
226fa12c626SMatthew Dillon     if (vn.v_flag & VONWORKLST)
22745136f35SMatthew Dillon 	printf(" VONWORKLST");
228fa12c626SMatthew Dillon     if (vn.v_flag & VMOUNT)
22945136f35SMatthew Dillon 	printf(" VMOUNT");
230fa12c626SMatthew Dillon     if (vn.v_flag & VOBJDIRTY)
23145136f35SMatthew Dillon 	printf(" VOBJDIRTY");
232fa12c626SMatthew Dillon     if (vn.v_flag & VPLACEMARKER)
23345136f35SMatthew Dillon 	printf(" VPLACEMARKER");
234fa12c626SMatthew Dillon     printf("\n");
235fa12c626SMatthew Dillon 
236fa12c626SMatthew Dillon     if (vn.v_lock.lk_sharecount || vn.v_lock.lk_waitcount ||
237fa12c626SMatthew Dillon 	vn.v_lock.lk_exclusivecount || vn.v_lock.lk_lockholder != LK_NOTHREAD) {
238fa12c626SMatthew Dillon 	printf("\tlk_flags %08x share %d wait %d excl %d holder = %p\n",
239fa12c626SMatthew Dillon 	    vn.v_lock.lk_flags, vn.v_lock.lk_sharecount,
240fa12c626SMatthew Dillon 	    vn.v_lock.lk_waitcount, vn.v_lock.lk_exclusivecount,
241fa12c626SMatthew Dillon 	    vn.v_lock.lk_lockholder);
242fa12c626SMatthew Dillon     }
243fa12c626SMatthew Dillon 
244fa12c626SMatthew Dillon     if (whichlist)
245fa12c626SMatthew Dillon 	return(vn.v_nmntvnodes.tqe_next);
246fa12c626SMatthew Dillon     else
247fa12c626SMatthew Dillon 	return(vn.v_freelist.tqe_next);
248fa12c626SMatthew Dillon }
249fa12c626SMatthew Dillon 
250fa12c626SMatthew Dillon void
251fa12c626SMatthew Dillon kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
252fa12c626SMatthew Dillon {
253fa12c626SMatthew Dillon     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
254fa12c626SMatthew Dillon         perror("kvm_read");
255fa12c626SMatthew Dillon         exit(1);
256fa12c626SMatthew Dillon     }
257fa12c626SMatthew Dillon }
258fa12c626SMatthew Dillon 
259