VFS messaging/interfacing work stage 7e/99: More firming up of stage 7.
[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 *
3a8683bb 12 * $DragonFly: src/test/debug/ncptrace.c,v 1.2 2004/10/06 05:13:20 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>
35
36struct nlist Nl[] = {
3a8683bb 37#ifdef CINV_PARENT
f4da0b70 38 { "_rootncp" },
3a8683bb
MD
39#else
40 { "_rootnamecache" },
41#endif
f4da0b70
MD
42 { NULL }
43};
44
45void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
46void dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path);
47
48main(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 }
3a8683bb 62#ifdef CINV_PARENT
f4da0b70 63 kkread(kd, Nl[0].n_value, &ncptr, sizeof(ncptr));
3a8683bb
MD
64#else
65 ncptr = (void *)Nl[0].n_value;
66#endif
f4da0b70
MD
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
78void
79dumpncp(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
3a8683bb
MD
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
f4da0b70 138 if (path) {
3a8683bb 139 printf(" %s\n", name);
f4da0b70 140 } else {
3a8683bb 141 printf("%s\n", haschildren ? " {" : "");
f4da0b70
MD
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
151void
152kkread(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