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