summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1997-09-04 08:28:55 +0000
committerphk <phk@FreeBSD.org>1997-09-04 08:28:55 +0000
commit9a333abb93f0a94f2fc4d523ffa9c31e6cc0f204 (patch)
tree3346cd0f5fb86d288dfb0a2a9fd6040d957ecfc5
parent775942111e5470deca3e270fca7d40b48c436e90 (diff)
downloadFreeBSD-src-9a333abb93f0a94f2fc4d523ffa9c31e6cc0f204.zip
FreeBSD-src-9a333abb93f0a94f2fc4d523ffa9c31e6cc0f204.tar.gz
A little gadget to dump the contents of the vfs name cache.
-rw-r--r--tools/diag/dumpvfscache/Makefile11
-rw-r--r--tools/diag/dumpvfscache/README6
-rw-r--r--tools/diag/dumpvfscache/dumpvfscache.c120
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);
+}
+
OpenPOWER on IntegriCloud