Install dma(8) config files with mode 640 as root:mail to prevent ``normal''
[dragonfly.git] / sbin / hammer / cmd_show.c
blob4e7883995f1e142c50b72e53bdad9b3721379b2d
1 /*
2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/sbin/hammer/cmd_show.c,v 1.4 2008/01/25 05:53:41 dillon Exp $
37 #include "hammer.h"
39 #define FLAG_TOOFARLEFT 0x0001
40 #define FLAG_TOOFARRIGHT 0x0002
41 #define FLAG_BADTYPE 0x0004
43 static void print_btree_node(struct cluster_info *cluster,
44 int32_t node_offset, int depth, int spike,
45 hammer_base_elm_t left_bound,
46 hammer_base_elm_t right_bound);
47 static void print_btree_elm(hammer_btree_elm_t elm, int i, u_int8_t type,
48 int flags, const char *label);
49 static int print_elm_flags(hammer_node_ondisk_t node, hammer_btree_elm_t elm,
50 u_int8_t btype, hammer_base_elm_t left_bound,
51 hammer_base_elm_t right_bound);
53 void
54 hammer_cmd_show(int32_t vol_no, int32_t clu_no, int depth)
56 struct volume_info *volume;
57 struct cluster_info *cluster;
58 int32_t node_offset;
60 if (vol_no == -1) {
61 if (RootVolNo < 0)
62 errx(1, "hammer show: root volume number unknown");
63 vol_no = RootVolNo;
65 volume = get_volume(vol_no);
66 if (volume == NULL)
67 errx(1, "hammer show: Unable to locate volume %d", vol_no);
68 if (clu_no == -1)
69 clu_no = volume->ondisk->vol0_root_clu_no;
70 cluster = get_cluster(volume, clu_no, 0);
71 printf("show %d:%d root@%08x parent@%d:%d:%08x depth %d\n",
72 vol_no, clu_no,
73 cluster->ondisk->clu_btree_root,
74 cluster->ondisk->clu_btree_parent_vol_no,
75 cluster->ondisk->clu_btree_parent_clu_no,
76 cluster->ondisk->clu_btree_parent_offset,
77 depth);
78 if (VerboseOpt) {
79 printf("\trecords=%d\n",
80 cluster->ondisk->stat_records);
82 node_offset = cluster->ondisk->clu_btree_root;
83 print_btree_node(cluster, node_offset, depth, 0,
84 &cluster->ondisk->clu_btree_beg,
85 &cluster->ondisk->clu_btree_end);
86 print_btree_node(cluster, node_offset, depth, 1,
87 &cluster->ondisk->clu_btree_beg,
88 &cluster->ondisk->clu_btree_end);
89 rel_cluster(cluster);
90 rel_volume(volume);
93 static void
94 print_btree_node(struct cluster_info *cluster, int32_t node_offset, int depth,
95 int spike,
96 hammer_base_elm_t left_bound, hammer_base_elm_t right_bound)
98 struct buffer_info *buffer = NULL;
99 hammer_node_ondisk_t node;
100 hammer_btree_elm_t elm;
101 int i;
102 int flags;
104 node = get_node(cluster, node_offset, &buffer);
106 if (spike == 0) {
107 printf(" NODE %d:%d:%08x count=%d parent=%08x "
108 "type=%c depth=%d {\n",
109 cluster->volume->vol_no,
110 cluster->clu_no,
111 node_offset, node->count, node->parent,
112 (node->type ? node->type : '?'),
113 depth);
115 for (i = 0; i < node->count; ++i) {
116 elm = &node->elms[i];
117 flags = print_elm_flags(node, elm, elm->base.btype,
118 left_bound, right_bound);
119 print_btree_elm(elm, i, node->type, flags, "ELM");
121 if (node->type == HAMMER_BTREE_TYPE_INTERNAL) {
122 elm = &node->elms[i];
123 flags = print_elm_flags(node, elm, 'I',
124 left_bound, right_bound);
125 print_btree_elm(elm, i, node->type, flags, "RBN");
127 printf(" }\n");
130 for (i = 0; i < node->count; ++i) {
131 elm = &node->elms[i];
133 switch(node->type) {
134 case HAMMER_BTREE_TYPE_INTERNAL:
135 if (elm->internal.subtree_offset) {
136 print_btree_node(cluster,
137 elm->internal.subtree_offset,
138 depth + 1, spike,
139 &elm[0].base, &elm[1].base);
141 break;
142 case HAMMER_BTREE_TYPE_LEAF:
143 if (RecurseOpt && spike &&
144 elm->leaf.base.btype == HAMMER_BTREE_TYPE_SPIKE_END) {
145 hammer_cmd_show(elm->leaf.spike_vol_no,
146 elm->leaf.spike_clu_no,
147 depth + 1);
149 break;
152 rel_buffer(buffer);
155 static
156 void
157 print_btree_elm(hammer_btree_elm_t elm, int i, u_int8_t type,
158 int flags, const char *label)
160 char flagstr[8] = { 0, '-', '-', '-', '-', '-', '-', 0 };
162 flagstr[0] = flags ? 'B' : 'G';
163 if (flags & FLAG_TOOFARLEFT)
164 flagstr[2] = 'L';
165 if (flags & FLAG_TOOFARRIGHT)
166 flagstr[3] = 'R';
167 if (flags & FLAG_BADTYPE)
168 flagstr[4] = 'T';
170 printf("%s\t%s %2d %c ",
171 flagstr, label, i,
172 (elm->base.btype ? elm->base.btype : '?'));
173 printf("obj=%016llx key=%016llx rt=%02x ot=%02x\n",
174 elm->base.obj_id,
175 elm->base.key,
176 elm->base.rec_type,
177 elm->base.obj_type);
178 printf("\t tids %016llx:%016llx ",
179 elm->base.create_tid,
180 elm->base.delete_tid);
182 switch(type) {
183 case HAMMER_BTREE_TYPE_INTERNAL:
184 printf("suboff=%08x", elm->internal.subtree_offset);
185 break;
186 case HAMMER_BTREE_TYPE_LEAF:
187 switch(elm->base.btype) {
188 case HAMMER_BTREE_TYPE_RECORD:
189 printf("recoff=%08x", elm->leaf.rec_offset);
190 break;
191 case HAMMER_BTREE_TYPE_SPIKE_BEG:
192 case HAMMER_BTREE_TYPE_SPIKE_END:
193 printf("spike %d:%d",
194 elm->leaf.spike_vol_no,
195 elm->leaf.spike_clu_no);
196 break;
198 break;
199 default:
200 break;
202 printf("\n");
205 static
207 print_elm_flags(hammer_node_ondisk_t node, hammer_btree_elm_t elm,
208 u_int8_t btype,
209 hammer_base_elm_t left_bound, hammer_base_elm_t right_bound)
211 int flags = 0;
213 switch(node->type) {
214 case HAMMER_BTREE_TYPE_INTERNAL:
215 switch(btype) {
216 case HAMMER_BTREE_TYPE_INTERNAL:
217 if (hammer_btree_cmp(&elm->base, left_bound) < 0)
218 flags |= FLAG_TOOFARLEFT;
219 if (hammer_btree_cmp(&elm->base, right_bound) > 0)
220 flags |= FLAG_TOOFARRIGHT;
221 break;
222 case HAMMER_BTREE_TYPE_LEAF:
223 if (hammer_btree_cmp(&elm->base, left_bound) < 0)
224 flags |= FLAG_TOOFARLEFT;
225 if (hammer_btree_cmp(&elm->base, right_bound) >= 0)
226 flags |= FLAG_TOOFARRIGHT;
227 break;
228 default:
229 flags |= FLAG_BADTYPE;
230 break;
232 break;
233 case HAMMER_BTREE_TYPE_LEAF:
234 switch(btype) {
235 case HAMMER_BTREE_TYPE_SPIKE_END:
236 if (hammer_btree_cmp(&elm->base, left_bound) < 0)
237 flags |= FLAG_TOOFARLEFT;
238 if (hammer_btree_cmp(&elm->base, right_bound) > 0)
239 flags |= FLAG_TOOFARRIGHT;
240 break;
241 case HAMMER_BTREE_TYPE_SPIKE_BEG:
242 case HAMMER_BTREE_TYPE_RECORD:
243 if (hammer_btree_cmp(&elm->base, left_bound) < 0)
244 flags |= FLAG_TOOFARLEFT;
245 if (hammer_btree_cmp(&elm->base, right_bound) >= 0)
246 flags |= FLAG_TOOFARRIGHT;
247 break;
248 default:
249 flags |= FLAG_BADTYPE;
250 break;
252 break;
253 default:
254 flags |= FLAG_BADTYPE;
255 break;
257 return(flags);