Update ncptrace.c to handle DragonFly_Stable and HEAD.
[dragonfly.git] / test / debug / ncptrace.c
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  *
12  * $DragonFly: src/test/debug/ncptrace.c,v 1.2 2004/10/06 05:13:20 dillon Exp $
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>
35
36 struct nlist Nl[] = {
37 #ifdef CINV_PARENT
38     { "_rootncp" },
39 #else
40     { "_rootnamecache" },
41 #endif
42     { NULL }
43 };
44
45 void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
46 void dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path);
47
48 main(int ac, char **av)
49 {
50     struct namecache *ncptr;
51     kvm_t *kd;
52     int i;
53
54     if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm:")) == NULL) {
55         perror("kvm_open");
56         exit(1);
57     }
58     if (kvm_nlist(kd, Nl) != 0) {
59         perror("kvm_nlist");
60         exit(1);
61     }
62 #ifdef CINV_PARENT
63     kkread(kd, Nl[0].n_value, &ncptr, sizeof(ncptr));
64 #else
65     ncptr = (void *)Nl[0].n_value;
66 #endif
67     if (ac == 1) {
68         dumpncp(kd, 0, ncptr, NULL);
69     } else {
70         for (i = 1; i < ac; ++i) {
71             if (av[i][0] != '/')
72                 fprintf(stderr, "%s: path must start at the root\n", av[i]);
73             dumpncp(kd, 0, ncptr, av[i]);
74         }
75     }
76 }
77
78 void
79 dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path)
80 {
81     struct namecache ncp;
82     struct namecache *ncscan;
83     const char *ptr;
84     int haschildren;
85     char name[256];
86
87     kkread(kd, (u_long)ncptr, &ncp, sizeof(ncp));
88     if (ncp.nc_nlen < sizeof(name)) {
89         kkread(kd, (u_long)ncp.nc_name, name, ncp.nc_nlen);
90         name[ncp.nc_nlen] = 0;
91     } else {
92         name[0] = 0;
93     }
94     if (tab == 0) {
95         strcpy(name, "ROOT");
96         if (path)
97             ++path;
98     } else if (ncp.nc_flag & NCF_MOUNTPT) {
99         strcpy(name, "MOUNTGLUE");
100     } else if (name[0] == 0) {
101         strcpy(name, "?");
102         if (path)
103             return;
104     } else if (path) {
105         if ((ptr = strchr(path, '/')) == NULL)
106             ptr = path + strlen(path);
107         if (strlen(name) != ptr - path ||
108             bcmp(name, path, ptr - path) != 0
109         ) {
110             return;
111         }
112         path = ptr;
113         if (*path == '/')
114             ++path;
115         if (*path == 0)
116             path = NULL;
117     }
118
119     if (ncp.nc_list.tqh_first)
120         haschildren = 1;
121     else
122         haschildren = 0;
123
124     if (path)
125         printf("ELM ");
126     else
127         printf("%*.*s%s ", tab, tab, "", name);
128     printf("[ncp=%p par=%p %04x vp=%p", 
129             ncptr, ncp.nc_parent, ncp.nc_flag, ncp.nc_vp);
130     if (ncp.nc_timeout)
131         printf(" timo=%d", ncp.nc_timeout);
132     if (ncp.nc_refs)
133         printf(" refs=%d", ncp.nc_refs);
134     if (ncp.nc_exlocks)
135         printf(" LOCKED(%d,td=%p)", ncp.nc_exlocks, ncp.nc_locktd);
136     printf("]");
137
138     if (path) {
139         printf(" %s\n", name);
140     } else {
141         printf("%s\n", haschildren ? " {" : "");
142     }
143     for (ncscan = ncp.nc_list.tqh_first; ncscan; ncscan = ncp.nc_entry.tqe_next) {
144         kkread(kd, (u_long)ncscan, &ncp, sizeof(ncp));
145         dumpncp(kd, (path ? (tab ? tab : 4) : tab + 4), ncscan, path);
146     }
147     if (haschildren && path == NULL)
148         printf("%*.*s}\n", tab, tab, "");
149 }
150
151 void
152 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
153 {
154     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
155         perror("kvm_read");
156         exit(1);
157     }
158 }
159