share/syscons: Separate hostprog and remove it from btools.
[dragonfly.git] / test / debug / checkhammer.c
bloba2a595cafa9c7e717c0fb2d1ba9f9b8e0019f247
1 /*
2 * checkhammer.c
4 * checkhammer blockmapdump btreedump
5 */
7 #include <sys/types.h>
8 #include <sys/tree.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
14 struct rbmap_tree;
15 struct rbmap;
17 static void parseBlockMap(FILE *fp);
18 static void parseBTree(FILE *fp);
19 static void dumpResults(void);
20 static int rbmap_cmp(struct rbmap *, struct rbmap *);
22 typedef u_int64_t hammer_off_t;
23 typedef struct rbmap *rbmap_t;
25 RB_HEAD(rbmap_tree, rbmap);
26 RB_PROTOTYPE2(rbmap_tree, rbmap, rbentry, rbmap_cmp, hammer_off_t);
28 struct rbmap {
29 RB_ENTRY(rbmap) rbentry;
30 hammer_off_t base;
31 long app;
32 long free;
33 long bytes;
34 int zone;
37 RB_GENERATE2(rbmap_tree, rbmap, rbentry, rbmap_cmp, hammer_off_t, base);
39 struct rbmap_tree rbroot;
41 static
42 int
43 rbmap_cmp(struct rbmap *rb1, struct rbmap *rb2)
45 if (rb1->base < rb2->base)
46 return(-1);
47 if (rb1->base > rb2->base)
48 return(1);
49 return(0);
52 int
53 main(int ac, char **av)
55 FILE *fp;
57 if (ac != 3) {
58 fprintf(stderr, "checkhammer blockmapdump btreedump\n");
59 exit(1);
61 if ((fp = fopen(av[1], "r")) == NULL) {
62 fprintf(stderr, "Unable to open %s\n", av[1]);
63 exit(1);
66 RB_INIT(&rbroot);
67 parseBlockMap(fp);
68 fclose(fp);
69 if ((fp = fopen(av[2], "r")) == NULL) {
70 fprintf(stderr, "Unable to open %s\n", av[1]);
71 exit(1);
73 parseBTree(fp);
74 fclose(fp);
76 dumpResults();
77 return(0);
80 static void
81 parseBlockMap(FILE *fp)
83 char buf[1024];
84 rbmap_t map;
85 int zone;
86 long long base;
87 long long app;
88 long long free;
90 while (fgets(buf, sizeof(buf), fp) != NULL) {
91 if (sscanf(buf, " 4%llx zone=%d app=%lld free=%lld",
92 &base, &zone, &app, &free) != 4)
93 continue;
94 if (RB_LOOKUP(rbmap_tree, &rbroot, (hammer_off_t)base))
95 continue;
96 map = malloc(sizeof(*map));
97 map->base = (hammer_off_t)base;
98 map->app = (long)app;
99 map->free = (long)free;
100 map->zone = zone;
101 map->bytes = 0;
102 RB_INSERT(rbmap_tree, &rbroot, map);
106 static void
107 parseBTree(FILE *fp)
109 char buf[1024];
110 rbmap_t map;
111 long long base;
112 long long bytes;
114 while (fgets(buf, sizeof(buf), fp) != NULL) {
115 if (sscanf(buf, " NODE 8%llx", &base) == 1) {
116 base &= 0x0FFFFFFFFF800000LLU;
117 map = RB_LOOKUP(rbmap_tree, &rbroot, base);
118 if (map == NULL) {
119 printf("(not in blockmap): %s", buf);
120 continue;
122 map->bytes += 4096;
124 if (sscanf(buf, " dataoff=%llx/%lld",
125 &base, &bytes) == 2) {
126 base &= 0x0FFFFFFFFF800000LLU;
127 map = RB_LOOKUP(rbmap_tree, &rbroot, base);
128 if (map == NULL) {
129 printf("(not in blockmap): %s", buf);
130 continue;
132 map->bytes += (bytes + 15) & ~15;
137 static void
138 dumpResults(void)
140 rbmap_t map;
141 hammer_off_t bfree;
143 printf("mismatches: (blockmap, actual)\n");
144 RB_FOREACH(map, rbmap_tree, &rbroot) {
145 bfree = 8192 * 1024 - (int64_t)map->bytes;
148 * Ignore matches
150 if (map->free == bfree)
151 continue;
154 * If the block is completely allocated but our calculations
155 * show nobody is referencing it it is probably an undo,
156 * blockmap, or unavailable reserved area.
158 if (map->free == 0 && bfree == 8192 * 1024) {
159 if (map->zone == 3 || map->zone == 4 ||
160 map->zone == 15)
161 continue;
164 printf(" bmap %016jx %jd %jd\n",
165 map->base,
166 (intmax_t)(int64_t)map->free,
167 (intmax_t)(int64_t)bfree);