4 * cc -I/usr/src/sys vnodeinfo.c -o /usr/local/bin/vnodeinfo -lkvm
8 * Dump the mountlist and related vnodes.
10 * $DragonFly: src/test/debug/vnodeinfo.c,v 1.1 2004/10/07 00:05:03 dillon Exp $
13 #define _KERNEL_STRUCTURES_
14 #include <sys/param.h>
16 #include <sys/malloc.h>
17 #include <sys/signalvar.h>
18 #include <sys/mount.h>
19 #include <sys/vnode.h>
22 #include <vm/vm_page.h>
23 #include <vm/vm_kern.h>
24 #include <vm/swap_pager.h>
25 #include <vm/vnode_pager.h>
37 { "_vnode_free_list" },
41 static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
42 static struct mount *dumpmount(kvm_t *kd, struct mount *mp);
43 static struct vnode *dumpvp(kvm_t *kd, struct vnode *vp, int whichlist);
45 main(int ac, char **av)
52 const char *corefile = NULL;
53 const char *sysfile = NULL;
55 while ((ch = getopt(ac, av, "M:N:")) != -1) {
64 fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
69 if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
73 if (kvm_nlist(kd, Nl) != 0) {
77 kkread(kd, Nl[0].n_value, &mp, sizeof(mp));
79 mp = dumpmount(kd, mp);
80 kkread(kd, Nl[1].n_value, &vp, sizeof(vp));
81 printf("VNODEFREELIST {\n");
83 vp = dumpvp(kd, vp, 0);
89 dumpmount(kvm_t *kd, struct mount *mp)
94 kkread(kd, (u_long)mp, &mnt, sizeof(mnt));
95 printf("MOUNTPOINT %s on %s {\n",
96 mnt.mnt_stat.f_mntfromname, mnt.mnt_stat.f_mntonname);
97 printf(" lk_flags %08x share %d wait %d excl %d holder = %p\n",
98 mnt.mnt_lock.lk_flags, mnt.mnt_lock.lk_sharecount,
99 mnt.mnt_lock.lk_waitcount, mnt.mnt_lock.lk_exclusivecount,
100 mnt.mnt_lock.lk_lockholder);
101 printf(" mnt_flag %08x mnt_kern_flag %08x\n",
102 mnt.mnt_flag, mnt.mnt_kern_flag);
103 printf(" mnt_nvnodelistsize %d\n", mnt.mnt_nvnodelistsize);
104 vp = mnt.mnt_nvnodelist.tqh_first;
106 vp = dumpvp(kd, vp, 1);
110 return(mnt.mnt_list.tqe_next);
114 vtype(enum vtype type)
140 snprintf(buf, sizeof(buf), "%d", (int)type);
144 static struct vnode *
145 dumpvp(kvm_t *kd, struct vnode *vp, int whichlist)
149 kkread(kd, (u_long)vp, &vn, sizeof(vn));
151 printf(" vnode %p usecnt %d holdcnt %d type=%s flags %08x",
152 vp, vn.v_usecount, vn.v_holdcnt, vtype(vn.v_type), vn.v_flag);
153 if (vn.v_flag & VROOT)
155 if (vn.v_flag & VTEXT)
157 if (vn.v_flag & VSYSTEM)
159 if (vn.v_flag & VISTTY)
161 if (vn.v_flag & VXLOCK)
163 if (vn.v_flag & VXWANT)
165 if (vn.v_flag & VBWAIT)
167 if (vn.v_flag & VOBJBUF)
169 if (vn.v_flag & VAGE)
171 if (vn.v_flag & VOLOCK)
173 if (vn.v_flag & VOWANT)
175 if (vn.v_flag & VDOOMED)
177 if (vn.v_flag & VFREE)
179 if (vn.v_flag & VINFREE)
181 if (vn.v_flag & VONWORKLST)
182 printf(" ONWORKLST");
183 if (vn.v_flag & VMOUNT)
185 if (vn.v_flag & VOBJDIRTY)
187 if (vn.v_flag & VPLACEMARKER)
188 printf(" PLACEMARKER");
191 if (vn.v_lock.lk_sharecount || vn.v_lock.lk_waitcount ||
192 vn.v_lock.lk_exclusivecount || vn.v_lock.lk_lockholder != LK_NOTHREAD) {
193 printf("\tlk_flags %08x share %d wait %d excl %d holder = %p\n",
194 vn.v_lock.lk_flags, vn.v_lock.lk_sharecount,
195 vn.v_lock.lk_waitcount, vn.v_lock.lk_exclusivecount,
196 vn.v_lock.lk_lockholder);
200 return(vn.v_nmntvnodes.tqe_next);
202 return(vn.v_freelist.tqe_next);
206 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
208 if (kvm_read(kd, addr, buf, nbytes) != nbytes) {