4 * cc -I/usr/src/sys ncptrace.c -o /usr/local/bin/ncptrace -lkvm
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.
13 * Copyright (c) 2004 The DragonFly Project. All rights reserved.
15 * This code is derived from software contributed to The DragonFly Project
16 * by Matthew Dillon <dillon@backplane.com>
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
28 * 3. Neither the name of The DragonFly Project nor the names of its
29 * contributors may be used to endorse or promote products derived
30 * from this software without specific, prior written permission.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
36 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
37 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
38 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
40 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
41 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
42 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * $DragonFly: src/test/debug/ncptrace.c,v 1.5 2004/10/08 18:32:58 dillon Exp $
48 #define _KERNEL_STRUCTURES_
49 #include <sys/param.h>
51 #include <sys/malloc.h>
52 #include <sys/signalvar.h>
53 #include <sys/vnode.h>
54 #include <sys/namecache.h>
57 #include <vm/vm_page.h>
58 #include <vm/vm_kern.h>
59 #include <vm/swap_pager.h>
60 #include <vm/vnode_pager.h>
79 void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
80 void dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path);
82 main(int ac, char **av)
84 struct namecache *ncptr;
86 const char *corefile = NULL;
87 const char *sysfile = NULL;
91 while ((ch = getopt(ac, av, "M:N:")) != -1) {
100 fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
107 if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
111 if (kvm_nlist(kd, Nl) != 0) {
116 kkread(kd, Nl[0].n_value, &ncptr, sizeof(ncptr));
118 ncptr = (void *)Nl[0].n_value;
121 dumpncp(kd, 0, ncptr, NULL);
123 for (i = 0; i < ac; ++i) {
125 fprintf(stderr, "%s: path must start at the root\n", av[i]);
126 dumpncp(kd, 0, ncptr, av[i]);
132 dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path)
134 struct namecache ncp;
135 struct namecache *ncscan;
140 kkread(kd, (u_long)ncptr, &ncp, sizeof(ncp));
141 if (ncp.nc_nlen < sizeof(name)) {
142 kkread(kd, (u_long)ncp.nc_name, name, ncp.nc_nlen);
143 name[ncp.nc_nlen] = 0;
148 strcpy(name, "ROOT");
151 } else if (ncp.nc_flag & NCF_MOUNTPT) {
152 strcpy(name, "MOUNTGLUE");
153 } else if (name[0] == 0) {
158 if ((ptr = strchr(path, '/')) == NULL)
159 ptr = path + strlen(path);
160 if (strlen(name) != ptr - path ||
161 bcmp(name, path, ptr - path) != 0
172 if (ncp.nc_list.tqh_first)
180 printf("%*.*s%s ", tab, tab, "", name);
181 printf("[ncp=%p par=%p %04x vp=%p",
182 ncptr, ncp.nc_parent, ncp.nc_flag, ncp.nc_vp);
184 printf(" timo=%d", ncp.nc_timeout);
186 printf(" refs=%d", ncp.nc_refs);
187 if ((ncp.nc_flag & NCF_UNRESOLVED) == 0 && ncp.nc_error)
188 printf(" error=%d", ncp.nc_error);
190 printf(" LOCKED(%d,td=%p)", ncp.nc_exlocks, ncp.nc_locktd);
194 printf(" %s\n", name);
196 printf("%s\n", haschildren ? " {" : "");
198 for (ncscan = ncp.nc_list.tqh_first; ncscan; ncscan = ncp.nc_entry.tqe_next) {
199 kkread(kd, (u_long)ncscan, &ncp, sizeof(ncp));
200 dumpncp(kd, (path ? (tab ? tab : 4) : tab + 4), ncscan, path);
202 if (haschildren && path == NULL)
203 printf("%*.*s}\n", tab, tab, "");
207 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
209 if (kvm_read(kd, addr, buf, nbytes) != nbytes) {