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.6 2005/03/24 20:15:11 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>
75 void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
76 void dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path);
78 main(int ac, char **av)
80 struct namecache *ncptr;
82 const char *corefile = NULL;
83 const char *sysfile = NULL;
87 while ((ch = getopt(ac, av, "M:N:")) != -1) {
96 fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
103 if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
107 if (kvm_nlist(kd, Nl) != 0) {
111 kkread(kd, Nl[0].n_value, &ncptr, sizeof(ncptr));
113 dumpncp(kd, 0, ncptr, NULL);
115 for (i = 0; i < ac; ++i) {
117 fprintf(stderr, "%s: path must start at the root\n", av[i]);
118 dumpncp(kd, 0, ncptr, av[i]);
124 dumpncp(kvm_t *kd, int tab, struct namecache *ncptr, const char *path)
126 struct namecache ncp;
127 struct namecache *ncscan;
132 kkread(kd, (u_long)ncptr, &ncp, sizeof(ncp));
133 if (ncp.nc_nlen < sizeof(name)) {
134 kkread(kd, (u_long)ncp.nc_name, name, ncp.nc_nlen);
135 name[ncp.nc_nlen] = 0;
140 strcpy(name, "ROOT");
143 } else if (ncp.nc_flag & NCF_MOUNTPT) {
144 strcpy(name, "MOUNTGLUE");
145 } else if (name[0] == 0) {
150 if ((ptr = strchr(path, '/')) == NULL)
151 ptr = path + strlen(path);
152 if (strlen(name) != ptr - path ||
153 bcmp(name, path, ptr - path) != 0
164 if (ncp.nc_list.tqh_first)
172 printf("%*.*s%s ", tab, tab, "", name);
173 printf("[ncp=%p par=%p %04x vp=%p",
174 ncptr, ncp.nc_parent, ncp.nc_flag, ncp.nc_vp);
176 printf(" timo=%d", ncp.nc_timeout);
178 printf(" refs=%d", ncp.nc_refs);
179 if ((ncp.nc_flag & NCF_UNRESOLVED) == 0 && ncp.nc_error)
180 printf(" error=%d", ncp.nc_error);
182 printf(" LOCKED(%d,td=%p)", ncp.nc_exlocks, ncp.nc_locktd);
186 printf(" %s\n", name);
188 printf("%s\n", haschildren ? " {" : "");
190 for (ncscan = ncp.nc_list.tqh_first; ncscan; ncscan = ncp.nc_entry.tqe_next) {
191 kkread(kd, (u_long)ncscan, &ncp, sizeof(ncp));
192 dumpncp(kd, (path ? (tab ? tab : 4) : tab + 4), ncscan, path);
194 if (haschildren && path == NULL)
195 printf("%*.*s}\n", tab, tab, "");
199 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
201 if (kvm_read(kd, addr, buf, nbytes) != nbytes) {