build - Add a few things in test/debug
[dragonfly.git] / test / debug / h2dio.c
1 /*
2  * H2DIO.C
3  *
4  * cc -I/usr/src/sys h2dio.c -o ~/bin/h2dio -lkvm
5  *
6  * h2dio <hmpaddr>
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 h2dioscan(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_dev_t hmp;
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, &hmp, sizeof(hmp));
110     cp = (uintptr_t)hmp.iotree.rbh_root;
111     if (cp)
112             h2dioscan(kd, 4, cp);
113     printf("\n");
114     return 0;
115 }
116
117 static
118 void
119 h2dioscan(kvm_t *kd, int tab, uintptr_t cp)
120 {
121         hammer2_io_t dio;
122
123         kkread(kd, cp, &dio, sizeof(dio));
124         if (dio.rbnode.rbe_left)
125                 h2dioscan(kd, tab, (uintptr_t)dio.rbnode.rbe_left);
126         printf("%*.*s dio %p pbase=%016lx refs=%08x "
127                 "bp=%p psize=%d ticks=%d err=%d\n",
128                 tab, tab, "", (void *)cp, dio.pbase, dio.refs,
129                 dio.bp, dio.psize, dio.ticks, dio.error);
130         if (dio.rbnode.rbe_right)
131                 h2dioscan(kd, tab, (uintptr_t)dio.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 }