1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <mdb/mdb_modapi.h>
27 #include <mdb/mdb_ks.h>
28 #include <sys/types.h>
29 #include <sys/sysmacros.h>
30 #include <sys/fs/ufs_inode.h>
31 #include <sys/fs/ufs_acl.h>
32 #include <sys/fs/ufs_fs.h>
33
34 #include "ufs_cmds.h"
35
36 typedef struct inode_walk_data {
37 int iw_inohsz;
38 int iw_inohcnt;
39 uintptr_t iw_ihead;
40 inode_t iw_inode;
41 } inode_walk_data_t;
42
43 static int
inode_walk_init(mdb_walk_state_t * wsp)44 inode_walk_init(mdb_walk_state_t *wsp)
45 {
46 int inohsz;
47 uintptr_t ihead;
48 union ihead ih;
49 inode_walk_data_t *iw;
50
51 if (wsp->walk_addr != 0) {
52 mdb_warn("inode_cache only supports global walks\n");
53 return (WALK_ERR);
54 }
55
56 if (mdb_readvar(&inohsz, "inohsz") == -1) {
57 mdb_warn("failed to read 'inohsz'");
58 return (WALK_ERR);
59 }
60
61 if (inohsz == 0)
62 return (WALK_DONE);
63
64 if (mdb_readvar(&ihead, "ihead") == -1) {
65 mdb_warn("failed to read 'ihead'");
66 return (WALK_ERR);
67 }
68
69 if (mdb_vread(&ih, sizeof (union ihead), ihead) == -1) {
70 mdb_warn("failed to read ihead at %p", ihead);
71 return (WALK_DONE);
72 }
73
74 iw = mdb_alloc(sizeof (inode_walk_data_t), UM_SLEEP);
75 iw->iw_inohsz = inohsz;
76 iw->iw_inohcnt = 0;
77 iw->iw_ihead = ihead;
78
79 wsp->walk_addr = (uintptr_t)ih.ih_chain[0];
80 wsp->walk_data = iw;
81
82 return (WALK_NEXT);
83 }
84
85 static int
inode_walk_step(mdb_walk_state_t * wsp)86 inode_walk_step(mdb_walk_state_t *wsp)
87 {
88 uintptr_t addr = wsp->walk_addr;
89 inode_walk_data_t *iw = wsp->walk_data;
90 union ihead ih;
91
92 while (addr == iw->iw_ihead) {
93 if (++iw->iw_inohcnt >= iw->iw_inohsz)
94 return (WALK_DONE);
95
96 iw->iw_ihead += sizeof (union ihead);
97
98 if (mdb_vread(&ih, sizeof (union ihead), iw->iw_ihead) == -1) {
99 mdb_warn("failed to read ihead at %p", iw->iw_ihead);
100 return (WALK_DONE);
101 }
102 addr = (uintptr_t)ih.ih_chain[0];
103 }
104
105 if (mdb_vread(&iw->iw_inode, sizeof (inode_t), addr) == -1) {
106 mdb_warn("failed to read inode at %p", addr);
107 return (WALK_DONE);
108 }
109
110 wsp->walk_addr = (uintptr_t)iw->iw_inode.i_forw;
111
112 return (wsp->walk_callback(addr, (void *)(uintptr_t)iw->iw_inohcnt,
113 wsp->walk_cbdata));
114 }
115
116 static void
inode_walk_fini(mdb_walk_state_t * wsp)117 inode_walk_fini(mdb_walk_state_t *wsp)
118 {
119 mdb_free(wsp->walk_data, sizeof (inode_walk_data_t));
120 }
121
122 typedef struct inode_cbdata {
123 ino_t id_inumber;
124 dev_t id_device;
125 uintptr_t id_addr;
126 uint_t id_flags;
127 } inode_cbdata_t;
128
129 static int
inode_cache_cb(uintptr_t addr,const int inohcnt,inode_cbdata_t * id)130 inode_cache_cb(uintptr_t addr, const int inohcnt, inode_cbdata_t *id)
131 {
132 inode_t inode;
133 int inohsz;
134
135 if (mdb_vread(&inode, sizeof (inode), addr) == -1) {
136 mdb_warn("failed to read inode_t at %p", addr);
137 return (WALK_ERR);
138 }
139
140 if (id->id_device != 0 && inode.i_dev != id->id_device)
141 return (WALK_NEXT);
142
143 if (id->id_inumber != 0 && inode.i_number != id->id_inumber)
144 return (WALK_NEXT);
145
146 if (id->id_flags & DCMD_ADDRSPEC && addr != id->id_addr)
147 return (WALK_NEXT);
148
149 if (id->id_flags & DCMD_PIPE_OUT) {
150 mdb_printf("%p\n", addr);
151 return (WALK_NEXT);
152 }
153
154 mdb_printf("%0?p %10lld %15lx",
155 addr, (u_longlong_t)inode.i_number, inode.i_dev);
156
157 /*
158 * INOHASH needs inohsz.
159 */
160 if (mdb_readvar(&inohsz, "inohsz") == -1) {
161 mdb_warn("failed to read 'inohsz'");
162 return (WALK_ERR);
163 }
164
165 /*
166 * Is the inode in the hash chain it should be?
167 */
168 if (inohcnt == INOHASH(inode.i_number)) {
169 mdb_printf(" %5d\n", inohcnt);
170 } else {
171 mdb_printf(" %<b>%5d/%5d ??</b>\n",
172 inohcnt, INOHASH(inode.i_number));
173 }
174
175 return (WALK_NEXT);
176 }
177
178 /*ARGSUSED*/
179 static int
inode_cache(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)180 inode_cache(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
181 {
182 inode_cbdata_t id;
183
184 id.id_inumber = 0;
185 id.id_device = 0;
186 id.id_addr = addr;
187 id.id_flags = flags;
188
189 if (mdb_getopts(argc, argv,
190 'i', MDB_OPT_UINT64, &id.id_inumber,
191 'd', MDB_OPT_UINTPTR, &id.id_device, NULL) != argc)
192 return (DCMD_USAGE);
193
194 if (DCMD_HDRSPEC(flags) && (flags & DCMD_PIPE_OUT) == 0) {
195 mdb_printf("%<u>%-?s %10s %15s %5s%</u>\n",
196 "ADDR", "INUMBER", "DEVICE", "CHAIN");
197 }
198
199 if (mdb_walk("inode_cache", (mdb_walk_cb_t)(uintptr_t)inode_cache_cb,
200 &id) == -1) {
201 mdb_warn("can't walk inode cache");
202 return (DCMD_ERR);
203 }
204
205 return (DCMD_OK);
206 }
207
208 /*ARGSUSED*/
209 static int
inode(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)210 inode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
211 {
212 uint_t verbose = FALSE;
213 inode_t inode;
214 char buf[64];
215 char path[MAXPATHLEN];
216
217 static const mdb_bitmask_t i_flag_masks[] = {
218 { "UPD", IUPD, IUPD },
219 { "ACC", IACC, IACC },
220 { "MOD", IMOD, IMOD },
221 { "CHG", ICHG, ICHG },
222 { "NOACC", INOACC, INOACC },
223 { "MODTIME", IMODTIME, IMODTIME },
224 { "REF", IREF, IREF },
225 { "SYNC", ISYNC, ISYNC },
226 { "FASTSYMLNK", IFASTSYMLNK, IFASTSYMLNK },
227 { "MODACC", IMODACC, IMODACC },
228 { "ATTCHG", IATTCHG, IATTCHG },
229 { "BDWRITE", IBDWRITE, IBDWRITE },
230 { "STALE", ISTALE, ISTALE },
231 { "DEL", IDEL, IDEL },
232 { "DIRECTIO", IDIRECTIO, IDIRECTIO },
233 { "JUNKIQ", IJUNKIQ, IJUNKIQ },
234 { NULL, 0, 0 }
235 };
236
237 static const mdb_bitmask_t i_modetype_masks[] = {
238 { "p", IFMT, IFIFO },
239 { "c", IFMT, IFCHR },
240 { "d", IFMT, IFDIR },
241 { "b", IFMT, IFBLK },
242 { "-", IFMT, IFREG },
243 { "l", IFMT, IFLNK },
244 { "S", IFMT, IFSHAD },
245 { "s", IFMT, IFSOCK },
246 { "A", IFMT, IFATTRDIR },
247 { NULL, 0, 0 }
248 };
249
250 if (!(flags & DCMD_ADDRSPEC))
251 return (DCMD_USAGE);
252
253 if (mdb_getopts(argc, argv,
254 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc)
255 return (DCMD_USAGE);
256
257 if (DCMD_HDRSPEC(flags) && (flags & DCMD_PIPE_OUT) == 0) {
258 mdb_printf("%<u>%-?s %10s %1s %5s %8s",
259 "ADDR", "INUMBER", "T", "MODE", "SIZE");
260
261 if (verbose)
262 mdb_printf(" %11s %-22s%</u>\n", "DEVICE", "FLAG");
263 else
264 mdb_printf(" %-12s %-21s%</u>\n", "MTIME", "NAME");
265 }
266
267 if (mdb_vread(&inode, sizeof (inode), addr) == -1) {
268 mdb_warn("failed to read inode_t at %p", addr);
269 return (DCMD_ERR);
270 }
271
272 mdb_printf("%0?p %10lld %b %5#o %8llx",
273 addr, (u_longlong_t)inode.i_number, inode.i_mode, i_modetype_masks,
274 inode.i_mode & ~IFMT, inode.i_size);
275
276 if (verbose) {
277
278 mdb_printf(" %11lx <%b>\n",
279 inode.i_dev, inode.i_flag, i_flag_masks);
280
281 mdb_inc_indent(2);
282
283 mdb_printf("%Y\n", inode.i_mtime.tv_sec);
284
285 if (mdb_vnode2path((uintptr_t)inode.i_vnode, path,
286 sizeof (path)) == 0 && *path != '\0')
287 mdb_printf("%s\n", path);
288 else
289 mdb_printf("??\n");
290
291 mdb_dec_indent(2);
292
293 return (DCMD_OK);
294 }
295
296 /*
297 * Not verbose, everything must fit into one line.
298 */
299 mdb_snprintf(buf, sizeof (buf), "%Y", inode.i_mtime.tv_sec);
300 buf[17] = '\0'; /* drop seconds */
301 if (buf[0] == '1' || buf[0] == '2')
302 mdb_printf(" %12s", buf + 5); /* drop year */
303 else
304 mdb_printf(" %-12s", "?");
305
306 if (mdb_vnode2path((uintptr_t)inode.i_vnode, path,
307 sizeof (path)) == 0 && *path != '\0') {
308 if (strlen(path) <= 21)
309 mdb_printf(" %-21s\n", path);
310 else
311 mdb_printf(" ...%-18s\n", path + strlen(path) - 18);
312 } else {
313 mdb_printf(" ??\n");
314 }
315
316 return (DCMD_OK);
317 }
318
319 static struct {
320 int am_offset;
321 char *am_tag;
322 } acl_map[] = {
323 { offsetof(si_t, aowner), "USER_OBJ" },
324 { offsetof(si_t, agroup), "GROUP_OBJ" },
325 { offsetof(si_t, aother), "OTHER_OBJ" },
326 { offsetof(si_t, ausers), "USER" },
327 { offsetof(si_t, agroups), "GROUP" },
328 { offsetof(si_t, downer), "DEF_USER_OBJ" },
329 { offsetof(si_t, dgroup), "DEF_GROUP_OBJ" },
330 { offsetof(si_t, dother), "DEF_OTHER_OBJ" },
331 { offsetof(si_t, dusers), "DEF_USER" },
332 { offsetof(si_t, dgroups), "DEF_GROUP" },
333 { -1, NULL }
334 };
335
336 static int
acl_walk_init(mdb_walk_state_t * wsp)337 acl_walk_init(mdb_walk_state_t *wsp)
338 {
339 uintptr_t addr = wsp->walk_addr;
340 inode_t inode;
341 si_t *si;
342 ufs_ic_acl_t **aclpp;
343
344 if (addr == 0) {
345 mdb_warn("acl walk needs an inode address\n");
346 return (WALK_ERR);
347 }
348
349 if (mdb_vread(&inode, sizeof (inode), addr) == -1) {
350 mdb_warn("failed to read inode_t at %p", addr);
351 return (WALK_ERR);
352 }
353
354 if (inode.i_ufs_acl == NULL)
355 return (WALK_DONE);
356
357 si = mdb_alloc(sizeof (si_t), UM_SLEEP);
358
359 if (mdb_vread(si, sizeof (si_t), (uintptr_t)inode.i_ufs_acl) == -1) {
360 mdb_warn("failed to read si_t at %p", inode.i_ufs_acl);
361 mdb_free(si, sizeof (si_t));
362 return (WALK_ERR);
363 }
364
365 /* LINTED - alignment */
366 aclpp = (ufs_ic_acl_t **)((caddr_t)si + acl_map[0].am_offset);
367
368 wsp->walk_addr = (uintptr_t)*aclpp;
369 wsp->walk_data = si;
370 wsp->walk_arg = 0;
371
372 return (WALK_NEXT);
373 }
374
375 static int
acl_walk_step(mdb_walk_state_t * wsp)376 acl_walk_step(mdb_walk_state_t *wsp)
377 {
378 uintptr_t addr = wsp->walk_addr;
379 si_t *si = wsp->walk_data;
380 uint_t i = (uintptr_t)wsp->walk_arg;
381 ufs_ic_acl_t **aclpp;
382 ufs_ic_acl_t acl;
383
384 while (addr == 0) {
385 wsp->walk_arg = (void *)(uintptr_t)++i;
386
387 if (acl_map[i].am_offset == -1)
388 return (WALK_DONE);
389
390 /* LINTED - alignment */
391 aclpp = (ufs_ic_acl_t **)((caddr_t)si + acl_map[i].am_offset);
392
393 addr = (uintptr_t)*aclpp;
394 }
395
396 if (mdb_vread(&acl, sizeof (acl), addr) == -1) {
397 mdb_warn("failed to read acl at %p", addr);
398 return (WALK_DONE);
399 }
400
401 wsp->walk_addr = (uintptr_t)acl.acl_ic_next;
402
403 return (wsp->walk_callback(addr, &acl, acl_map[i].am_tag));
404 }
405
406 static void
acl_walk_fini(mdb_walk_state_t * wsp)407 acl_walk_fini(mdb_walk_state_t *wsp)
408 {
409 mdb_free(wsp->walk_data, sizeof (si_t));
410 }
411
412 static int
acl_cb(uintptr_t addr,const void * arg,void * data)413 acl_cb(uintptr_t addr, const void *arg, void *data)
414 {
415 ufs_ic_acl_t *aclp = (ufs_ic_acl_t *)arg;
416
417 mdb_printf("%?p %-16s %7#o %10d\n",
418 addr, (char *)data, aclp->acl_ic_perm, aclp->acl_ic_who);
419
420 return (WALK_NEXT);
421 }
422
423 /*ARGSUSED*/
424 static int
acl_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)425 acl_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
426 {
427 if (!(flags & DCMD_ADDRSPEC))
428 return (DCMD_USAGE);
429
430 if (argc != 0)
431 return (DCMD_USAGE);
432
433 if (DCMD_HDRSPEC(flags)) {
434 mdb_printf("%<u>%?s %-16s %7s %10s%</u>\n",
435 "ADDR", "TAG", "PERM", "WHO");
436 }
437
438 if (mdb_pwalk("acl", (mdb_walk_cb_t)acl_cb, NULL, addr) == -1) {
439 mdb_warn("can't walk acls of inode %p", addr);
440 return (DCMD_ERR);
441 }
442
443 return (DCMD_OK);
444 }
445
446
447 static int
cg_walk_init(mdb_walk_state_t * wsp)448 cg_walk_init(mdb_walk_state_t *wsp)
449 {
450 if (mdb_layered_walk("buf", wsp) == -1) {
451 mdb_warn("couldn't walk bio buf hash");
452 return (WALK_ERR);
453 }
454
455 return (WALK_NEXT);
456 }
457
458 static int
cg_walk_step(mdb_walk_state_t * wsp)459 cg_walk_step(mdb_walk_state_t *wsp)
460 {
461 uintptr_t addr = (uintptr_t)((const buf_t *)wsp->walk_layer)->b_un.b_cg;
462 struct cg cg;
463
464 if (mdb_vread(&cg, sizeof (cg), addr) == -1) {
465 mdb_warn("failed to read cg struct at %p", addr);
466 return (WALK_ERR);
467 }
468
469 if (cg.cg_magic != CG_MAGIC)
470 return (WALK_NEXT);
471
472 return (wsp->walk_callback(addr, &cg, wsp->walk_cbdata));
473 }
474
475 static void
pbits(const uchar_t * cp,const int max,const int linelen)476 pbits(const uchar_t *cp, const int max, const int linelen)
477 {
478 int i, j, len;
479 char entry[40];
480 int linecnt = -1;
481
482 for (i = 0; i < max; i++) {
483 if (isset(cp, i)) {
484 len = mdb_snprintf(entry, sizeof (entry), "%d", i);
485 j = i;
486 while ((i + 1) < max && isset(cp, i+1))
487 i++;
488 if (i != j)
489 len += mdb_snprintf(entry + len,
490 sizeof (entry) - len, "-%d", i);
491
492 if (linecnt == -1) {
493 /* first entry */
494 mdb_printf("%s", entry);
495 linecnt = linelen - len;
496 } else if (linecnt - (len + 3) > 0) {
497 /* subsequent entry on same line */
498 mdb_printf(", %s", entry);
499 linecnt -= len + 2;
500 } else {
501 /* subsequent enty on new line */
502 mdb_printf(",\n%s", entry);
503 linecnt = linelen - len;
504 }
505 }
506 }
507 mdb_printf("\n");
508 }
509
510 /*ARGSUSED*/
511 static int
cg(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)512 cg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
513 {
514 uint_t verbose = FALSE;
515 struct cg cg;
516 struct cg *cgp = &cg;
517 size_t size;
518 int i, j, cnt, off;
519 int32_t *blktot;
520 short *blks;
521
522 if (!(flags & DCMD_ADDRSPEC)) {
523 if (mdb_walk_dcmd("cg", "cg", argc, argv) == -1) {
524 mdb_warn("can't walk cylinder group structs");
525 return (DCMD_ERR);
526 }
527 return (DCMD_OK);
528 }
529
530 if (mdb_getopts(argc, argv,
531 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc)
532 return (DCMD_USAGE);
533
534 if (mdb_vread(cgp, sizeof (cg), addr) == -1) {
535 mdb_warn("failed to read cg struct at %p", addr);
536 return (DCMD_ERR);
537 }
538
539 if (!verbose) {
540 if (DCMD_HDRSPEC(flags))
541 mdb_printf("%<u>%4s %?s %10s %10s %10s %10s%</u>\n",
542 "CGX", "CG", "NDIR", "NBFREE", "NIFREE", "NFFREE");
543
544 mdb_printf("%4d %?p %10d %10d %10d %10d\n", cgp->cg_cgx,
545 addr, cgp->cg_cs.cs_ndir, cgp->cg_cs.cs_nbfree,
546 cgp->cg_cs.cs_nifree, cgp->cg_cs.cs_nffree);
547
548 return (DCMD_OK);
549 }
550
551 /*
552 * Verbose: produce output similiar to "fstyp -v".
553 */
554 if (cgp->cg_btotoff >= cgp->cg_nextfreeoff ||
555 cgp->cg_boff >= cgp->cg_nextfreeoff ||
556 cgp->cg_iusedoff >= cgp->cg_nextfreeoff ||
557 cgp->cg_freeoff >= cgp->cg_nextfreeoff) {
558 mdb_warn("struct cg at %p seems broken\n", addr);
559 return (DCMD_ERR);
560 }
561
562 size = cgp->cg_nextfreeoff;
563 cgp = mdb_alloc(size, UM_SLEEP);
564
565 if (mdb_vread(cgp, size, addr) == -1) {
566 mdb_warn("failed to read struct cg and maps at %p", addr);
567 mdb_free(cgp, size);
568 return (DCMD_ERR);
569 }
570
571 mdb_printf("%<b>cg %d (%0?p)%</b>\n", cgp->cg_cgx, addr);
572
573 mdb_inc_indent(4);
574
575 mdb_printf("time:\t%Y\n", cgp->cg_time);
576 mdb_printf("ndir:\t%d\n", cgp->cg_cs.cs_ndir);
577 mdb_printf("nbfree:\t%d\n", cgp->cg_cs.cs_nbfree);
578 mdb_printf("nifree:\t%d\n", cgp->cg_cs.cs_nifree);
579 mdb_printf("nffree:\t%d\n", cgp->cg_cs.cs_nffree);
580
581 mdb_printf("frsum:");
582 for (i = 1; i < MAXFRAG; i++)
583 mdb_printf("\t%d", cgp->cg_frsum[i]);
584 mdb_printf("\n");
585
586 off = cgp->cg_iusedoff;
587 mdb_printf("used inode map (%0?p):\n", (char *)addr + off);
588 mdb_inc_indent(4);
589 pbits((uchar_t *)cgp + off, cgp->cg_niblk / sizeof (char), 72);
590 mdb_dec_indent(4);
591
592 off = cgp->cg_freeoff;
593 mdb_printf("free block map (%0?p):\n", (char *)addr + off);
594 mdb_inc_indent(4);
595 pbits((uchar_t *)cgp + off, cgp->cg_ndblk / sizeof (char), 72);
596 mdb_dec_indent(4);
597
598 /* LINTED - alignment */
599 blktot = (int32_t *)((char *)cgp + cgp->cg_btotoff);
600 /* LINTED - alignment */
601 blks = (short *)((char *)cgp + cgp->cg_boff);
602 cnt = (cgp->cg_iusedoff - cgp->cg_boff) / cgp->cg_ncyl / sizeof (short);
603 mdb_printf("free block positions:\n");
604 mdb_inc_indent(4);
605
606 for (i = 0; i < cgp->cg_ncyl; i++) {
607 mdb_printf("c%d:\t(%d)\t", i, blktot[i]);
608 for (j = 0; j < cnt; j++)
609 mdb_printf(" %d", blks[i*cnt + j]);
610 mdb_printf("\n");
611 }
612 mdb_dec_indent(4);
613
614 mdb_printf("\n");
615 mdb_dec_indent(4);
616
617 mdb_free(cgp, size);
618
619 return (DCMD_OK);
620 }
621
622 void
inode_cache_help(void)623 inode_cache_help(void)
624 {
625 mdb_printf(
626 "Displays cached inode_t. If an address, an inode number and/or a\n"
627 "device is specified, searches inode cache for inodes which match\n"
628 "the specified criteria. Prints nothing but the address, if\n"
629 "output is a pipe.\n"
630 "\n"
631 "Options:\n"
632 " -d device Filter out inodes, which reside on the specified"
633 " device.\n"
634 " -i inumber Filter out inodes with the specified inode"
635 " number.\n");
636 }
637
638 /*
639 * MDB module linkage
640 */
641 static const mdb_dcmd_t dcmds[] = {
642 { "inode_cache", "?[-d device] [-i inumber]",
643 "search/display inodes from inode cache",
644 inode_cache, inode_cache_help },
645 { "inode", ":[-v]", "display summarized inode_t", inode },
646 { "acl", ":", "given an inode, display its in core acl's", acl_dcmd },
647 { "cg", "?[-v]", "display a summarized cylinder group structure", cg },
648 { "mapentry", ":", "dumps ufslog mapentry", mapentry_dcmd },
649 { "mapstats", ":", "dumps ufslog stats", mapstats_dcmd },
650 { NULL }
651 };
652
653 static const mdb_walker_t walkers[] = {
654 { "inode_cache", "walk inode cache",
655 inode_walk_init, inode_walk_step, inode_walk_fini },
656 { "acl", "given an inode, walk chains of in core acl's",
657 acl_walk_init, acl_walk_step, acl_walk_fini },
658 { "cg", "walk cg's in bio buffer cache",
659 cg_walk_init, cg_walk_step, NULL },
660 { "ufslogmap", "walk map entries in a ufs_log mt_map",
661 ufslogmap_walk_init, ufslogmap_walk_step, NULL },
662 { NULL }
663 };
664
665 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
666
667 const mdb_modinfo_t *
_mdb_init(void)668 _mdb_init(void)
669 {
670 return (&modinfo);
671 }
672