diff options
author | phk <phk@FreeBSD.org> | 1997-09-04 08:28:55 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1997-09-04 08:28:55 +0000 |
commit | 9a333abb93f0a94f2fc4d523ffa9c31e6cc0f204 (patch) | |
tree | 3346cd0f5fb86d288dfb0a2a9fd6040d957ecfc5 /tools/diag | |
parent | 775942111e5470deca3e270fca7d40b48c436e90 (diff) | |
download | FreeBSD-src-9a333abb93f0a94f2fc4d523ffa9c31e6cc0f204.zip FreeBSD-src-9a333abb93f0a94f2fc4d523ffa9c31e6cc0f204.tar.gz |
A little gadget to dump the contents of the vfs name cache.
Diffstat (limited to 'tools/diag')
-rw-r--r-- | tools/diag/dumpvfscache/Makefile | 11 | ||||
-rw-r--r-- | tools/diag/dumpvfscache/README | 6 | ||||
-rw-r--r-- | tools/diag/dumpvfscache/dumpvfscache.c | 120 |
3 files changed, 137 insertions, 0 deletions
diff --git a/tools/diag/dumpvfscache/Makefile b/tools/diag/dumpvfscache/Makefile new file mode 100644 index 0000000..a9299ce --- /dev/null +++ b/tools/diag/dumpvfscache/Makefile @@ -0,0 +1,11 @@ + +PROG= dumpvfscache + +LDADD= -lkvm -lmd + +NOMAN= 1 + +test: ${PROG} + ./${PROG} > a + +.include <bsd.prog.mk> diff --git a/tools/diag/dumpvfscache/README b/tools/diag/dumpvfscache/README new file mode 100644 index 0000000..2a1c57c --- /dev/null +++ b/tools/diag/dumpvfscache/README @@ -0,0 +1,6 @@ +This is a little C-program that can be used to examine the contents of +the vfs name cache. It's very likely to loop and crash if you use it +on an active system. + + Poul-Henning Kamp + 4 sep 1997 diff --git a/tools/diag/dumpvfscache/dumpvfscache.c b/tools/diag/dumpvfscache/dumpvfscache.c new file mode 100644 index 0000000..6deaab6 --- /dev/null +++ b/tools/diag/dumpvfscache/dumpvfscache.c @@ -0,0 +1,120 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <kvm.h> +#include <nlist.h> +#include <sys/uio.h> +#include <sys/namei.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/vnode.h> +/*----------------------------------*/ +static u_int crc16_table[16] = { + 0x0000, 0xCC01, 0xD801, 0x1400, + 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, + 0x5000, 0x9C01, 0x8801, 0x4400 +}; + +static u_short +wlpsacrc(u_char *buf, u_int len) +{ + u_short crc = 0; + int i, r1; + + for (i = 0; i < len; i++, buf++) { + /* lower 4 bits */ + r1 = crc16_table[crc & 0xF]; + crc = (crc >> 4) & 0x0FFF; + crc = crc ^ r1 ^ crc16_table[*buf & 0xF]; + + /* upper 4 bits */ + r1 = crc16_table[crc & 0xF]; + crc = (crc >> 4) & 0x0FFF; + crc = crc ^ r1 ^ crc16_table[(*buf >> 4) & 0xF]; + } + return(crc); +} + +/*----------------------------------*/ +struct nlist nl[] = { + { "_nchash", 0}, + { "_nchashtbl", 0}, + { 0, 0 }, +}; + +int histo[2047]; +int histn[2047]; +int *newbucket; + +int +main(int argc, char **argv) +{ + int nchash, i, j, k, kn; + int nb, p1, p2; + u_long p; + LIST_HEAD(nchashhead, namecache) *nchashtbl; + struct namecache *nc; + struct vnode vn; + + kvm_t *kvm = kvm_open(0, 0, 0, O_RDONLY, 0); + + printf("kvm: %p\n", kvm); + printf("kvm_nlist: %d\n", kvm_nlist(kvm, nl)); + kvm_read(kvm, nl[0].n_value, &nchash, sizeof nchash); + nchash++; + nchashtbl = malloc(nchash * sizeof *nchashtbl); + nc = malloc(sizeof *nc + 400); + newbucket = malloc(nchash * sizeof (int)); + memset(newbucket, 0, nchash * sizeof (int)); + kvm_read(kvm, nl[1].n_value, &p, sizeof p); + kvm_read(kvm, p, nchashtbl, nchash * sizeof *nchashtbl); + for (i=0; i < nchash; i++) { +#if 0 + printf("%d\n", i); +#endif + nb=0; + p = (u_long)LIST_FIRST(nchashtbl+i); + while (p) { + nb++; + kvm_read(kvm, p, nc, sizeof *nc + 400); + kvm_read(kvm, (u_long)nc->nc_dvp, &vn, sizeof vn); + nc->nc_name[nc->nc_nlen] = '\0'; + for (j=k=kn=0;nc->nc_name[j];j++) { + k+= nc->nc_name[j]; + kn <<= 1; + kn+= nc->nc_name[j]; + } + /* + kn = k; + */ + kn = wlpsacrc(nc->nc_name,nc->nc_nlen); + + /* kn += (u_long)vn.v_data >> 8; */ + /* kn += (u_long)nc->nc_dvp >> 7; */ + kn += vn.v_id; + kn &= (nchash - 1); + newbucket[kn]++; +#if 1 + printf("%4d dvp %08x hash %08x vp %08x id %08x name <%s>\n", + i,nc->nc_dvp, k, nc->nc_vp, vn.v_id, nc->nc_name); +#endif + p = (u_long)LIST_NEXT(nc, nc_hash); + } + histo[nb]++; + } + for (i=0; i < nchash; i++) { + histn[newbucket[i]]++; + } + p1=p2 = 0; + for (i=0;i<30;i++) { + p1 += histo[i] * i; + p2 += histn[i] * i; + if (histo[i] || histn[i]) + printf("H%02d %4d %4d / %4d %4d\n",i,histo[i], p1 , histn[i], p2); + } + + return (0); +} + |