xref: /dragonfly/test/debug/h2inodes.c (revision de78d61c)
1 /*
2  * H2INODES.C
3  *
4  * cc -I/usr/src/sys h2inodes.c -o ~/bin/h2inodes -lkvm
5  *
6  * h2inodes <pfsaddr>
7  *
8  * Copyright (c) 2018 The DragonFly Project.  All rights reserved.
9  *
10  * This code is derived from software contributed to The DragonFly Project
11  * by Matthew Dillon <dillon@backplane.com>
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in
21  *    the documentation and/or other materials provided with the
22  *    distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
28  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #include <sys/types.h>
39 #include <sys/user.h>
40 #include <vfs/hammer2/hammer2.h>
41 
42 #include <vm/vm.h>
43 #include <vm/vm_page.h>
44 #include <vm/vm_kern.h>
45 #include <vm/swap_pager.h>
46 #include <vm/vnode_pager.h>
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <fcntl.h>
52 #include <kvm.h>
53 #include <nlist.h>
54 #include <getopt.h>
55 
56 static void h2inumscan(kvm_t *kd, int tab, uintptr_t cp);
57 static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
58 
59 #if 0
60 struct nlist Nl[] = {
61     { "_rootnch" },
62     { "_mountlist" },
63     { NULL }
64 };
65 #endif
66 
67 int
68 main(int ac, char **av)
69 {
70     kvm_t *kd;
71     const char *corefile = NULL;
72     const char *sysfile = NULL;
73     hammer2_pfs_t pmp;
74     uintptr_t base;
75     uintptr_t cp;
76     int ch;
77 
78     while ((ch = getopt(ac, av, "M:N:")) != -1) {
79 	switch(ch) {
80 	case 'M':
81 	    corefile = optarg;
82 	    break;
83 	case 'N':
84 	    sysfile = optarg;
85 	    break;
86 	default:
87 	    fprintf(stderr, "%s [-M core] [-N system]\n", av[0]);
88 	    exit(1);
89 	}
90     }
91     ac -= optind;
92     av += optind;
93 
94     if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
95 	perror("kvm_open");
96 	exit(1);
97     }
98 #if 0
99     if (kvm_nlist(kd, Nl) != 0) {
100 	perror("kvm_nlist");
101 	exit(1);
102     }
103     kkread(kd, Nl[0].n_value, &nch, sizeof(nch));
104     kkread(kd, Nl[1].n_value, &list, sizeof(list));
105 #endif
106 
107     base = strtoul(av[0], NULL, 0);
108 
109     kkread(kd, base, &pmp, sizeof(pmp));
110     cp = (uintptr_t)pmp.inum_tree.rbh_root;
111     if (cp)
112 	    h2inumscan(kd, 4, cp);
113     printf("\n");
114     return 0;
115 }
116 
117 static
118 void
119 h2inumscan(kvm_t *kd, int tab, uintptr_t cp)
120 {
121 	hammer2_inode_t ip;
122 
123 	kkread(kd, cp, &ip, sizeof(ip));
124 	if (ip.rbnode.rbe_left)
125 		h2inumscan(kd, tab, (uintptr_t)ip.rbnode.rbe_left);
126 	printf("%*.*s ip %p inum=%ld refs=%08x "
127 		"flags=%08x chain0=%p vp=%p\n",
128 		tab, tab, "", (void *)cp, ip.meta.inum, ip.refs,
129 		ip.flags, ip.cluster.array[0].chain, ip.vp);
130 	if (ip.rbnode.rbe_right)
131 		h2inumscan(kd, tab, (uintptr_t)ip.rbnode.rbe_right);
132 }
133 
134 static void
135 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
136 {
137 	if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
138 		perror("kvm_read");
139 		exit(1);
140 	}
141 }
142