Add vnodeinfo - a program which scans each mount's vnode list and dumps
[dragonfly.git] / test / debug / ncptrace.c
CommitLineData
f4da0b70
MD
1/*
2 * NCPTRACE.C
3 *
4 * cc -I/usr/src/sys ncptrace.c -o /usr/local/bin/ncptrace -lkvm
5 *
6 * ncptrace
7 * ncptrace [path]
8 *
9 * Trace and dump the kernel namecache hierarchy. If a path is specified
10 * the trace begins there, otherwise the trace begins at the root.
11 *
fa12c626 12 * $DragonFly: src/test/debug/ncptrace.c,v 1.3 2004/10/07 00:05:03 dillon Exp $
f4da0b70
MD
13 */
14
15#define _KERNEL_STRUCTURES_
16#include <sys/param.h>
17#include <sys/user.h>
18#include <sys/malloc.h>
19#include <sys/signalvar.h>
20#include <sys/vnode.h>
21#include <sys/namecache.h>
22
23#include <vm/vm.h>
24#include <vm/vm_page.h>
25#include <vm/vm_kern.h>
26#include <vm/swap_pager.h>
27#include <vm/vnode_pager.h>
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <fcntl.h>
33#include <kvm.h>
34#include <nlist.h>
fa12c626 35#include <getopt.h>
f4da0b70
MD
36
37struct nlist Nl[] = {
3a8683bb 38#ifdef CINV_PARENT
f4da0b70 39 { "_rootncp" },
3a8683bb
MD
40#else
41 { "_rootnamecache" },
42#endif
f4da0b70
MD
43 { NULL }
44};
45
46void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
47void dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path);
48
49main(int ac, char **av)
50{
51 struct namecache *ncptr;
52 kvm_t *kd;
fa12c626
MD
53 const char *corefile = NULL;
54 const char *sysfile = NULL;
55 int ch;
f4da0b70
MD
56 int i;
57
fa12c626
MD
58 while ((ch = getopt(ac, av, "M:N:")) != -1) {
59 switch(ch) {
60 case 'M':
61 corefile = optarg;
62 break;
63 case 'N':
64 sysfile = optarg;
65 break;
66 default:
67 fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
68 exit(1);
69 }
70 }
71
72 if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
f4da0b70
MD
73 perror("kvm_open");
74 exit(1);
75 }
76 if (kvm_nlist(kd, Nl) != 0) {
77 perror("kvm_nlist");
78 exit(1);
79 }
3a8683bb 80#ifdef CINV_PARENT
f4da0b70 81 kkread(kd, Nl[0].n_value, &ncptr, sizeof(ncptr));
3a8683bb
MD
82#else
83 ncptr = (void *)Nl[0].n_value;
84#endif
f4da0b70
MD
85 if (ac == 1) {
86 dumpncp(kd, 0, ncptr, NULL);
87 } else {
88 for (i = 1; i < ac; ++i) {
89 if (av[i][0] != '/')
90 fprintf(stderr, "%s: path must start at the root\n", av[i]);
91 dumpncp(kd, 0, ncptr, av[i]);
92 }
93 }
94}
95
96void
97dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path)
98{
99 struct namecache ncp;
100 struct namecache *ncscan;
101 const char *ptr;
102 int haschildren;
103 char name[256];
104
105 kkread(kd, (u_long)ncptr, &ncp, sizeof(ncp));
106 if (ncp.nc_nlen < sizeof(name)) {
107 kkread(kd, (u_long)ncp.nc_name, name, ncp.nc_nlen);
108 name[ncp.nc_nlen] = 0;
109 } else {
110 name[0] = 0;
111 }
112 if (tab == 0) {
113 strcpy(name, "ROOT");
114 if (path)
115 ++path;
116 } else if (ncp.nc_flag & NCF_MOUNTPT) {
117 strcpy(name, "MOUNTGLUE");
118 } else if (name[0] == 0) {
119 strcpy(name, "?");
120 if (path)
121 return;
122 } else if (path) {
123 if ((ptr = strchr(path, '/')) == NULL)
124 ptr = path + strlen(path);
125 if (strlen(name) != ptr - path ||
126 bcmp(name, path, ptr - path) != 0
127 ) {
128 return;
129 }
130 path = ptr;
131 if (*path == '/')
132 ++path;
133 if (*path == 0)
134 path = NULL;
135 }
136
137 if (ncp.nc_list.tqh_first)
138 haschildren = 1;
139 else
140 haschildren = 0;
141
3a8683bb
MD
142 if (path)
143 printf("ELM ");
144 else
145 printf("%*.*s%s ", tab, tab, "", name);
146 printf("[ncp=%p par=%p %04x vp=%p",
147 ncptr, ncp.nc_parent, ncp.nc_flag, ncp.nc_vp);
148 if (ncp.nc_timeout)
149 printf(" timo=%d", ncp.nc_timeout);
150 if (ncp.nc_refs)
151 printf(" refs=%d", ncp.nc_refs);
152 if (ncp.nc_exlocks)
153 printf(" LOCKED(%d,td=%p)", ncp.nc_exlocks, ncp.nc_locktd);
154 printf("]");
155
f4da0b70 156 if (path) {
3a8683bb 157 printf(" %s\n", name);
f4da0b70 158 } else {
3a8683bb 159 printf("%s\n", haschildren ? " {" : "");
f4da0b70
MD
160 }
161 for (ncscan = ncp.nc_list.tqh_first; ncscan; ncscan = ncp.nc_entry.tqe_next) {
162 kkread(kd, (u_long)ncscan, &ncp, sizeof(ncp));
163 dumpncp(kd, (path ? (tab ? tab : 4) : tab + 4), ncscan, path);
164 }
165 if (haschildren && path == NULL)
166 printf("%*.*s}\n", tab, tab, "");
167}
168
169void
170kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
171{
172 if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
173 perror("kvm_read");
174 exit(1);
175 }
176}
177