Print this page
NEX-19993 mdb zfs_params output contains obsolete symbols
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9752 backport illumos 6950 ARC should cache compressed data
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
6950 ARC should cache compressed data
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Don Brady <don.brady@intel.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
6289 ::dbuf dcmd misaligned output
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-3165 need some dedup improvements
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-3165 segregate ddt in arc
NEX-3079 port illumos ARC improvements
4370 avoid transmitting holes during zfs send
4371 DMU code clean up
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Approved by: Garrett D'Amore <garrett@damore.org>
Fix up some merges where we wanted the upstream version.
Fixup merge results
re #13660 rb4549 ALUA mode: `/usr/demo/comstar/bin/aluaadm enable 1` sets "ALUA Node" = 0
re 13697 update ::zfs_params dcmd
Reviewed by: <Boris.Protopopov@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/mdb/common/modules/zfs/zfs.c
+++ new/usr/src/cmd/mdb/common/modules/zfs/zfs.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2019 Nexenta Systems, Inc.
24 24 * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
25 25 * Copyright (c) 2017, Joyent, Inc. All rights reserved.
26 26 */
27 27
28 28 /* Portions Copyright 2010 Robert Milkowski */
29 29
30 30 #include <mdb/mdb_ctf.h>
31 31 #include <sys/zfs_context.h>
32 32 #include <sys/mdb_modapi.h>
33 33 #include <sys/dbuf.h>
34 34 #include <sys/dmu_objset.h>
35 35 #include <sys/dsl_dir.h>
36 36 #include <sys/dsl_pool.h>
37 37 #include <sys/metaslab_impl.h>
38 38 #include <sys/space_map.h>
39 39 #include <sys/list.h>
40 40 #include <sys/vdev_impl.h>
41 41 #include <sys/zap_leaf.h>
42 42 #include <sys/zap_impl.h>
43 43 #include <ctype.h>
44 44 #include <sys/zfs_acl.h>
45 45 #include <sys/sa_impl.h>
46 46 #include <sys/multilist.h>
47 47
48 48 #ifdef _KERNEL
49 49 #define ZFS_OBJ_NAME "zfs"
50 50 extern int64_t mdb_gethrtime(void);
51 51 #else
52 52 #define ZFS_OBJ_NAME "libzpool.so.1"
53 53 #endif
54 54
55 55 #define ZFS_STRUCT "struct " ZFS_OBJ_NAME "`"
56 56
57 57 #ifndef _KERNEL
58 58 int aok;
59 59 #endif
60 60
61 61 enum spa_flags {
62 62 SPA_FLAG_CONFIG = 1 << 0,
63 63 SPA_FLAG_VDEVS = 1 << 1,
64 64 SPA_FLAG_ERRORS = 1 << 2,
65 65 SPA_FLAG_METASLAB_GROUPS = 1 << 3,
66 66 SPA_FLAG_METASLABS = 1 << 4,
67 67 SPA_FLAG_HISTOGRAMS = 1 << 5
68 68 };
69 69
70 70 /*
71 71 * If any of these flags are set, call spa_vdevs in spa_print
72 72 */
73 73 #define SPA_FLAG_ALL_VDEV \
74 74 (SPA_FLAG_VDEVS | SPA_FLAG_ERRORS | SPA_FLAG_METASLAB_GROUPS | \
75 75 SPA_FLAG_METASLABS)
76 76
77 77 static int
78 78 getmember(uintptr_t addr, const char *type, mdb_ctf_id_t *idp,
79 79 const char *member, int len, void *buf)
80 80 {
81 81 mdb_ctf_id_t id;
82 82 ulong_t off;
83 83 char name[64];
84 84
85 85 if (idp == NULL) {
86 86 if (mdb_ctf_lookup_by_name(type, &id) == -1) {
87 87 mdb_warn("couldn't find type %s", type);
88 88 return (DCMD_ERR);
89 89 }
90 90 idp = &id;
91 91 } else {
92 92 type = name;
93 93 mdb_ctf_type_name(*idp, name, sizeof (name));
94 94 }
95 95
96 96 if (mdb_ctf_offsetof(*idp, member, &off) == -1) {
97 97 mdb_warn("couldn't find member %s of type %s\n", member, type);
98 98 return (DCMD_ERR);
99 99 }
100 100 if (off % 8 != 0) {
101 101 mdb_warn("member %s of type %s is unsupported bitfield",
102 102 member, type);
103 103 return (DCMD_ERR);
104 104 }
105 105 off /= 8;
106 106
107 107 if (mdb_vread(buf, len, addr + off) == -1) {
108 108 mdb_warn("failed to read %s from %s at %p",
109 109 member, type, addr + off);
110 110 return (DCMD_ERR);
111 111 }
112 112 /* mdb_warn("read %s from %s at %p+%llx\n", member, type, addr, off); */
113 113
114 114 return (0);
115 115 }
116 116
117 117 #define GETMEMB(addr, structname, member, dest) \
118 118 getmember(addr, ZFS_STRUCT structname, NULL, #member, \
119 119 sizeof (dest), &(dest))
120 120
121 121 #define GETMEMBID(addr, ctfid, member, dest) \
122 122 getmember(addr, NULL, ctfid, #member, sizeof (dest), &(dest))
123 123
124 124 static boolean_t
125 125 strisprint(const char *cp)
126 126 {
127 127 for (; *cp; cp++) {
128 128 if (!isprint(*cp))
129 129 return (B_FALSE);
130 130 }
131 131 return (B_TRUE);
132 132 }
133 133
134 134 #define NICENUM_BUFLEN 6
135 135
136 136 static int
137 137 snprintfrac(char *buf, int len,
138 138 uint64_t numerator, uint64_t denom, int frac_digits)
139 139 {
140 140 int mul = 1;
141 141 int whole, frac, i;
142 142
143 143 for (i = frac_digits; i; i--)
144 144 mul *= 10;
145 145 whole = numerator / denom;
146 146 frac = mul * numerator / denom - mul * whole;
147 147 return (mdb_snprintf(buf, len, "%u.%0*u", whole, frac_digits, frac));
148 148 }
149 149
150 150 static void
151 151 mdb_nicenum(uint64_t num, char *buf)
152 152 {
153 153 uint64_t n = num;
154 154 int index = 0;
155 155 char *u;
156 156
157 157 while (n >= 1024) {
158 158 n = (n + (1024 / 2)) / 1024; /* Round up or down */
159 159 index++;
160 160 }
161 161
162 162 u = &" \0K\0M\0G\0T\0P\0E\0"[index*2];
163 163
164 164 if (index == 0) {
165 165 (void) mdb_snprintf(buf, NICENUM_BUFLEN, "%llu",
166 166 (u_longlong_t)n);
167 167 } else if (n < 10 && (num & (num - 1)) != 0) {
168 168 (void) snprintfrac(buf, NICENUM_BUFLEN,
169 169 num, 1ULL << 10 * index, 2);
170 170 strcat(buf, u);
171 171 } else if (n < 100 && (num & (num - 1)) != 0) {
172 172 (void) snprintfrac(buf, NICENUM_BUFLEN,
173 173 num, 1ULL << 10 * index, 1);
174 174 strcat(buf, u);
175 175 } else {
176 176 (void) mdb_snprintf(buf, NICENUM_BUFLEN, "%llu%s",
177 177 (u_longlong_t)n, u);
178 178 }
179 179 }
180 180
181 181 static int verbose;
182 182
183 183 static int
184 184 freelist_walk_init(mdb_walk_state_t *wsp)
185 185 {
186 186 if (wsp->walk_addr == NULL) {
187 187 mdb_warn("must supply starting address\n");
188 188 return (WALK_ERR);
189 189 }
190 190
191 191 wsp->walk_data = 0; /* Index into the freelist */
192 192 return (WALK_NEXT);
193 193 }
194 194
195 195 static int
196 196 freelist_walk_step(mdb_walk_state_t *wsp)
197 197 {
198 198 uint64_t entry;
199 199 uintptr_t number = (uintptr_t)wsp->walk_data;
200 200 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
201 201 "INVALID", "INVALID", "INVALID", "INVALID" };
202 202 int mapshift = SPA_MINBLOCKSHIFT;
203 203
204 204 if (mdb_vread(&entry, sizeof (entry), wsp->walk_addr) == -1) {
205 205 mdb_warn("failed to read freelist entry %p", wsp->walk_addr);
206 206 return (WALK_DONE);
207 207 }
208 208 wsp->walk_addr += sizeof (entry);
209 209 wsp->walk_data = (void *)(number + 1);
210 210
211 211 if (SM_DEBUG_DECODE(entry)) {
212 212 mdb_printf("DEBUG: %3u %10s: txg=%llu pass=%llu\n",
213 213 number,
214 214 ddata[SM_DEBUG_ACTION_DECODE(entry)],
215 215 SM_DEBUG_TXG_DECODE(entry),
216 216 SM_DEBUG_SYNCPASS_DECODE(entry));
217 217 } else {
218 218 mdb_printf("Entry: %3u offsets=%08llx-%08llx type=%c "
219 219 "size=%06llx", number,
220 220 SM_OFFSET_DECODE(entry) << mapshift,
221 221 (SM_OFFSET_DECODE(entry) + SM_RUN_DECODE(entry)) <<
222 222 mapshift,
223 223 SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
224 224 SM_RUN_DECODE(entry) << mapshift);
225 225 if (verbose)
226 226 mdb_printf(" (raw=%012llx)\n", entry);
227 227 mdb_printf("\n");
228 228 }
229 229 return (WALK_NEXT);
230 230 }
231 231
232 232 static int
233 233 mdb_dsl_dir_name(uintptr_t addr, char *buf)
234 234 {
235 235 static int gotid;
236 236 static mdb_ctf_id_t dd_id;
237 237 uintptr_t dd_parent;
238 238 char dd_myname[ZFS_MAX_DATASET_NAME_LEN];
239 239
240 240 if (!gotid) {
241 241 if (mdb_ctf_lookup_by_name(ZFS_STRUCT "dsl_dir",
242 242 &dd_id) == -1) {
243 243 mdb_warn("couldn't find struct dsl_dir");
244 244 return (DCMD_ERR);
245 245 }
246 246 gotid = TRUE;
247 247 }
248 248 if (GETMEMBID(addr, &dd_id, dd_parent, dd_parent) ||
249 249 GETMEMBID(addr, &dd_id, dd_myname, dd_myname)) {
250 250 return (DCMD_ERR);
251 251 }
252 252
253 253 if (dd_parent) {
254 254 if (mdb_dsl_dir_name(dd_parent, buf))
255 255 return (DCMD_ERR);
256 256 strcat(buf, "/");
257 257 }
258 258
259 259 if (dd_myname[0])
260 260 strcat(buf, dd_myname);
261 261 else
262 262 strcat(buf, "???");
263 263
264 264 return (0);
265 265 }
266 266
267 267 static int
268 268 objset_name(uintptr_t addr, char *buf)
269 269 {
270 270 static int gotid;
271 271 static mdb_ctf_id_t os_id, ds_id;
272 272 uintptr_t os_dsl_dataset;
273 273 char ds_snapname[ZFS_MAX_DATASET_NAME_LEN];
274 274 uintptr_t ds_dir;
275 275
276 276 buf[0] = '\0';
277 277
278 278 if (!gotid) {
279 279 if (mdb_ctf_lookup_by_name(ZFS_STRUCT "objset",
280 280 &os_id) == -1) {
281 281 mdb_warn("couldn't find struct objset");
282 282 return (DCMD_ERR);
283 283 }
284 284 if (mdb_ctf_lookup_by_name(ZFS_STRUCT "dsl_dataset",
285 285 &ds_id) == -1) {
286 286 mdb_warn("couldn't find struct dsl_dataset");
287 287 return (DCMD_ERR);
288 288 }
289 289
290 290 gotid = TRUE;
291 291 }
292 292
293 293 if (GETMEMBID(addr, &os_id, os_dsl_dataset, os_dsl_dataset))
294 294 return (DCMD_ERR);
295 295
296 296 if (os_dsl_dataset == 0) {
297 297 strcat(buf, "mos");
298 298 return (0);
299 299 }
300 300
301 301 if (GETMEMBID(os_dsl_dataset, &ds_id, ds_snapname, ds_snapname) ||
302 302 GETMEMBID(os_dsl_dataset, &ds_id, ds_dir, ds_dir)) {
303 303 return (DCMD_ERR);
304 304 }
305 305
306 306 if (ds_dir && mdb_dsl_dir_name(ds_dir, buf))
307 307 return (DCMD_ERR);
308 308
309 309 if (ds_snapname[0]) {
310 310 strcat(buf, "@");
311 311 strcat(buf, ds_snapname);
312 312 }
313 313 return (0);
314 314 }
315 315
316 316 static int
317 317 enum_lookup(char *type, int val, const char *prefix, size_t size, char *out)
318 318 {
319 319 const char *cp;
320 320 size_t len = strlen(prefix);
321 321 mdb_ctf_id_t enum_type;
322 322
323 323 if (mdb_ctf_lookup_by_name(type, &enum_type) != 0) {
324 324 mdb_warn("Could not find enum for %s", type);
325 325 return (-1);
326 326 }
327 327
328 328 if ((cp = mdb_ctf_enum_name(enum_type, val)) != NULL) {
329 329 if (strncmp(cp, prefix, len) == 0)
330 330 cp += len;
331 331 (void) strncpy(out, cp, size);
332 332 } else {
333 333 mdb_snprintf(out, size, "? (%d)", val);
334 334 }
335 335 return (0);
336 336 }
|
↓ open down ↓ |
303 lines elided |
↑ open up ↑ |
337 337
338 338 /* ARGSUSED */
339 339 static int
340 340 zfs_params(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
341 341 {
342 342 /*
343 343 * This table can be approximately generated by running:
344 344 * egrep "^[a-z0-9_]+ [a-z0-9_]+( =.*)?;" *.c | cut -d ' ' -f 2
345 345 */
346 346 static const char *params[] = {
347 - "arc_reduce_dnlc_percent",
348 347 "arc_lotsfree_percent",
349 - "zfs_dirty_data_max",
350 - "zfs_dirty_data_sync",
351 - "zfs_delay_max_ns",
352 - "zfs_delay_min_dirty_percent",
353 - "zfs_delay_scale",
354 - "zfs_vdev_max_active",
355 - "zfs_vdev_sync_read_min_active",
356 - "zfs_vdev_sync_read_max_active",
357 - "zfs_vdev_sync_write_min_active",
358 - "zfs_vdev_sync_write_max_active",
359 - "zfs_vdev_async_read_min_active",
360 - "zfs_vdev_async_read_max_active",
361 - "zfs_vdev_async_write_min_active",
362 - "zfs_vdev_async_write_max_active",
363 - "zfs_vdev_scrub_min_active",
364 - "zfs_vdev_scrub_max_active",
365 - "zfs_vdev_async_write_active_min_dirty_percent",
366 - "zfs_vdev_async_write_active_max_dirty_percent",
348 + "arc_pages_pp_reserve",
349 + "arc_reduce_dnlc_percent",
350 + "arc_swapfs_reserve",
351 + "arc_zio_arena_free_shift",
352 + "dbuf_cache_hiwater_pct",
353 + "dbuf_cache_lowater_pct",
354 + "dbuf_cache_max_bytes",
355 + "dbuf_cache_shift",
356 + "dbuf_metadata_cache_max_bytes",
357 + "dbuf_metadata_cache_overflow",
358 + "dbuf_metadata_cache_shift",
359 + "ddt_zap_indirect_blockshift",
360 + "ddt_zap_leaf_blockshift",
361 + "ditto_same_vdev_distance_shift",
362 + "dmu_find_threads",
363 + "dmu_rescan_dnode_threshold",
364 + "dsl_scan_delay_completion",
365 + "fzap_default_block_shift",
366 + "krrp_debug",
367 + "l2arc_feed_again",
368 + "l2arc_feed_min_ms",
369 + "l2arc_feed_secs",
370 + "l2arc_headroom",
371 + "l2arc_headroom_boost",
372 + "l2arc_noprefetch",
373 + "l2arc_norw",
374 + "l2arc_rebuild_enabled",
375 + "l2arc_write_boost",
376 + "l2arc_write_max",
377 + "last_free_memory",
378 + "last_free_reason",
379 + "metaslab_aliquot",
380 + "metaslab_alloc_dva_algorithm",
381 + "metaslab_bias_enabled",
382 + "metaslab_debug_load",
383 + "metaslab_debug_unload",
384 + "metaslab_df_alloc_threshold",
385 + "metaslab_df_free_pct",
386 + "metaslab_fragmentation_factor_enabled",
387 + "metaslab_gang_bang",
388 + "metaslab_lba_weighting_enabled",
389 + "metaslab_load_pct",
390 + "metaslab_min_alloc_size",
391 + "metaslab_ndf_clump_shift",
392 + "metaslab_preload_enabled",
393 + "metaslab_preload_limit",
394 + "metaslab_trace_enabled",
395 + "metaslab_trace_max_entries",
396 + "metaslab_unload_delay",
397 + "metaslabs_per_vdev",
398 + "nms_worm_transition_time",
399 + "rrw_tsd_key",
400 + "send_holes_without_birth_time",
367 401 "spa_asize_inflation",
402 + "spa_avg_stat_update_ticks",
403 + "spa_load_verify_data",
404 + "spa_load_verify_maxinflight",
405 + "spa_load_verify_metadata",
406 + "spa_max_replication_override",
407 + "spa_min_latency_delta",
408 + "spa_min_slop",
409 + "spa_mode_global",
410 + "spa_namespace_lock",
411 + "spa_obj_mtx_sz",
412 + "spa_rotor_load_adjusting",
413 + "spa_rotor_use_weight",
414 + "spa_slop_shift",
415 + "spa_special_factor",
416 + "spa_special_to_normal_delta",
417 + "spa_special_to_normal_ratio",
418 + "spa_static_routing_percentage",
419 + "space_map_blksz",
420 + "vdev_mirror_shift",
421 + "vdev_raidz_default_to_general",
422 + "wbc_arc_enabled",
423 + "wbc_force_trigger",
424 + "wbc_idle_delay_ms",
425 + "wbc_max_move_tasks_count",
426 + "wbc_min_move_tasks_count",
427 + "wbc_mv_cancel_threshold_cap",
428 + "wbc_mv_cancel_threshold_initial",
429 + "wbc_mv_cancel_threshold_step",
430 + "wbc_spa_util_high_wm",
431 + "wbc_spa_util_low_wm",
432 + "wbc_throttle_move_delay_ms",
433 + "wbc_update_statistics_interval_ms",
434 + "wbc_window_roll_delay_ms",
435 + "zcr_blksz_max",
436 + "zcr_blksz_min",
437 + "zfs_abd_chunk_size",
438 + "zfs_abd_scatter_enabled",
439 + "zfs_arc_average_blocksize",
440 + "zfs_arc_ddt_limit",
441 + "zfs_arc_evict_batch_limit",
442 + "zfs_arc_grow_retry",
368 443 "zfs_arc_max",
444 + "zfs_arc_meta_limit",
445 + "zfs_arc_meta_min",
369 446 "zfs_arc_min",
370 - "arc_shrink_shift",
371 - "zfs_mdcomp_disable",
372 - "zfs_prefetch_disable",
373 - "zfetch_max_streams",
374 - "zfetch_min_sec_reap",
375 - "zfetch_block_cap",
376 - "zfetch_array_rd_sz",
447 + "zfs_arc_p_min_shift",
448 + "zfs_arc_segregate_ddt",
449 + "zfs_arc_shrink_shift",
450 + "zfs_commit_timeout_pct",
451 + "zfs_compressed_arc_enabled",
452 + "zfs_condense_pct",
453 + "zfs_dbgmsg_maxsize",
454 + "zfs_dbgmsg_size",
455 + "zfs_dbuf_evict_key",
456 + "zfs_ddt_byte_ceiling",
457 + "zfs_ddt_limit_type",
458 + "zfs_ddts_msize",
459 + "zfs_deadman_checktime_ms",
460 + "zfs_deadman_enabled",
461 + "zfs_deadman_synctime_ms",
462 + "zfs_dedup_prefetch",
377 463 "zfs_default_bs",
378 464 "zfs_default_ibs",
379 - "metaslab_aliquot",
380 - "reference_tracking_enable",
381 - "reference_history",
382 - "spa_max_replication_override",
383 - "spa_mode_global",
465 + "zfs_delay_max_ns",
466 + "zfs_delay_min_dirty_percent",
467 + "zfs_delay_resolution_ns",
468 + "zfs_delay_scale",
469 + "zfs_dequeue_run_bonus_ms",
470 + "zfs_dirty_data_max",
471 + "zfs_dirty_data_max_max",
472 + "zfs_dirty_data_max_percent",
473 + "zfs_dirty_data_sync",
474 + "zfs_do_async_free",
475 + "zfs_fastflush",
384 476 "zfs_flags",
385 - "zfs_txg_timeout",
386 - "zfs_vdev_cache_max",
387 - "zfs_vdev_cache_size",
388 - "zfs_vdev_cache_bshift",
389 - "vdev_mirror_shift",
390 - "zfs_scrub_limit",
477 + "zfs_flush_ntasks",
478 + "zfs_free_bpobj_enabled",
479 + "zfs_free_leak_on_eio",
480 + "zfs_free_max_blocks",
481 + "zfs_free_min_time_ms",
482 + "zfs_fsync_sync_cnt",
483 + "zfs_fsyncer_key",
484 + "zfs_immediate_write_sz",
485 + "zfs_l2arc_async_evict",
486 + "zfs_li",
487 + "zfs_lua_check_instrlimit_interval",
488 + "zfs_lua_max_instrlimit",
489 + "zfs_lua_max_memlimit",
490 + "zfs_max_recordsize",
491 + "zfs_mdcomp_disable",
492 + "zfs_metaslab_condense_block_threshold",
493 + "zfs_metaslab_fragmentation_threshold",
494 + "zfs_metaslab_segment_weight_enabled",
495 + "zfs_metaslab_switch_threshold",
496 + "zfs_mg_fragmentation_threshold",
497 + "zfs_mg_noalloc_threshold",
498 + "zfs_multilist_num_sublists",
391 499 "zfs_no_scrub_io",
392 500 "zfs_no_scrub_prefetch",
393 - "zfs_vdev_aggregation_limit",
394 - "fzap_default_block_shift",
395 - "zfs_immediate_write_sz",
396 - "zfs_read_chunk_size",
397 501 "zfs_nocacheflush",
502 + "zfs_nopwrite_enabled",
503 + "zfs_pd_bytes_max",
504 + "zfs_per_txg_dirty_frees_percent",
505 + "zfs_prefetch_disable",
506 + "zfs_read_chunk_size",
507 + "zfs_recover",
508 + "zfs_recv_queue_length",
509 + "zfs_redundant_metadata_most_ditto_level",
510 + "zfs_resilver_min_time_ms",
511 + "zfs_root_latency_alpha",
512 + "zfs_scan_checkpoint_intval",
513 + "zfs_scan_dequeue_min",
514 + "zfs_scan_dequeue_run_target_ms",
515 + "zfs_scan_direct",
516 + "zfs_scan_fill_weight",
517 + "zfs_scan_max_ext_gap",
518 + "zfs_scan_mem_lim_fact",
519 + "zfs_scan_mem_lim_min",
520 + "zfs_scan_mem_lim_soft_fact",
521 + "zfs_scan_mem_lim_soft_max",
522 + "zfs_scan_min_time_ms",
523 + "zfs_scrub_limit",
524 + "zfs_send_corrupt_data",
525 + "zfs_send_queue_length",
526 + "zfs_send_set_freerecords_bit",
527 + "zfs_send_timeout",
528 + "zfs_share_lock",
529 + "zfs_smartcomp_interval",
530 + "zfs_smartcomp_interval_exp",
531 + "zfs_smartcomp_threshold_factor",
532 + "zfs_sync_pass_deferred_free",
533 + "zfs_sync_pass_dont_compress",
534 + "zfs_sync_pass_rewrite",
535 + "zfs_sync_taskq_batch_pct",
536 + "zfs_top_maxinflight",
537 + "zfs_trim",
538 + "zfs_trim_min_ext_sz",
539 + "zfs_txg_timeout",
540 + "zfs_vdev_aggregation_limit",
541 + "zfs_vdev_async_read_max_active",
542 + "zfs_vdev_async_read_min_active",
543 + "zfs_vdev_async_write_active_max_dirty_percent",
544 + "zfs_vdev_async_write_active_min_dirty_percent",
545 + "zfs_vdev_async_write_max_active",
546 + "zfs_vdev_async_write_min_active",
547 + "zfs_vdev_cache_bshift",
548 + "zfs_vdev_cache_max",
549 + "zfs_vdev_cache_size",
550 + "zfs_vdev_max_active",
551 + "zfs_vdev_queue_depth_pct",
552 + "zfs_vdev_read_gap_limit",
553 + "zfs_vdev_resilver_max_active",
554 + "zfs_vdev_resilver_min_active",
555 + "zfs_vdev_scrub_max_active",
556 + "zfs_vdev_scrub_min_active",
557 + "zfs_vdev_sync_read_max_active",
558 + "zfs_vdev_sync_read_min_active",
559 + "zfs_vdev_sync_write_max_active",
560 + "zfs_vdev_sync_write_min_active",
561 + "zfs_vdev_write_gap_limit",
562 + "zfs_vn_rele_max_tasks",
563 + "zfs_vs_latency_alpha",
564 + "zfs_wbc_data_max",
565 + "zfs_wbc_schedtmo",
566 + "zfs_write_implies_delete_child",
567 + "zfs_zil_clean_taskq_maxalloc",
568 + "zfs_zil_clean_taskq_minalloc",
569 + "zfs_zil_clean_taskq_nthr_pct",
398 570 "zil_replay_disable",
399 - "metaslab_gang_bang",
400 - "metaslab_df_alloc_threshold",
401 - "metaslab_df_free_pct",
571 + "zil_slog_bulk",
572 + "zio_buf_debug_limit",
573 + "zio_dva_throttle_enabled",
574 + "zio_faulty_vdev_delay_us",
575 + "zio_faulty_vdev_enabled",
576 + "zio_faulty_vdev_guid",
402 577 "zio_injection_enabled",
403 578 "zvol_immediate_write_sz",
579 + "zvol_maxphys",
580 + "zvol_unmap_enabled",
581 + "zvol_unmap_sync_enabled",
404 582 };
405 583
406 584 for (int i = 0; i < sizeof (params) / sizeof (params[0]); i++) {
407 585 int sz;
408 586 uint64_t val64;
409 587 uint32_t *val32p = (uint32_t *)&val64;
410 588
411 589 sz = mdb_readvar(&val64, params[i]);
412 590 if (sz == 4) {
413 591 mdb_printf("%s = 0x%x\n", params[i], *val32p);
414 592 } else if (sz == 8) {
415 593 mdb_printf("%s = 0x%llx\n", params[i], val64);
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
416 594 } else {
417 595 mdb_warn("variable %s not found", params[i]);
418 596 }
419 597 }
420 598
421 599 return (DCMD_OK);
422 600 }
423 601
424 602 /* ARGSUSED */
425 603 static int
426 -dva(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
427 -{
428 - dva_t dva;
429 - if (mdb_vread(&dva, sizeof (dva_t), addr) == -1) {
430 - mdb_warn("failed to read dva_t");
431 - return (DCMD_ERR);
432 - }
433 - mdb_printf("<%llu:%llx:%llx>\n",
434 - (u_longlong_t)DVA_GET_VDEV(&dva),
435 - (u_longlong_t)DVA_GET_OFFSET(&dva),
436 - (u_longlong_t)DVA_GET_ASIZE(&dva));
437 -
438 - return (DCMD_OK);
439 -}
440 -
441 -/* ARGSUSED */
442 -static int
443 604 blkptr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
444 605 {
445 606 char type[80], checksum[80], compress[80];
446 607 blkptr_t blk, *bp = &blk;
447 608 char buf[BP_SPRINTF_LEN];
448 609
449 610 if (mdb_vread(&blk, sizeof (blkptr_t), addr) == -1) {
450 611 mdb_warn("failed to read blkptr_t");
451 612 return (DCMD_ERR);
452 613 }
453 614
454 615 if (enum_lookup("enum dmu_object_type", BP_GET_TYPE(bp), "DMU_OT_",
455 616 sizeof (type), type) == -1 ||
456 617 enum_lookup("enum zio_checksum", BP_GET_CHECKSUM(bp),
457 618 "ZIO_CHECKSUM_", sizeof (checksum), checksum) == -1 ||
458 619 enum_lookup("enum zio_compress", BP_GET_COMPRESS(bp),
459 620 "ZIO_COMPRESS_", sizeof (compress), compress) == -1) {
460 621 mdb_warn("Could not find blkptr enumerated types");
461 622 return (DCMD_ERR);
462 623 }
463 624
464 625 SNPRINTF_BLKPTR(mdb_snprintf, '\n', buf, sizeof (buf), bp, type,
465 626 checksum, compress);
466 627
467 628 mdb_printf("%s\n", buf);
468 629
469 630 return (DCMD_OK);
470 631 }
471 632
472 633 typedef struct mdb_dmu_buf_impl {
473 634 struct {
474 635 uint64_t db_object;
475 636 uintptr_t db_data;
476 637 } db;
477 638 uintptr_t db_objset;
478 639 uint64_t db_level;
479 640 uint64_t db_blkid;
480 641 struct {
481 642 uint64_t rc_count;
482 643 } db_holds;
483 644 } mdb_dmu_buf_impl_t;
484 645
485 646 /* ARGSUSED */
486 647 static int
487 648 dbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
488 649 {
489 650 mdb_dmu_buf_impl_t db;
490 651 char objectname[32];
491 652 char blkidname[32];
492 653 char path[ZFS_MAX_DATASET_NAME_LEN];
493 654 int ptr_width = (int)(sizeof (void *)) * 2;
494 655
495 656 if (DCMD_HDRSPEC(flags))
496 657 mdb_printf("%*s %8s %3s %9s %5s %s\n",
497 658 ptr_width, "addr", "object", "lvl", "blkid", "holds", "os");
498 659
499 660 if (mdb_ctf_vread(&db, ZFS_STRUCT "dmu_buf_impl", "mdb_dmu_buf_impl_t",
500 661 addr, 0) == -1)
501 662 return (DCMD_ERR);
502 663
503 664 if (db.db.db_object == DMU_META_DNODE_OBJECT)
504 665 (void) strcpy(objectname, "mdn");
505 666 else
506 667 (void) mdb_snprintf(objectname, sizeof (objectname), "%llx",
507 668 (u_longlong_t)db.db.db_object);
508 669
509 670 if (db.db_blkid == DMU_BONUS_BLKID)
510 671 (void) strcpy(blkidname, "bonus");
511 672 else
512 673 (void) mdb_snprintf(blkidname, sizeof (blkidname), "%llx",
513 674 (u_longlong_t)db.db_blkid);
514 675
515 676 if (objset_name(db.db_objset, path)) {
516 677 return (DCMD_ERR);
517 678 }
518 679
519 680 mdb_printf("%*p %8s %3u %9s %5llu %s\n", ptr_width, addr,
520 681 objectname, (int)db.db_level, blkidname,
521 682 db.db_holds.rc_count, path);
522 683
523 684 return (DCMD_OK);
524 685 }
525 686
526 687 /* ARGSUSED */
527 688 static int
528 689 dbuf_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
529 690 {
530 691 #define HISTOSZ 32
531 692 uintptr_t dbp;
532 693 dmu_buf_impl_t db;
533 694 dbuf_hash_table_t ht;
534 695 uint64_t bucket, ndbufs;
535 696 uint64_t histo[HISTOSZ];
536 697 uint64_t histo2[HISTOSZ];
537 698 int i, maxidx;
538 699
539 700 if (mdb_readvar(&ht, "dbuf_hash_table") == -1) {
540 701 mdb_warn("failed to read 'dbuf_hash_table'");
541 702 return (DCMD_ERR);
542 703 }
543 704
544 705 for (i = 0; i < HISTOSZ; i++) {
545 706 histo[i] = 0;
546 707 histo2[i] = 0;
547 708 }
548 709
549 710 ndbufs = 0;
550 711 for (bucket = 0; bucket < ht.hash_table_mask+1; bucket++) {
551 712 int len;
552 713
553 714 if (mdb_vread(&dbp, sizeof (void *),
554 715 (uintptr_t)(ht.hash_table+bucket)) == -1) {
555 716 mdb_warn("failed to read hash bucket %u at %p",
556 717 bucket, ht.hash_table+bucket);
557 718 return (DCMD_ERR);
558 719 }
559 720
560 721 len = 0;
561 722 while (dbp != 0) {
562 723 if (mdb_vread(&db, sizeof (dmu_buf_impl_t),
563 724 dbp) == -1) {
564 725 mdb_warn("failed to read dbuf at %p", dbp);
565 726 return (DCMD_ERR);
566 727 }
567 728 dbp = (uintptr_t)db.db_hash_next;
568 729 for (i = MIN(len, HISTOSZ - 1); i >= 0; i--)
569 730 histo2[i]++;
570 731 len++;
571 732 ndbufs++;
572 733 }
573 734
574 735 if (len >= HISTOSZ)
575 736 len = HISTOSZ-1;
576 737 histo[len]++;
577 738 }
578 739
579 740 mdb_printf("hash table has %llu buckets, %llu dbufs "
580 741 "(avg %llu buckets/dbuf)\n",
581 742 ht.hash_table_mask+1, ndbufs,
582 743 (ht.hash_table_mask+1)/ndbufs);
583 744
584 745 mdb_printf("\n");
585 746 maxidx = 0;
586 747 for (i = 0; i < HISTOSZ; i++)
587 748 if (histo[i] > 0)
588 749 maxidx = i;
589 750 mdb_printf("hash chain length number of buckets\n");
590 751 for (i = 0; i <= maxidx; i++)
591 752 mdb_printf("%u %llu\n", i, histo[i]);
592 753
593 754 mdb_printf("\n");
594 755 maxidx = 0;
595 756 for (i = 0; i < HISTOSZ; i++)
596 757 if (histo2[i] > 0)
597 758 maxidx = i;
598 759 mdb_printf("hash chain depth number of dbufs\n");
599 760 for (i = 0; i <= maxidx; i++)
600 761 mdb_printf("%u or more %llu %llu%%\n",
601 762 i, histo2[i], histo2[i]*100/ndbufs);
602 763
603 764
604 765 return (DCMD_OK);
605 766 }
606 767
607 768 #define CHAIN_END 0xffff
608 769 /*
609 770 * ::zap_leaf [-v]
610 771 *
611 772 * Print a zap_leaf_phys_t, assumed to be 16k
612 773 */
613 774 /* ARGSUSED */
614 775 static int
615 776 zap_leaf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
616 777 {
617 778 char buf[16*1024];
618 779 int verbose = B_FALSE;
619 780 int four = B_FALSE;
620 781 dmu_buf_t l_dbuf;
621 782 zap_leaf_t l;
622 783 zap_leaf_phys_t *zlp = (void *)buf;
623 784 int i;
624 785
625 786 if (mdb_getopts(argc, argv,
626 787 'v', MDB_OPT_SETBITS, TRUE, &verbose,
627 788 '4', MDB_OPT_SETBITS, TRUE, &four,
628 789 NULL) != argc)
629 790 return (DCMD_USAGE);
630 791
631 792 l_dbuf.db_data = zlp;
632 793 l.l_dbuf = &l_dbuf;
633 794 l.l_bs = 14; /* assume 16k blocks */
634 795 if (four)
635 796 l.l_bs = 12;
636 797
637 798 if (!(flags & DCMD_ADDRSPEC)) {
638 799 return (DCMD_USAGE);
639 800 }
640 801
641 802 if (mdb_vread(buf, sizeof (buf), addr) == -1) {
642 803 mdb_warn("failed to read zap_leaf_phys_t at %p", addr);
643 804 return (DCMD_ERR);
644 805 }
645 806
646 807 if (zlp->l_hdr.lh_block_type != ZBT_LEAF ||
647 808 zlp->l_hdr.lh_magic != ZAP_LEAF_MAGIC) {
648 809 mdb_warn("This does not appear to be a zap_leaf_phys_t");
649 810 return (DCMD_ERR);
650 811 }
651 812
652 813 mdb_printf("zap_leaf_phys_t at %p:\n", addr);
653 814 mdb_printf(" lh_prefix_len = %u\n", zlp->l_hdr.lh_prefix_len);
654 815 mdb_printf(" lh_prefix = %llx\n", zlp->l_hdr.lh_prefix);
655 816 mdb_printf(" lh_nentries = %u\n", zlp->l_hdr.lh_nentries);
656 817 mdb_printf(" lh_nfree = %u\n", zlp->l_hdr.lh_nfree,
657 818 zlp->l_hdr.lh_nfree * 100 / (ZAP_LEAF_NUMCHUNKS(&l)));
658 819 mdb_printf(" lh_freelist = %u\n", zlp->l_hdr.lh_freelist);
659 820 mdb_printf(" lh_flags = %x (%s)\n", zlp->l_hdr.lh_flags,
660 821 zlp->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED ?
661 822 "ENTRIES_CDSORTED" : "");
662 823
663 824 if (verbose) {
664 825 mdb_printf(" hash table:\n");
665 826 for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++) {
666 827 if (zlp->l_hash[i] != CHAIN_END)
667 828 mdb_printf(" %u: %u\n", i, zlp->l_hash[i]);
668 829 }
669 830 }
670 831
671 832 mdb_printf(" chunks:\n");
672 833 for (i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) {
673 834 /* LINTED: alignment */
674 835 zap_leaf_chunk_t *zlc = &ZAP_LEAF_CHUNK(&l, i);
675 836 switch (zlc->l_entry.le_type) {
676 837 case ZAP_CHUNK_FREE:
677 838 if (verbose) {
678 839 mdb_printf(" %u: free; lf_next = %u\n",
679 840 i, zlc->l_free.lf_next);
680 841 }
681 842 break;
682 843 case ZAP_CHUNK_ENTRY:
683 844 mdb_printf(" %u: entry\n", i);
684 845 if (verbose) {
685 846 mdb_printf(" le_next = %u\n",
686 847 zlc->l_entry.le_next);
687 848 }
688 849 mdb_printf(" le_name_chunk = %u\n",
689 850 zlc->l_entry.le_name_chunk);
690 851 mdb_printf(" le_name_numints = %u\n",
691 852 zlc->l_entry.le_name_numints);
692 853 mdb_printf(" le_value_chunk = %u\n",
693 854 zlc->l_entry.le_value_chunk);
694 855 mdb_printf(" le_value_intlen = %u\n",
695 856 zlc->l_entry.le_value_intlen);
696 857 mdb_printf(" le_value_numints = %u\n",
697 858 zlc->l_entry.le_value_numints);
698 859 mdb_printf(" le_cd = %u\n",
699 860 zlc->l_entry.le_cd);
700 861 mdb_printf(" le_hash = %llx\n",
701 862 zlc->l_entry.le_hash);
702 863 break;
703 864 case ZAP_CHUNK_ARRAY:
704 865 mdb_printf(" %u: array", i);
705 866 if (strisprint((char *)zlc->l_array.la_array))
706 867 mdb_printf(" \"%s\"", zlc->l_array.la_array);
707 868 mdb_printf("\n");
708 869 if (verbose) {
709 870 int j;
710 871 mdb_printf(" ");
711 872 for (j = 0; j < ZAP_LEAF_ARRAY_BYTES; j++) {
712 873 mdb_printf("%02x ",
713 874 zlc->l_array.la_array[j]);
714 875 }
715 876 mdb_printf("\n");
716 877 }
717 878 if (zlc->l_array.la_next != CHAIN_END) {
718 879 mdb_printf(" lf_next = %u\n",
719 880 zlc->l_array.la_next);
720 881 }
721 882 break;
722 883 default:
723 884 mdb_printf(" %u: undefined type %u\n",
724 885 zlc->l_entry.le_type);
725 886 }
726 887 }
727 888
728 889 return (DCMD_OK);
729 890 }
730 891
731 892 typedef struct dbufs_data {
732 893 mdb_ctf_id_t id;
733 894 uint64_t objset;
734 895 uint64_t object;
735 896 uint64_t level;
736 897 uint64_t blkid;
737 898 char *osname;
738 899 } dbufs_data_t;
739 900
740 901 #define DBUFS_UNSET (0xbaddcafedeadbeefULL)
741 902
742 903 /* ARGSUSED */
743 904 static int
744 905 dbufs_cb(uintptr_t addr, const void *unknown, void *arg)
745 906 {
746 907 dbufs_data_t *data = arg;
747 908 uintptr_t objset;
748 909 dmu_buf_t db;
749 910 uint8_t level;
750 911 uint64_t blkid;
751 912 char osname[ZFS_MAX_DATASET_NAME_LEN];
752 913
753 914 if (GETMEMBID(addr, &data->id, db_objset, objset) ||
754 915 GETMEMBID(addr, &data->id, db, db) ||
755 916 GETMEMBID(addr, &data->id, db_level, level) ||
756 917 GETMEMBID(addr, &data->id, db_blkid, blkid)) {
757 918 return (WALK_ERR);
758 919 }
759 920
760 921 if ((data->objset == DBUFS_UNSET || data->objset == objset) &&
761 922 (data->osname == NULL || (objset_name(objset, osname) == 0 &&
762 923 strcmp(data->osname, osname) == 0)) &&
763 924 (data->object == DBUFS_UNSET || data->object == db.db_object) &&
764 925 (data->level == DBUFS_UNSET || data->level == level) &&
765 926 (data->blkid == DBUFS_UNSET || data->blkid == blkid)) {
766 927 mdb_printf("%#lr\n", addr);
767 928 }
768 929 return (WALK_NEXT);
769 930 }
770 931
771 932 /* ARGSUSED */
772 933 static int
773 934 dbufs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
774 935 {
775 936 dbufs_data_t data;
776 937 char *object = NULL;
777 938 char *blkid = NULL;
778 939
779 940 data.objset = data.object = data.level = data.blkid = DBUFS_UNSET;
780 941 data.osname = NULL;
781 942
782 943 if (mdb_getopts(argc, argv,
783 944 'O', MDB_OPT_UINT64, &data.objset,
784 945 'n', MDB_OPT_STR, &data.osname,
785 946 'o', MDB_OPT_STR, &object,
786 947 'l', MDB_OPT_UINT64, &data.level,
787 948 'b', MDB_OPT_STR, &blkid) != argc) {
788 949 return (DCMD_USAGE);
789 950 }
790 951
791 952 if (object) {
792 953 if (strcmp(object, "mdn") == 0) {
793 954 data.object = DMU_META_DNODE_OBJECT;
794 955 } else {
795 956 data.object = mdb_strtoull(object);
796 957 }
797 958 }
798 959
799 960 if (blkid) {
800 961 if (strcmp(blkid, "bonus") == 0) {
801 962 data.blkid = DMU_BONUS_BLKID;
802 963 } else {
803 964 data.blkid = mdb_strtoull(blkid);
804 965 }
805 966 }
806 967
807 968 if (mdb_ctf_lookup_by_name(ZFS_STRUCT "dmu_buf_impl", &data.id) == -1) {
808 969 mdb_warn("couldn't find struct dmu_buf_impl_t");
809 970 return (DCMD_ERR);
810 971 }
811 972
812 973 if (mdb_walk("dmu_buf_impl_t", dbufs_cb, &data) != 0) {
813 974 mdb_warn("can't walk dbufs");
814 975 return (DCMD_ERR);
815 976 }
816 977
817 978 return (DCMD_OK);
818 979 }
819 980
820 981 typedef struct abuf_find_data {
821 982 dva_t dva;
822 983 mdb_ctf_id_t id;
823 984 } abuf_find_data_t;
824 985
825 986 /* ARGSUSED */
826 987 static int
827 988 abuf_find_cb(uintptr_t addr, const void *unknown, void *arg)
828 989 {
829 990 abuf_find_data_t *data = arg;
830 991 dva_t dva;
831 992
832 993 if (GETMEMBID(addr, &data->id, b_dva, dva)) {
833 994 return (WALK_ERR);
834 995 }
835 996
836 997 if (dva.dva_word[0] == data->dva.dva_word[0] &&
837 998 dva.dva_word[1] == data->dva.dva_word[1]) {
838 999 mdb_printf("%#lr\n", addr);
839 1000 }
840 1001 return (WALK_NEXT);
841 1002 }
842 1003
843 1004 /* ARGSUSED */
844 1005 static int
845 1006 abuf_find(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
846 1007 {
847 1008 abuf_find_data_t data;
848 1009 GElf_Sym sym;
849 1010 int i;
850 1011 const char *syms[] = {
851 1012 "ARC_mru",
852 1013 "ARC_mru_ghost",
853 1014 "ARC_mfu",
854 1015 "ARC_mfu_ghost",
855 1016 };
856 1017
857 1018 if (argc != 2)
858 1019 return (DCMD_USAGE);
859 1020
860 1021 for (i = 0; i < 2; i ++) {
861 1022 switch (argv[i].a_type) {
862 1023 case MDB_TYPE_STRING:
863 1024 data.dva.dva_word[i] = mdb_strtoull(argv[i].a_un.a_str);
864 1025 break;
865 1026 case MDB_TYPE_IMMEDIATE:
866 1027 data.dva.dva_word[i] = argv[i].a_un.a_val;
867 1028 break;
868 1029 default:
869 1030 return (DCMD_USAGE);
870 1031 }
871 1032 }
872 1033
873 1034 if (mdb_ctf_lookup_by_name(ZFS_STRUCT "arc_buf_hdr", &data.id) == -1) {
874 1035 mdb_warn("couldn't find struct arc_buf_hdr");
875 1036 return (DCMD_ERR);
876 1037 }
877 1038
878 1039 for (i = 0; i < sizeof (syms) / sizeof (syms[0]); i++) {
879 1040 if (mdb_lookup_by_obj(ZFS_OBJ_NAME, syms[i], &sym)) {
880 1041 mdb_warn("can't find symbol %s", syms[i]);
881 1042 return (DCMD_ERR);
882 1043 }
883 1044
884 1045 if (mdb_pwalk("list", abuf_find_cb, &data, sym.st_value) != 0) {
885 1046 mdb_warn("can't walk %s", syms[i]);
886 1047 return (DCMD_ERR);
887 1048 }
888 1049 }
889 1050
890 1051 return (DCMD_OK);
891 1052 }
892 1053
893 1054
894 1055 typedef struct dbgmsg_arg {
895 1056 boolean_t da_verbose;
896 1057 boolean_t da_address;
897 1058 } dbgmsg_arg_t;
898 1059
899 1060 /* ARGSUSED */
900 1061 static int
901 1062 dbgmsg_cb(uintptr_t addr, const void *unknown, void *arg)
902 1063 {
903 1064 static mdb_ctf_id_t id;
904 1065 static boolean_t gotid;
905 1066 static ulong_t off;
906 1067
907 1068 dbgmsg_arg_t *da = arg;
908 1069 time_t timestamp;
909 1070 char buf[1024];
910 1071
911 1072 if (!gotid) {
912 1073 if (mdb_ctf_lookup_by_name(ZFS_STRUCT "zfs_dbgmsg", &id) ==
913 1074 -1) {
914 1075 mdb_warn("couldn't find struct zfs_dbgmsg");
915 1076 return (WALK_ERR);
916 1077 }
917 1078 gotid = TRUE;
918 1079 if (mdb_ctf_offsetof(id, "zdm_msg", &off) == -1) {
919 1080 mdb_warn("couldn't find zdm_msg");
920 1081 return (WALK_ERR);
921 1082 }
922 1083 off /= 8;
923 1084 }
924 1085
925 1086
926 1087 if (GETMEMBID(addr, &id, zdm_timestamp, timestamp)) {
927 1088 return (WALK_ERR);
928 1089 }
929 1090
930 1091 if (mdb_readstr(buf, sizeof (buf), addr + off) == -1) {
931 1092 mdb_warn("failed to read zdm_msg at %p\n", addr + off);
932 1093 return (DCMD_ERR);
933 1094 }
934 1095
935 1096 if (da->da_address)
936 1097 mdb_printf("%p ", addr);
937 1098 if (da->da_verbose)
938 1099 mdb_printf("%Y ", timestamp);
939 1100
940 1101 mdb_printf("%s\n", buf);
941 1102
942 1103 if (da->da_verbose)
943 1104 (void) mdb_call_dcmd("whatis", addr, DCMD_ADDRSPEC, 0, NULL);
944 1105
945 1106 return (WALK_NEXT);
946 1107 }
947 1108
948 1109 /* ARGSUSED */
949 1110 static int
950 1111 dbgmsg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
951 1112 {
952 1113 GElf_Sym sym;
953 1114 dbgmsg_arg_t da = { 0 };
954 1115
955 1116 if (mdb_getopts(argc, argv,
956 1117 'v', MDB_OPT_SETBITS, B_TRUE, &da.da_verbose,
957 1118 'a', MDB_OPT_SETBITS, B_TRUE, &da.da_address,
958 1119 NULL) != argc)
959 1120 return (DCMD_USAGE);
960 1121
961 1122 if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "zfs_dbgmsgs", &sym)) {
962 1123 mdb_warn("can't find zfs_dbgmsgs");
963 1124 return (DCMD_ERR);
964 1125 }
965 1126
966 1127 if (mdb_pwalk("list", dbgmsg_cb, &da, sym.st_value) != 0) {
967 1128 mdb_warn("can't walk zfs_dbgmsgs");
968 1129 return (DCMD_ERR);
969 1130 }
970 1131
971 1132 return (DCMD_OK);
972 1133 }
973 1134
974 1135 /*ARGSUSED*/
975 1136 static int
976 1137 arc_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
977 1138 {
978 1139 kstat_named_t *stats;
979 1140 GElf_Sym sym;
|
↓ open down ↓ |
527 lines elided |
↑ open up ↑ |
980 1141 int nstats, i;
981 1142 uint_t opt_a = FALSE;
982 1143 uint_t opt_b = FALSE;
983 1144 uint_t shift = 0;
984 1145 const char *suffix;
985 1146
986 1147 static const char *bytestats[] = {
987 1148 "p", "c", "c_min", "c_max", "size", "duplicate_buffers_size",
988 1149 "arc_meta_used", "arc_meta_limit", "arc_meta_max",
989 1150 "arc_meta_min", "hdr_size", "data_size", "metadata_size",
990 - "other_size", "anon_size", "anon_evictable_data",
991 - "anon_evictable_metadata", "mru_size", "mru_evictable_data",
992 - "mru_evictable_metadata", "mru_ghost_size",
1151 + "ddt_size", "other_size", "anon_size", "anon_evictable_data",
1152 + "anon_evictable_metadata", "anon_evictable_ddt", "mru_size",
1153 + "mru_evictable_data", "mru_evictable_metadata",
1154 + "mru_evictable_ddt", "mru_ghost_size",
993 1155 "mru_ghost_evictable_data", "mru_ghost_evictable_metadata",
994 - "mfu_size", "mfu_evictable_data", "mfu_evictable_metadata",
1156 + "mru_ghost_evictable_ddt", "mfu_size", "mfu_evictable_data",
1157 + "mfu_evictable_metadata", "mfu_evictable_ddt",
995 1158 "mfu_ghost_size", "mfu_ghost_evictable_data",
996 - "mfu_ghost_evictable_metadata", "evict_l2_cached",
997 - "evict_l2_eligible", "evict_l2_ineligible", "l2_read_bytes",
998 - "l2_write_bytes", "l2_size", "l2_asize", "l2_hdr_size",
999 - "compressed_size", "uncompressed_size", "overhead_size",
1159 + "mfu_ghost_evictable_metadata", "mfu_ghost_evictable_ddt",
1160 + "evict_l2_cached", "evict_l2_eligible", "evict_l2_ineligible",
1161 + "l2_read_bytes", "l2_ddt_read_bytes", "l2_write_bytes",
1162 + "l2_ddt_write_bytes", "l2_size", "l2_asize",
1163 + "l2_hdr_size", "compressed_size", "uncompressed_size",
1164 + "overhead_size",
1000 1165 NULL
1001 1166 };
1002 1167
1003 1168 static const char *extras[] = {
1004 1169 "arc_no_grow", "arc_tempreserve",
1005 1170 NULL
1006 1171 };
1007 1172
1008 1173 if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "arc_stats", &sym) == -1) {
1009 1174 mdb_warn("failed to find 'arc_stats'");
1010 1175 return (DCMD_ERR);
1011 1176 }
1012 1177
1013 1178 stats = mdb_zalloc(sym.st_size, UM_SLEEP | UM_GC);
1014 1179
1015 1180 if (mdb_vread(stats, sym.st_size, sym.st_value) == -1) {
1016 1181 mdb_warn("couldn't read 'arc_stats' at %p", sym.st_value);
1017 1182 return (DCMD_ERR);
1018 1183 }
1019 1184
1020 1185 nstats = sym.st_size / sizeof (kstat_named_t);
1021 1186
1022 1187 /* NB: -a / opt_a are ignored for backwards compatability */
1023 1188 if (mdb_getopts(argc, argv,
1024 1189 'a', MDB_OPT_SETBITS, TRUE, &opt_a,
1025 1190 'b', MDB_OPT_SETBITS, TRUE, &opt_b,
1026 1191 'k', MDB_OPT_SETBITS, 10, &shift,
1027 1192 'm', MDB_OPT_SETBITS, 20, &shift,
1028 1193 'g', MDB_OPT_SETBITS, 30, &shift,
1029 1194 NULL) != argc)
1030 1195 return (DCMD_USAGE);
1031 1196
1032 1197 if (!opt_b && !shift)
1033 1198 shift = 20;
1034 1199
1035 1200 switch (shift) {
1036 1201 case 0:
1037 1202 suffix = "B";
1038 1203 break;
1039 1204 case 10:
1040 1205 suffix = "KB";
1041 1206 break;
1042 1207 case 20:
1043 1208 suffix = "MB";
1044 1209 break;
1045 1210 case 30:
1046 1211 suffix = "GB";
1047 1212 break;
1048 1213 default:
1049 1214 suffix = "XX";
1050 1215 }
1051 1216
1052 1217 for (i = 0; i < nstats; i++) {
1053 1218 int j;
1054 1219 boolean_t bytes = B_FALSE;
1055 1220
1056 1221 for (j = 0; bytestats[j]; j++) {
1057 1222 if (strcmp(stats[i].name, bytestats[j]) == 0) {
1058 1223 bytes = B_TRUE;
1059 1224 break;
1060 1225 }
1061 1226 }
1062 1227
1063 1228 if (bytes) {
1064 1229 mdb_printf("%-25s = %9llu %s\n", stats[i].name,
1065 1230 stats[i].value.ui64 >> shift, suffix);
1066 1231 } else {
1067 1232 mdb_printf("%-25s = %9llu\n", stats[i].name,
1068 1233 stats[i].value.ui64);
1069 1234 }
1070 1235 }
1071 1236
1072 1237 for (i = 0; extras[i]; i++) {
1073 1238 uint64_t buf;
1074 1239
1075 1240 if (mdb_lookup_by_obj(ZFS_OBJ_NAME, extras[i], &sym) == -1) {
1076 1241 mdb_warn("failed to find '%s'", extras[i]);
1077 1242 return (DCMD_ERR);
1078 1243 }
1079 1244
1080 1245 if (sym.st_size != sizeof (uint64_t) &&
1081 1246 sym.st_size != sizeof (uint32_t)) {
1082 1247 mdb_warn("expected scalar for variable '%s'\n",
1083 1248 extras[i]);
1084 1249 return (DCMD_ERR);
1085 1250 }
1086 1251
1087 1252 if (mdb_vread(&buf, sym.st_size, sym.st_value) == -1) {
1088 1253 mdb_warn("couldn't read '%s'", extras[i]);
1089 1254 return (DCMD_ERR);
1090 1255 }
1091 1256
1092 1257 mdb_printf("%-25s = ", extras[i]);
1093 1258
1094 1259 /* NB: all the 64-bit extras happen to be byte counts */
1095 1260 if (sym.st_size == sizeof (uint64_t))
1096 1261 mdb_printf("%9llu %s\n", buf >> shift, suffix);
1097 1262
1098 1263 if (sym.st_size == sizeof (uint32_t))
1099 1264 mdb_printf("%9d\n", *((uint32_t *)&buf));
1100 1265 }
1101 1266 return (DCMD_OK);
1102 1267 }
1103 1268
1104 1269 typedef struct mdb_spa_print {
1105 1270 pool_state_t spa_state;
1106 1271 char spa_name[ZFS_MAX_DATASET_NAME_LEN];
1107 1272 uintptr_t spa_normal_class;
1108 1273 } mdb_spa_print_t;
1109 1274
1110 1275
1111 1276 const char histo_stars[] = "****************************************";
1112 1277 const int histo_width = sizeof (histo_stars) - 1;
1113 1278
1114 1279 static void
1115 1280 dump_histogram(const uint64_t *histo, int size, int offset)
1116 1281 {
1117 1282 int i;
1118 1283 int minidx = size - 1;
1119 1284 int maxidx = 0;
1120 1285 uint64_t max = 0;
1121 1286
1122 1287 for (i = 0; i < size; i++) {
1123 1288 if (histo[i] > max)
1124 1289 max = histo[i];
1125 1290 if (histo[i] > 0 && i > maxidx)
1126 1291 maxidx = i;
1127 1292 if (histo[i] > 0 && i < minidx)
1128 1293 minidx = i;
1129 1294 }
1130 1295
1131 1296 if (max < histo_width)
1132 1297 max = histo_width;
1133 1298
1134 1299 for (i = minidx; i <= maxidx; i++) {
1135 1300 mdb_printf("%3u: %6llu %s\n",
1136 1301 i + offset, (u_longlong_t)histo[i],
1137 1302 &histo_stars[(max - histo[i]) * histo_width / max]);
1138 1303 }
1139 1304 }
1140 1305
1141 1306 typedef struct mdb_metaslab_class {
1142 1307 uint64_t mc_histogram[RANGE_TREE_HISTOGRAM_SIZE];
1143 1308 } mdb_metaslab_class_t;
1144 1309
1145 1310 /*
1146 1311 * spa_class_histogram(uintptr_t class_addr)
1147 1312 *
1148 1313 * Prints free space histogram for a device class
1149 1314 *
1150 1315 * Returns DCMD_OK, or DCMD_ERR.
1151 1316 */
1152 1317 static int
1153 1318 spa_class_histogram(uintptr_t class_addr)
1154 1319 {
1155 1320 mdb_metaslab_class_t mc;
1156 1321 if (mdb_ctf_vread(&mc, "metaslab_class_t",
1157 1322 "mdb_metaslab_class_t", class_addr, 0) == -1)
1158 1323 return (DCMD_ERR);
1159 1324
1160 1325 mdb_inc_indent(4);
1161 1326 dump_histogram(mc.mc_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
1162 1327 mdb_dec_indent(4);
1163 1328 return (DCMD_OK);
1164 1329 }
1165 1330
1166 1331 /*
1167 1332 * ::spa
1168 1333 *
1169 1334 * -c Print configuration information as well
1170 1335 * -v Print vdev state
1171 1336 * -e Print vdev error stats
1172 1337 * -m Print vdev metaslab info
1173 1338 * -M print vdev metaslab group info
1174 1339 * -h Print histogram info (must be combined with -m or -M)
1175 1340 *
1176 1341 * Print a summarized spa_t. When given no arguments, prints out a table of all
1177 1342 * active pools on the system.
1178 1343 */
1179 1344 /* ARGSUSED */
1180 1345 static int
1181 1346 spa_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1182 1347 {
1183 1348 const char *statetab[] = { "ACTIVE", "EXPORTED", "DESTROYED",
1184 1349 "SPARE", "L2CACHE", "UNINIT", "UNAVAIL", "POTENTIAL" };
1185 1350 const char *state;
1186 1351 int spa_flags = 0;
1187 1352
1188 1353 if (mdb_getopts(argc, argv,
1189 1354 'c', MDB_OPT_SETBITS, SPA_FLAG_CONFIG, &spa_flags,
1190 1355 'v', MDB_OPT_SETBITS, SPA_FLAG_VDEVS, &spa_flags,
1191 1356 'e', MDB_OPT_SETBITS, SPA_FLAG_ERRORS, &spa_flags,
1192 1357 'M', MDB_OPT_SETBITS, SPA_FLAG_METASLAB_GROUPS, &spa_flags,
1193 1358 'm', MDB_OPT_SETBITS, SPA_FLAG_METASLABS, &spa_flags,
1194 1359 'h', MDB_OPT_SETBITS, SPA_FLAG_HISTOGRAMS, &spa_flags,
1195 1360 NULL) != argc)
1196 1361 return (DCMD_USAGE);
1197 1362
1198 1363 if (!(flags & DCMD_ADDRSPEC)) {
1199 1364 if (mdb_walk_dcmd("spa", "spa", argc, argv) == -1) {
1200 1365 mdb_warn("can't walk spa");
1201 1366 return (DCMD_ERR);
1202 1367 }
1203 1368
1204 1369 return (DCMD_OK);
1205 1370 }
1206 1371
1207 1372 if (flags & DCMD_PIPE_OUT) {
1208 1373 mdb_printf("%#lr\n", addr);
1209 1374 return (DCMD_OK);
1210 1375 }
1211 1376
1212 1377 if (DCMD_HDRSPEC(flags))
1213 1378 mdb_printf("%<u>%-?s %9s %-*s%</u>\n", "ADDR", "STATE",
1214 1379 sizeof (uintptr_t) == 4 ? 60 : 52, "NAME");
1215 1380
1216 1381 mdb_spa_print_t spa;
1217 1382 if (mdb_ctf_vread(&spa, "spa_t", "mdb_spa_print_t", addr, 0) == -1)
1218 1383 return (DCMD_ERR);
1219 1384
1220 1385 if (spa.spa_state < 0 || spa.spa_state > POOL_STATE_UNAVAIL)
1221 1386 state = "UNKNOWN";
1222 1387 else
1223 1388 state = statetab[spa.spa_state];
1224 1389
1225 1390 mdb_printf("%0?p %9s %s\n", addr, state, spa.spa_name);
1226 1391 if (spa_flags & SPA_FLAG_HISTOGRAMS)
1227 1392 spa_class_histogram(spa.spa_normal_class);
1228 1393
1229 1394 if (spa_flags & SPA_FLAG_CONFIG) {
1230 1395 mdb_printf("\n");
1231 1396 mdb_inc_indent(4);
1232 1397 if (mdb_call_dcmd("spa_config", addr, flags, 0,
1233 1398 NULL) != DCMD_OK)
1234 1399 return (DCMD_ERR);
1235 1400 mdb_dec_indent(4);
1236 1401 }
1237 1402
1238 1403 if (spa_flags & SPA_FLAG_ALL_VDEV) {
1239 1404 mdb_arg_t v;
1240 1405 char opts[100] = "-";
1241 1406 int args =
1242 1407 (spa_flags | SPA_FLAG_VDEVS) == SPA_FLAG_VDEVS ? 0 : 1;
1243 1408
1244 1409 if (spa_flags & SPA_FLAG_ERRORS)
1245 1410 strcat(opts, "e");
1246 1411 if (spa_flags & SPA_FLAG_METASLABS)
1247 1412 strcat(opts, "m");
1248 1413 if (spa_flags & SPA_FLAG_METASLAB_GROUPS)
1249 1414 strcat(opts, "M");
1250 1415 if (spa_flags & SPA_FLAG_HISTOGRAMS)
1251 1416 strcat(opts, "h");
1252 1417
1253 1418 v.a_type = MDB_TYPE_STRING;
1254 1419 v.a_un.a_str = opts;
1255 1420
1256 1421 mdb_printf("\n");
1257 1422 mdb_inc_indent(4);
1258 1423 if (mdb_call_dcmd("spa_vdevs", addr, flags, args,
1259 1424 &v) != DCMD_OK)
1260 1425 return (DCMD_ERR);
1261 1426 mdb_dec_indent(4);
1262 1427 }
1263 1428
1264 1429 return (DCMD_OK);
1265 1430 }
1266 1431
1267 1432 typedef struct mdb_spa_config_spa {
1268 1433 uintptr_t spa_config;
1269 1434 } mdb_spa_config_spa_t;
1270 1435
1271 1436 /*
1272 1437 * ::spa_config
1273 1438 *
1274 1439 * Given a spa_t, print the configuration information stored in spa_config.
1275 1440 * Since it's just an nvlist, format it as an indented list of name=value pairs.
1276 1441 * We simply read the value of spa_config and pass off to ::nvlist.
1277 1442 */
1278 1443 /* ARGSUSED */
1279 1444 static int
1280 1445 spa_print_config(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1281 1446 {
1282 1447 mdb_spa_config_spa_t spa;
1283 1448
1284 1449 if (argc != 0 || !(flags & DCMD_ADDRSPEC))
1285 1450 return (DCMD_USAGE);
1286 1451
1287 1452 if (mdb_ctf_vread(&spa, ZFS_STRUCT "spa", "mdb_spa_config_spa_t",
1288 1453 addr, 0) == -1)
1289 1454 return (DCMD_ERR);
1290 1455
1291 1456 if (spa.spa_config == 0) {
1292 1457 mdb_printf("(none)\n");
1293 1458 return (DCMD_OK);
1294 1459 }
1295 1460
1296 1461 return (mdb_call_dcmd("nvlist", spa.spa_config, flags,
1297 1462 0, NULL));
1298 1463 }
1299 1464
1300 1465
1301 1466
1302 1467 typedef struct mdb_range_tree {
1303 1468 uint64_t rt_space;
1304 1469 } mdb_range_tree_t;
1305 1470
1306 1471 typedef struct mdb_metaslab_group {
1307 1472 uint64_t mg_fragmentation;
1308 1473 uint64_t mg_histogram[RANGE_TREE_HISTOGRAM_SIZE];
1309 1474 uintptr_t mg_vd;
1310 1475 } mdb_metaslab_group_t;
1311 1476
1312 1477 typedef struct mdb_metaslab {
1313 1478 uint64_t ms_id;
1314 1479 uint64_t ms_start;
1315 1480 uint64_t ms_size;
1316 1481 int64_t ms_deferspace;
1317 1482 uint64_t ms_fragmentation;
1318 1483 uint64_t ms_weight;
1319 1484 uintptr_t ms_alloctree[TXG_SIZE];
1320 1485 uintptr_t ms_freeingtree;
1321 1486 uintptr_t ms_freedtree;
1322 1487 uintptr_t ms_tree;
1323 1488 uintptr_t ms_sm;
1324 1489 } mdb_metaslab_t;
1325 1490
1326 1491 typedef struct mdb_space_map_phys_t {
1327 1492 uint64_t smp_alloc;
1328 1493 uint64_t smp_histogram[SPACE_MAP_HISTOGRAM_SIZE];
1329 1494 } mdb_space_map_phys_t;
1330 1495
1331 1496 typedef struct mdb_space_map {
1332 1497 uint64_t sm_size;
1333 1498 uint8_t sm_shift;
1334 1499 uint64_t sm_alloc;
1335 1500 uintptr_t sm_phys;
1336 1501 } mdb_space_map_t;
1337 1502
1338 1503 typedef struct mdb_vdev {
1339 1504 uintptr_t vdev_path;
1340 1505 uintptr_t vdev_ms;
1341 1506 uintptr_t vdev_ops;
1342 1507 uint64_t vdev_ms_count;
1343 1508 uint64_t vdev_id;
1344 1509 vdev_stat_t vdev_stat;
1345 1510 } mdb_vdev_t;
1346 1511
1347 1512 typedef struct mdb_vdev_ops {
1348 1513 char vdev_op_type[16];
1349 1514 } mdb_vdev_ops_t;
1350 1515
1351 1516 static int
1352 1517 metaslab_stats(uintptr_t addr, int spa_flags)
1353 1518 {
1354 1519 mdb_vdev_t vdev;
1355 1520 uintptr_t *vdev_ms;
1356 1521
1357 1522 if (mdb_ctf_vread(&vdev, "vdev_t", "mdb_vdev_t",
1358 1523 (uintptr_t)addr, 0) == -1) {
1359 1524 mdb_warn("failed to read vdev at %p\n", addr);
1360 1525 return (DCMD_ERR);
1361 1526 }
1362 1527
1363 1528 mdb_inc_indent(4);
1364 1529 mdb_printf("%<u>%-?s %6s %20s %10s %9s%</u>\n", "ADDR", "ID",
1365 1530 "OFFSET", "FREE", "FRAGMENTATION");
1366 1531
1367 1532 vdev_ms = mdb_alloc(vdev.vdev_ms_count * sizeof (void *),
1368 1533 UM_SLEEP | UM_GC);
1369 1534 if (mdb_vread(vdev_ms, vdev.vdev_ms_count * sizeof (void *),
1370 1535 (uintptr_t)vdev.vdev_ms) == -1) {
1371 1536 mdb_warn("failed to read vdev_ms at %p\n", vdev.vdev_ms);
1372 1537 return (DCMD_ERR);
1373 1538 }
1374 1539
1375 1540 for (int m = 0; m < vdev.vdev_ms_count; m++) {
1376 1541 mdb_metaslab_t ms;
1377 1542 mdb_space_map_t sm = { 0 };
1378 1543 char free[NICENUM_BUFLEN];
1379 1544
1380 1545 if (mdb_ctf_vread(&ms, "metaslab_t", "mdb_metaslab_t",
1381 1546 (uintptr_t)vdev_ms[m], 0) == -1)
1382 1547 return (DCMD_ERR);
1383 1548
1384 1549 if (ms.ms_sm != NULL &&
1385 1550 mdb_ctf_vread(&sm, "space_map_t", "mdb_space_map_t",
1386 1551 ms.ms_sm, 0) == -1)
1387 1552 return (DCMD_ERR);
1388 1553
1389 1554 mdb_nicenum(ms.ms_size - sm.sm_alloc, free);
1390 1555
1391 1556 mdb_printf("%0?p %6llu %20llx %10s ", vdev_ms[m], ms.ms_id,
1392 1557 ms.ms_start, free);
1393 1558 if (ms.ms_fragmentation == ZFS_FRAG_INVALID)
1394 1559 mdb_printf("%9s\n", "-");
1395 1560 else
1396 1561 mdb_printf("%9llu%%\n", ms.ms_fragmentation);
1397 1562
1398 1563 if ((spa_flags & SPA_FLAG_HISTOGRAMS) && ms.ms_sm != NULL) {
1399 1564 mdb_space_map_phys_t smp;
1400 1565
1401 1566 if (sm.sm_phys == NULL)
1402 1567 continue;
1403 1568
1404 1569 (void) mdb_ctf_vread(&smp, "space_map_phys_t",
1405 1570 "mdb_space_map_phys_t", sm.sm_phys, 0);
1406 1571
1407 1572 dump_histogram(smp.smp_histogram,
1408 1573 SPACE_MAP_HISTOGRAM_SIZE, sm.sm_shift);
1409 1574 }
1410 1575 }
1411 1576 mdb_dec_indent(4);
1412 1577 return (DCMD_OK);
1413 1578 }
1414 1579
1415 1580 static int
1416 1581 metaslab_group_stats(uintptr_t addr, int spa_flags)
1417 1582 {
1418 1583 mdb_metaslab_group_t mg;
1419 1584 if (mdb_ctf_vread(&mg, "metaslab_group_t", "mdb_metaslab_group_t",
1420 1585 (uintptr_t)addr, 0) == -1) {
1421 1586 mdb_warn("failed to read vdev_mg at %p\n", addr);
1422 1587 return (DCMD_ERR);
1423 1588 }
1424 1589
1425 1590 mdb_inc_indent(4);
1426 1591 mdb_printf("%<u>%-?s %15s%</u>\n", "ADDR", "FRAGMENTATION");
1427 1592 if (mg.mg_fragmentation == ZFS_FRAG_INVALID)
1428 1593 mdb_printf("%0?p %15s\n", addr, "-");
1429 1594 else
1430 1595 mdb_printf("%0?p %15llu%%\n", addr, mg.mg_fragmentation);
1431 1596
1432 1597 if (spa_flags & SPA_FLAG_HISTOGRAMS)
1433 1598 dump_histogram(mg.mg_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
1434 1599 mdb_dec_indent(4);
1435 1600 return (DCMD_OK);
1436 1601 }
1437 1602
1438 1603 /*
1439 1604 * ::vdev
1440 1605 *
1441 1606 * Print out a summarized vdev_t, in the following form:
1442 1607 *
1443 1608 * ADDR STATE AUX DESC
1444 1609 * fffffffbcde23df0 HEALTHY - /dev/dsk/c0t0d0
1445 1610 *
1446 1611 * If '-r' is specified, recursively visit all children.
1447 1612 *
1448 1613 * With '-e', the statistics associated with the vdev are printed as well.
1449 1614 */
1450 1615 static int
1451 1616 do_print_vdev(uintptr_t addr, int flags, int depth, boolean_t recursive,
1452 1617 int spa_flags)
1453 1618 {
1454 1619 vdev_t vdev;
1455 1620 char desc[MAXNAMELEN];
1456 1621 int c, children;
1457 1622 uintptr_t *child;
1458 1623 const char *state, *aux;
1459 1624
1460 1625 if (mdb_vread(&vdev, sizeof (vdev), (uintptr_t)addr) == -1) {
1461 1626 mdb_warn("failed to read vdev_t at %p\n", (uintptr_t)addr);
1462 1627 return (DCMD_ERR);
1463 1628 }
1464 1629
1465 1630 if (flags & DCMD_PIPE_OUT) {
1466 1631 mdb_printf("%#lr\n", addr);
1467 1632 } else {
1468 1633 if (vdev.vdev_path != NULL) {
1469 1634 if (mdb_readstr(desc, sizeof (desc),
1470 1635 (uintptr_t)vdev.vdev_path) == -1) {
1471 1636 mdb_warn("failed to read vdev_path at %p\n",
1472 1637 vdev.vdev_path);
1473 1638 return (DCMD_ERR);
1474 1639 }
1475 1640 } else if (vdev.vdev_ops != NULL) {
1476 1641 vdev_ops_t ops;
1477 1642 if (mdb_vread(&ops, sizeof (ops),
1478 1643 (uintptr_t)vdev.vdev_ops) == -1) {
1479 1644 mdb_warn("failed to read vdev_ops at %p\n",
1480 1645 vdev.vdev_ops);
1481 1646 return (DCMD_ERR);
1482 1647 }
1483 1648 (void) strcpy(desc, ops.vdev_op_type);
1484 1649 } else {
1485 1650 (void) strcpy(desc, "<unknown>");
1486 1651 }
1487 1652
1488 1653 if (depth == 0 && DCMD_HDRSPEC(flags))
1489 1654 mdb_printf("%<u>%-?s %-9s %-12s %-*s%</u>\n",
1490 1655 "ADDR", "STATE", "AUX",
1491 1656 sizeof (uintptr_t) == 4 ? 43 : 35,
1492 1657 "DESCRIPTION");
1493 1658
1494 1659 mdb_printf("%0?p ", addr);
1495 1660
1496 1661 switch (vdev.vdev_state) {
1497 1662 case VDEV_STATE_CLOSED:
1498 1663 state = "CLOSED";
1499 1664 break;
1500 1665 case VDEV_STATE_OFFLINE:
1501 1666 state = "OFFLINE";
1502 1667 break;
1503 1668 case VDEV_STATE_CANT_OPEN:
1504 1669 state = "CANT_OPEN";
1505 1670 break;
1506 1671 case VDEV_STATE_DEGRADED:
1507 1672 state = "DEGRADED";
1508 1673 break;
1509 1674 case VDEV_STATE_HEALTHY:
1510 1675 state = "HEALTHY";
1511 1676 break;
1512 1677 case VDEV_STATE_REMOVED:
1513 1678 state = "REMOVED";
1514 1679 break;
1515 1680 case VDEV_STATE_FAULTED:
1516 1681 state = "FAULTED";
1517 1682 break;
1518 1683 default:
1519 1684 state = "UNKNOWN";
1520 1685 break;
1521 1686 }
1522 1687
1523 1688 switch (vdev.vdev_stat.vs_aux) {
1524 1689 case VDEV_AUX_NONE:
1525 1690 aux = "-";
1526 1691 break;
1527 1692 case VDEV_AUX_OPEN_FAILED:
1528 1693 aux = "OPEN_FAILED";
1529 1694 break;
1530 1695 case VDEV_AUX_CORRUPT_DATA:
1531 1696 aux = "CORRUPT_DATA";
1532 1697 break;
1533 1698 case VDEV_AUX_NO_REPLICAS:
1534 1699 aux = "NO_REPLICAS";
1535 1700 break;
1536 1701 case VDEV_AUX_BAD_GUID_SUM:
1537 1702 aux = "BAD_GUID_SUM";
1538 1703 break;
1539 1704 case VDEV_AUX_TOO_SMALL:
1540 1705 aux = "TOO_SMALL";
1541 1706 break;
1542 1707 case VDEV_AUX_BAD_LABEL:
1543 1708 aux = "BAD_LABEL";
1544 1709 break;
1545 1710 case VDEV_AUX_VERSION_NEWER:
1546 1711 aux = "VERS_NEWER";
1547 1712 break;
1548 1713 case VDEV_AUX_VERSION_OLDER:
1549 1714 aux = "VERS_OLDER";
1550 1715 break;
1551 1716 case VDEV_AUX_UNSUP_FEAT:
1552 1717 aux = "UNSUP_FEAT";
1553 1718 break;
1554 1719 case VDEV_AUX_SPARED:
1555 1720 aux = "SPARED";
1556 1721 break;
1557 1722 case VDEV_AUX_ERR_EXCEEDED:
1558 1723 aux = "ERR_EXCEEDED";
1559 1724 break;
1560 1725 case VDEV_AUX_IO_FAILURE:
1561 1726 aux = "IO_FAILURE";
|
↓ open down ↓ |
552 lines elided |
↑ open up ↑ |
1562 1727 break;
1563 1728 case VDEV_AUX_BAD_LOG:
1564 1729 aux = "BAD_LOG";
1565 1730 break;
1566 1731 case VDEV_AUX_EXTERNAL:
1567 1732 aux = "EXTERNAL";
1568 1733 break;
1569 1734 case VDEV_AUX_SPLIT_POOL:
1570 1735 aux = "SPLIT_POOL";
1571 1736 break;
1572 - case VDEV_AUX_CHILDREN_OFFLINE:
1573 - aux = "CHILDREN_OFFLINE";
1574 - break;
1575 1737 default:
1576 1738 aux = "UNKNOWN";
1577 1739 break;
1578 1740 }
1579 1741
1580 1742 mdb_printf("%-9s %-12s %*s%s\n", state, aux, depth, "", desc);
1581 1743
1582 1744 if (spa_flags & SPA_FLAG_ERRORS) {
1583 1745 vdev_stat_t *vs = &vdev.vdev_stat;
1584 1746 int i;
1585 1747
1586 1748 mdb_inc_indent(4);
1587 1749 mdb_printf("\n");
1588 1750 mdb_printf("%<u> %12s %12s %12s %12s "
1589 1751 "%12s%</u>\n", "READ", "WRITE", "FREE", "CLAIM",
1590 1752 "IOCTL");
1591 1753 mdb_printf("OPS ");
1592 1754 for (i = 1; i < ZIO_TYPES; i++)
1593 1755 mdb_printf("%11#llx%s", vs->vs_ops[i],
1594 1756 i == ZIO_TYPES - 1 ? "" : " ");
1595 1757 mdb_printf("\n");
1596 1758 mdb_printf("BYTES ");
1597 1759 for (i = 1; i < ZIO_TYPES; i++)
1598 1760 mdb_printf("%11#llx%s", vs->vs_bytes[i],
1599 1761 i == ZIO_TYPES - 1 ? "" : " ");
1600 1762
1601 1763
1602 1764 mdb_printf("\n");
1603 1765 mdb_printf("EREAD %10#llx\n", vs->vs_read_errors);
1604 1766 mdb_printf("EWRITE %10#llx\n", vs->vs_write_errors);
1605 1767 mdb_printf("ECKSUM %10#llx\n",
1606 1768 vs->vs_checksum_errors);
1607 1769 mdb_dec_indent(4);
1608 1770 mdb_printf("\n");
1609 1771 }
1610 1772
1611 1773 if (spa_flags & SPA_FLAG_METASLAB_GROUPS &&
1612 1774 vdev.vdev_mg != NULL) {
1613 1775 metaslab_group_stats((uintptr_t)vdev.vdev_mg,
1614 1776 spa_flags);
1615 1777 }
1616 1778 if (spa_flags & SPA_FLAG_METASLABS && vdev.vdev_ms != NULL) {
1617 1779 metaslab_stats((uintptr_t)addr, spa_flags);
1618 1780 }
1619 1781 }
1620 1782
1621 1783 children = vdev.vdev_children;
1622 1784
1623 1785 if (children == 0 || !recursive)
1624 1786 return (DCMD_OK);
1625 1787
1626 1788 child = mdb_alloc(children * sizeof (void *), UM_SLEEP | UM_GC);
1627 1789 if (mdb_vread(child, children * sizeof (void *),
1628 1790 (uintptr_t)vdev.vdev_child) == -1) {
1629 1791 mdb_warn("failed to read vdev children at %p", vdev.vdev_child);
1630 1792 return (DCMD_ERR);
1631 1793 }
1632 1794
1633 1795 for (c = 0; c < children; c++) {
1634 1796 if (do_print_vdev(child[c], flags, depth + 2, recursive,
1635 1797 spa_flags)) {
1636 1798 return (DCMD_ERR);
1637 1799 }
1638 1800 }
1639 1801
1640 1802 return (DCMD_OK);
1641 1803 }
1642 1804
1643 1805 static int
1644 1806 vdev_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1645 1807 {
1646 1808 uint64_t depth = 0;
1647 1809 boolean_t recursive = B_FALSE;
1648 1810 int spa_flags = 0;
1649 1811
1650 1812 if (mdb_getopts(argc, argv,
1651 1813 'e', MDB_OPT_SETBITS, SPA_FLAG_ERRORS, &spa_flags,
1652 1814 'm', MDB_OPT_SETBITS, SPA_FLAG_METASLABS, &spa_flags,
1653 1815 'M', MDB_OPT_SETBITS, SPA_FLAG_METASLAB_GROUPS, &spa_flags,
1654 1816 'h', MDB_OPT_SETBITS, SPA_FLAG_HISTOGRAMS, &spa_flags,
1655 1817 'r', MDB_OPT_SETBITS, TRUE, &recursive,
1656 1818 'd', MDB_OPT_UINT64, &depth, NULL) != argc)
1657 1819 return (DCMD_USAGE);
1658 1820
1659 1821 if (!(flags & DCMD_ADDRSPEC)) {
1660 1822 mdb_warn("no vdev_t address given\n");
1661 1823 return (DCMD_ERR);
1662 1824 }
1663 1825
1664 1826 return (do_print_vdev(addr, flags, (int)depth, recursive, spa_flags));
1665 1827 }
1666 1828
1667 1829 typedef struct mdb_metaslab_alloc_trace {
1668 1830 uintptr_t mat_mg;
1669 1831 uintptr_t mat_msp;
1670 1832 uint64_t mat_size;
1671 1833 uint64_t mat_weight;
1672 1834 uint64_t mat_offset;
1673 1835 uint32_t mat_dva_id;
1674 1836 } mdb_metaslab_alloc_trace_t;
1675 1837
1676 1838 static void
1677 1839 metaslab_print_weight(uint64_t weight)
1678 1840 {
1679 1841 char buf[100];
1680 1842
1681 1843 if (WEIGHT_IS_SPACEBASED(weight)) {
1682 1844 mdb_nicenum(
1683 1845 weight & ~(METASLAB_ACTIVE_MASK | METASLAB_WEIGHT_TYPE),
1684 1846 buf);
1685 1847 } else {
1686 1848 char size[NICENUM_BUFLEN];
1687 1849 mdb_nicenum(1ULL << WEIGHT_GET_INDEX(weight), size);
1688 1850 (void) mdb_snprintf(buf, sizeof (buf), "%llu x %s",
1689 1851 WEIGHT_GET_COUNT(weight), size);
1690 1852 }
1691 1853 mdb_printf("%11s ", buf);
1692 1854 }
1693 1855
1694 1856 /* ARGSUSED */
1695 1857 static int
1696 1858 metaslab_weight(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1697 1859 {
1698 1860 uint64_t weight = 0;
1699 1861 char active;
1700 1862
1701 1863 if (argc == 0 && (flags & DCMD_ADDRSPEC)) {
1702 1864 if (mdb_vread(&weight, sizeof (uint64_t), addr) == -1) {
1703 1865 mdb_warn("failed to read weight at %p\n", addr);
1704 1866 return (DCMD_ERR);
1705 1867 }
1706 1868 } else if (argc == 1 && !(flags & DCMD_ADDRSPEC)) {
1707 1869 weight = (argv[0].a_type == MDB_TYPE_IMMEDIATE) ?
1708 1870 argv[0].a_un.a_val : mdb_strtoull(argv[0].a_un.a_str);
1709 1871 } else {
1710 1872 return (DCMD_USAGE);
1711 1873 }
1712 1874
1713 1875 if (DCMD_HDRSPEC(flags)) {
1714 1876 mdb_printf("%<u>%-6s %9s %9s%</u>\n",
1715 1877 "ACTIVE", "ALGORITHM", "WEIGHT");
1716 1878 }
1717 1879
1718 1880 if (weight & METASLAB_WEIGHT_PRIMARY)
1719 1881 active = 'P';
1720 1882 else if (weight & METASLAB_WEIGHT_SECONDARY)
1721 1883 active = 'S';
1722 1884 else
1723 1885 active = '-';
1724 1886 mdb_printf("%6c %8s ", active,
1725 1887 WEIGHT_IS_SPACEBASED(weight) ? "SPACE" : "SEGMENT");
1726 1888 metaslab_print_weight(weight);
1727 1889 mdb_printf("\n");
1728 1890
1729 1891 return (DCMD_OK);
1730 1892 }
1731 1893
1732 1894 /* ARGSUSED */
1733 1895 static int
1734 1896 metaslab_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1735 1897 {
1736 1898 mdb_metaslab_alloc_trace_t mat;
1737 1899 mdb_metaslab_group_t mg = { 0 };
1738 1900 char result_type[100];
1739 1901
1740 1902 if (mdb_ctf_vread(&mat, "metaslab_alloc_trace_t",
1741 1903 "mdb_metaslab_alloc_trace_t", addr, 0) == -1) {
1742 1904 return (DCMD_ERR);
1743 1905 }
1744 1906
1745 1907 if (!(flags & DCMD_PIPE_OUT) && DCMD_HDRSPEC(flags)) {
1746 1908 mdb_printf("%<u>%6s %6s %8s %11s %18s %18s%</u>\n",
1747 1909 "MSID", "DVA", "ASIZE", "WEIGHT", "RESULT", "VDEV");
1748 1910 }
1749 1911
1750 1912 if (mat.mat_msp != NULL) {
1751 1913 mdb_metaslab_t ms;
1752 1914
1753 1915 if (mdb_ctf_vread(&ms, "metaslab_t", "mdb_metaslab_t",
1754 1916 mat.mat_msp, 0) == -1) {
1755 1917 return (DCMD_ERR);
1756 1918 }
1757 1919 mdb_printf("%6llu ", ms.ms_id);
1758 1920 } else {
1759 1921 mdb_printf("%6s ", "-");
1760 1922 }
1761 1923
1762 1924 mdb_printf("%6d %8llx ", mat.mat_dva_id, mat.mat_size);
1763 1925
1764 1926 metaslab_print_weight(mat.mat_weight);
1765 1927
1766 1928 if ((int64_t)mat.mat_offset < 0) {
1767 1929 if (enum_lookup("enum trace_alloc_type", mat.mat_offset,
1768 1930 "TRACE_", sizeof (result_type), result_type) == -1) {
1769 1931 mdb_warn("Could not find enum for trace_alloc_type");
1770 1932 return (DCMD_ERR);
1771 1933 }
1772 1934 mdb_printf("%18s ", result_type);
1773 1935 } else {
1774 1936 mdb_printf("%<b>%18llx%</b> ", mat.mat_offset);
1775 1937 }
1776 1938
1777 1939 if (mat.mat_mg != NULL &&
1778 1940 mdb_ctf_vread(&mg, "metaslab_group_t", "mdb_metaslab_group_t",
1779 1941 mat.mat_mg, 0) == -1) {
1780 1942 return (DCMD_ERR);
1781 1943 }
1782 1944
1783 1945 if (mg.mg_vd != NULL) {
1784 1946 mdb_vdev_t vdev;
1785 1947 char desc[MAXNAMELEN];
1786 1948
1787 1949 if (mdb_ctf_vread(&vdev, "vdev_t", "mdb_vdev_t",
1788 1950 mg.mg_vd, 0) == -1) {
1789 1951 return (DCMD_ERR);
1790 1952 }
1791 1953
1792 1954 if (vdev.vdev_path != NULL) {
1793 1955 char path[MAXNAMELEN];
1794 1956
1795 1957 if (mdb_readstr(path, sizeof (path),
1796 1958 vdev.vdev_path) == -1) {
1797 1959 mdb_warn("failed to read vdev_path at %p\n",
1798 1960 vdev.vdev_path);
1799 1961 return (DCMD_ERR);
1800 1962 }
1801 1963 char *slash;
1802 1964 if ((slash = strrchr(path, '/')) != NULL) {
1803 1965 strcpy(desc, slash + 1);
1804 1966 } else {
1805 1967 strcpy(desc, path);
1806 1968 }
1807 1969 } else if (vdev.vdev_ops != NULL) {
1808 1970 mdb_vdev_ops_t ops;
1809 1971 if (mdb_ctf_vread(&ops, "vdev_ops_t", "mdb_vdev_ops_t",
1810 1972 vdev.vdev_ops, 0) == -1) {
1811 1973 mdb_warn("failed to read vdev_ops at %p\n",
1812 1974 vdev.vdev_ops);
1813 1975 return (DCMD_ERR);
1814 1976 }
1815 1977 (void) mdb_snprintf(desc, sizeof (desc),
1816 1978 "%s-%llu", ops.vdev_op_type, vdev.vdev_id);
1817 1979 } else {
1818 1980 (void) strcpy(desc, "<unknown>");
1819 1981 }
1820 1982 mdb_printf("%18s\n", desc);
1821 1983 }
1822 1984
1823 1985 return (DCMD_OK);
1824 1986 }
1825 1987
1826 1988 typedef struct metaslab_walk_data {
1827 1989 uint64_t mw_numvdevs;
1828 1990 uintptr_t *mw_vdevs;
1829 1991 int mw_curvdev;
1830 1992 uint64_t mw_nummss;
1831 1993 uintptr_t *mw_mss;
1832 1994 int mw_curms;
1833 1995 } metaslab_walk_data_t;
1834 1996
1835 1997 static int
1836 1998 metaslab_walk_step(mdb_walk_state_t *wsp)
1837 1999 {
1838 2000 metaslab_walk_data_t *mw = wsp->walk_data;
1839 2001 metaslab_t ms;
1840 2002 uintptr_t msp;
1841 2003
1842 2004 if (mw->mw_curvdev >= mw->mw_numvdevs)
1843 2005 return (WALK_DONE);
1844 2006
1845 2007 if (mw->mw_mss == NULL) {
1846 2008 uintptr_t mssp;
1847 2009 uintptr_t vdevp;
1848 2010
1849 2011 ASSERT(mw->mw_curms == 0);
1850 2012 ASSERT(mw->mw_nummss == 0);
1851 2013
1852 2014 vdevp = mw->mw_vdevs[mw->mw_curvdev];
1853 2015 if (GETMEMB(vdevp, "vdev", vdev_ms, mssp) ||
1854 2016 GETMEMB(vdevp, "vdev", vdev_ms_count, mw->mw_nummss)) {
1855 2017 return (WALK_ERR);
1856 2018 }
1857 2019
1858 2020 mw->mw_mss = mdb_alloc(mw->mw_nummss * sizeof (void*),
1859 2021 UM_SLEEP | UM_GC);
1860 2022 if (mdb_vread(mw->mw_mss, mw->mw_nummss * sizeof (void*),
1861 2023 mssp) == -1) {
1862 2024 mdb_warn("failed to read vdev_ms at %p", mssp);
1863 2025 return (WALK_ERR);
1864 2026 }
1865 2027 }
1866 2028
1867 2029 if (mw->mw_curms >= mw->mw_nummss) {
1868 2030 mw->mw_mss = NULL;
1869 2031 mw->mw_curms = 0;
1870 2032 mw->mw_nummss = 0;
1871 2033 mw->mw_curvdev++;
1872 2034 return (WALK_NEXT);
1873 2035 }
1874 2036
1875 2037 msp = mw->mw_mss[mw->mw_curms];
1876 2038 if (mdb_vread(&ms, sizeof (metaslab_t), msp) == -1) {
1877 2039 mdb_warn("failed to read metaslab_t at %p", msp);
1878 2040 return (WALK_ERR);
1879 2041 }
1880 2042
1881 2043 mw->mw_curms++;
1882 2044
1883 2045 return (wsp->walk_callback(msp, &ms, wsp->walk_cbdata));
1884 2046 }
1885 2047
1886 2048 static int
1887 2049 metaslab_walk_init(mdb_walk_state_t *wsp)
1888 2050 {
1889 2051 metaslab_walk_data_t *mw;
1890 2052 uintptr_t root_vdevp;
1891 2053 uintptr_t childp;
1892 2054
1893 2055 if (wsp->walk_addr == NULL) {
1894 2056 mdb_warn("must supply address of spa_t\n");
1895 2057 return (WALK_ERR);
1896 2058 }
1897 2059
1898 2060 mw = mdb_zalloc(sizeof (metaslab_walk_data_t), UM_SLEEP | UM_GC);
1899 2061
1900 2062 if (GETMEMB(wsp->walk_addr, "spa", spa_root_vdev, root_vdevp) ||
1901 2063 GETMEMB(root_vdevp, "vdev", vdev_children, mw->mw_numvdevs) ||
1902 2064 GETMEMB(root_vdevp, "vdev", vdev_child, childp)) {
1903 2065 return (DCMD_ERR);
1904 2066 }
1905 2067
1906 2068 mw->mw_vdevs = mdb_alloc(mw->mw_numvdevs * sizeof (void *),
1907 2069 UM_SLEEP | UM_GC);
1908 2070 if (mdb_vread(mw->mw_vdevs, mw->mw_numvdevs * sizeof (void *),
1909 2071 childp) == -1) {
1910 2072 mdb_warn("failed to read root vdev children at %p", childp);
1911 2073 return (DCMD_ERR);
1912 2074 }
1913 2075
1914 2076 wsp->walk_data = mw;
1915 2077
1916 2078 return (WALK_NEXT);
1917 2079 }
1918 2080
1919 2081 typedef struct mdb_spa {
1920 2082 uintptr_t spa_dsl_pool;
1921 2083 uintptr_t spa_root_vdev;
1922 2084 } mdb_spa_t;
1923 2085
1924 2086 typedef struct mdb_dsl_pool {
1925 2087 uintptr_t dp_root_dir;
1926 2088 } mdb_dsl_pool_t;
1927 2089
1928 2090 typedef struct mdb_dsl_dir {
1929 2091 uintptr_t dd_dbuf;
1930 2092 int64_t dd_space_towrite[TXG_SIZE];
1931 2093 } mdb_dsl_dir_t;
1932 2094
1933 2095 typedef struct mdb_dsl_dir_phys {
1934 2096 uint64_t dd_used_bytes;
1935 2097 uint64_t dd_compressed_bytes;
1936 2098 uint64_t dd_uncompressed_bytes;
1937 2099 } mdb_dsl_dir_phys_t;
1938 2100
1939 2101 typedef struct space_data {
1940 2102 uint64_t ms_alloctree[TXG_SIZE];
1941 2103 uint64_t ms_freeingtree;
1942 2104 uint64_t ms_freedtree;
1943 2105 uint64_t ms_tree;
1944 2106 int64_t ms_deferspace;
1945 2107 uint64_t avail;
1946 2108 uint64_t nowavail;
1947 2109 } space_data_t;
1948 2110
1949 2111 /* ARGSUSED */
1950 2112 static int
1951 2113 space_cb(uintptr_t addr, const void *unknown, void *arg)
1952 2114 {
1953 2115 space_data_t *sd = arg;
1954 2116 mdb_metaslab_t ms;
1955 2117 mdb_range_tree_t rt;
1956 2118 mdb_space_map_t sm = { 0 };
1957 2119 mdb_space_map_phys_t smp = { 0 };
1958 2120 int i;
1959 2121
1960 2122 if (mdb_ctf_vread(&ms, "metaslab_t", "mdb_metaslab_t",
1961 2123 addr, 0) == -1)
1962 2124 return (WALK_ERR);
1963 2125
1964 2126 for (i = 0; i < TXG_SIZE; i++) {
1965 2127 if (mdb_ctf_vread(&rt, "range_tree_t",
1966 2128 "mdb_range_tree_t", ms.ms_alloctree[i], 0) == -1)
1967 2129 return (WALK_ERR);
1968 2130
1969 2131 sd->ms_alloctree[i] += rt.rt_space;
1970 2132
1971 2133 }
1972 2134
1973 2135 if (mdb_ctf_vread(&rt, "range_tree_t",
1974 2136 "mdb_range_tree_t", ms.ms_freeingtree, 0) == -1)
1975 2137 return (WALK_ERR);
1976 2138 sd->ms_freeingtree += rt.rt_space;
1977 2139
1978 2140 if (mdb_ctf_vread(&rt, "range_tree_t",
1979 2141 "mdb_range_tree_t", ms.ms_freedtree, 0) == -1)
1980 2142 return (WALK_ERR);
1981 2143 sd->ms_freedtree += rt.rt_space;
1982 2144
1983 2145 if (mdb_ctf_vread(&rt, "range_tree_t",
1984 2146 "mdb_range_tree_t", ms.ms_tree, 0) == -1)
1985 2147 return (WALK_ERR);
1986 2148 sd->ms_tree += rt.rt_space;
1987 2149
1988 2150 if (ms.ms_sm != NULL &&
1989 2151 mdb_ctf_vread(&sm, "space_map_t",
1990 2152 "mdb_space_map_t", ms.ms_sm, 0) == -1)
1991 2153 return (WALK_ERR);
1992 2154
1993 2155 if (sm.sm_phys != NULL) {
1994 2156 (void) mdb_ctf_vread(&smp, "space_map_phys_t",
1995 2157 "mdb_space_map_phys_t", sm.sm_phys, 0);
1996 2158 }
1997 2159
1998 2160 sd->ms_deferspace += ms.ms_deferspace;
1999 2161 sd->avail += sm.sm_size - sm.sm_alloc;
2000 2162 sd->nowavail += sm.sm_size - smp.smp_alloc;
2001 2163
2002 2164 return (WALK_NEXT);
2003 2165 }
2004 2166
2005 2167 /*
2006 2168 * ::spa_space [-b]
2007 2169 *
2008 2170 * Given a spa_t, print out it's on-disk space usage and in-core
2009 2171 * estimates of future usage. If -b is given, print space in bytes.
2010 2172 * Otherwise print in megabytes.
2011 2173 */
2012 2174 /* ARGSUSED */
2013 2175 static int
2014 2176 spa_space(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2015 2177 {
2016 2178 mdb_spa_t spa;
2017 2179 mdb_dsl_pool_t dp;
2018 2180 mdb_dsl_dir_t dd;
2019 2181 mdb_dmu_buf_impl_t db;
2020 2182 mdb_dsl_dir_phys_t dsp;
2021 2183 space_data_t sd;
2022 2184 int shift = 20;
2023 2185 char *suffix = "M";
2024 2186 int bytes = B_FALSE;
2025 2187
2026 2188 if (mdb_getopts(argc, argv, 'b', MDB_OPT_SETBITS, TRUE, &bytes, NULL) !=
2027 2189 argc)
2028 2190 return (DCMD_USAGE);
2029 2191 if (!(flags & DCMD_ADDRSPEC))
2030 2192 return (DCMD_USAGE);
2031 2193
2032 2194 if (bytes) {
2033 2195 shift = 0;
2034 2196 suffix = "";
2035 2197 }
2036 2198
2037 2199 if (mdb_ctf_vread(&spa, ZFS_STRUCT "spa", "mdb_spa_t",
2038 2200 addr, 0) == -1 ||
2039 2201 mdb_ctf_vread(&dp, ZFS_STRUCT "dsl_pool", "mdb_dsl_pool_t",
2040 2202 spa.spa_dsl_pool, 0) == -1 ||
2041 2203 mdb_ctf_vread(&dd, ZFS_STRUCT "dsl_dir", "mdb_dsl_dir_t",
2042 2204 dp.dp_root_dir, 0) == -1 ||
2043 2205 mdb_ctf_vread(&db, ZFS_STRUCT "dmu_buf_impl", "mdb_dmu_buf_impl_t",
2044 2206 dd.dd_dbuf, 0) == -1 ||
2045 2207 mdb_ctf_vread(&dsp, ZFS_STRUCT "dsl_dir_phys",
2046 2208 "mdb_dsl_dir_phys_t", db.db.db_data, 0) == -1) {
2047 2209 return (DCMD_ERR);
2048 2210 }
2049 2211
2050 2212 mdb_printf("dd_space_towrite = %llu%s %llu%s %llu%s %llu%s\n",
2051 2213 dd.dd_space_towrite[0] >> shift, suffix,
2052 2214 dd.dd_space_towrite[1] >> shift, suffix,
2053 2215 dd.dd_space_towrite[2] >> shift, suffix,
2054 2216 dd.dd_space_towrite[3] >> shift, suffix);
2055 2217
2056 2218 mdb_printf("dd_phys.dd_used_bytes = %llu%s\n",
2057 2219 dsp.dd_used_bytes >> shift, suffix);
2058 2220 mdb_printf("dd_phys.dd_compressed_bytes = %llu%s\n",
2059 2221 dsp.dd_compressed_bytes >> shift, suffix);
2060 2222 mdb_printf("dd_phys.dd_uncompressed_bytes = %llu%s\n",
2061 2223 dsp.dd_uncompressed_bytes >> shift, suffix);
2062 2224
2063 2225 bzero(&sd, sizeof (sd));
2064 2226 if (mdb_pwalk("metaslab", space_cb, &sd, addr) != 0) {
2065 2227 mdb_warn("can't walk metaslabs");
2066 2228 return (DCMD_ERR);
2067 2229 }
|
↓ open down ↓ |
483 lines elided |
↑ open up ↑ |
2068 2230
2069 2231 mdb_printf("ms_allocmap = %llu%s %llu%s %llu%s %llu%s\n",
2070 2232 sd.ms_alloctree[0] >> shift, suffix,
2071 2233 sd.ms_alloctree[1] >> shift, suffix,
2072 2234 sd.ms_alloctree[2] >> shift, suffix,
2073 2235 sd.ms_alloctree[3] >> shift, suffix);
2074 2236 mdb_printf("ms_freeingtree = %llu%s\n",
2075 2237 sd.ms_freeingtree >> shift, suffix);
2076 2238 mdb_printf("ms_freedtree = %llu%s\n",
2077 2239 sd.ms_freedtree >> shift, suffix);
2078 - mdb_printf("ms_tree = %llu%s\n",
2079 - sd.ms_tree >> shift, suffix);
2240 + mdb_printf("ms_tree = %llu%s\n", sd.ms_tree >> shift, suffix);
2080 2241 mdb_printf("ms_deferspace = %llu%s\n",
2081 2242 sd.ms_deferspace >> shift, suffix);
2082 - mdb_printf("last synced avail = %llu%s\n",
2083 - sd.avail >> shift, suffix);
2243 + mdb_printf("last synced avail = %llu%s\n", sd.avail >> shift, suffix);
2084 2244 mdb_printf("current syncing avail = %llu%s\n",
2085 2245 sd.nowavail >> shift, suffix);
2086 2246
2087 2247 return (DCMD_OK);
2088 2248 }
2089 2249
2090 2250 typedef struct mdb_spa_aux_vdev {
2091 2251 int sav_count;
2092 2252 uintptr_t sav_vdevs;
2093 2253 } mdb_spa_aux_vdev_t;
2094 2254
2095 2255 typedef struct mdb_spa_vdevs {
2096 2256 uintptr_t spa_root_vdev;
2097 2257 mdb_spa_aux_vdev_t spa_l2cache;
2098 2258 mdb_spa_aux_vdev_t spa_spares;
2099 2259 } mdb_spa_vdevs_t;
2100 2260
2101 2261 static int
2102 2262 spa_print_aux(mdb_spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,
2103 2263 const char *name)
2104 2264 {
2105 2265 uintptr_t *aux;
2106 2266 size_t len;
2107 2267 int ret, i;
2108 2268
2109 2269 /*
2110 2270 * Iterate over aux vdevs and print those out as well. This is a
2111 2271 * little annoying because we don't have a root vdev to pass to ::vdev.
2112 2272 * Instead, we print a single line and then call it for each child
2113 2273 * vdev.
2114 2274 */
2115 2275 if (sav->sav_count != 0) {
2116 2276 v[1].a_type = MDB_TYPE_STRING;
2117 2277 v[1].a_un.a_str = "-d";
2118 2278 v[2].a_type = MDB_TYPE_IMMEDIATE;
2119 2279 v[2].a_un.a_val = 2;
2120 2280
2121 2281 len = sav->sav_count * sizeof (uintptr_t);
2122 2282 aux = mdb_alloc(len, UM_SLEEP);
2123 2283 if (mdb_vread(aux, len, sav->sav_vdevs) == -1) {
2124 2284 mdb_free(aux, len);
2125 2285 mdb_warn("failed to read l2cache vdevs at %p",
2126 2286 sav->sav_vdevs);
2127 2287 return (DCMD_ERR);
2128 2288 }
2129 2289
2130 2290 mdb_printf("%-?s %-9s %-12s %s\n", "-", "-", "-", name);
2131 2291
2132 2292 for (i = 0; i < sav->sav_count; i++) {
2133 2293 ret = mdb_call_dcmd("vdev", aux[i], flags, 3, v);
2134 2294 if (ret != DCMD_OK) {
2135 2295 mdb_free(aux, len);
2136 2296 return (ret);
2137 2297 }
2138 2298 }
2139 2299
2140 2300 mdb_free(aux, len);
2141 2301 }
2142 2302
2143 2303 return (0);
2144 2304 }
2145 2305
2146 2306 /*
2147 2307 * ::spa_vdevs
2148 2308 *
2149 2309 * -e Include error stats
2150 2310 * -m Include metaslab information
2151 2311 * -M Include metaslab group information
2152 2312 * -h Include histogram information (requires -m or -M)
2153 2313 *
2154 2314 * Print out a summarized list of vdevs for the given spa_t.
2155 2315 * This is accomplished by invoking "::vdev -re" on the root vdev, as well as
2156 2316 * iterating over the cache devices.
2157 2317 */
2158 2318 /* ARGSUSED */
2159 2319 static int
2160 2320 spa_vdevs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2161 2321 {
2162 2322 mdb_arg_t v[3];
2163 2323 int ret;
2164 2324 char opts[100] = "-r";
2165 2325 int spa_flags = 0;
2166 2326
2167 2327 if (mdb_getopts(argc, argv,
2168 2328 'e', MDB_OPT_SETBITS, SPA_FLAG_ERRORS, &spa_flags,
2169 2329 'm', MDB_OPT_SETBITS, SPA_FLAG_METASLABS, &spa_flags,
2170 2330 'M', MDB_OPT_SETBITS, SPA_FLAG_METASLAB_GROUPS, &spa_flags,
2171 2331 'h', MDB_OPT_SETBITS, SPA_FLAG_HISTOGRAMS, &spa_flags,
2172 2332 NULL) != argc)
2173 2333 return (DCMD_USAGE);
2174 2334
2175 2335 if (!(flags & DCMD_ADDRSPEC))
2176 2336 return (DCMD_USAGE);
2177 2337
2178 2338 mdb_spa_vdevs_t spa;
2179 2339 if (mdb_ctf_vread(&spa, "spa_t", "mdb_spa_vdevs_t", addr, 0) == -1)
2180 2340 return (DCMD_ERR);
2181 2341
2182 2342 /*
2183 2343 * Unitialized spa_t structures can have a NULL root vdev.
2184 2344 */
2185 2345 if (spa.spa_root_vdev == NULL) {
2186 2346 mdb_printf("no associated vdevs\n");
2187 2347 return (DCMD_OK);
2188 2348 }
2189 2349
2190 2350 if (spa_flags & SPA_FLAG_ERRORS)
2191 2351 strcat(opts, "e");
2192 2352 if (spa_flags & SPA_FLAG_METASLABS)
2193 2353 strcat(opts, "m");
2194 2354 if (spa_flags & SPA_FLAG_METASLAB_GROUPS)
2195 2355 strcat(opts, "M");
2196 2356 if (spa_flags & SPA_FLAG_HISTOGRAMS)
2197 2357 strcat(opts, "h");
2198 2358
2199 2359 v[0].a_type = MDB_TYPE_STRING;
2200 2360 v[0].a_un.a_str = opts;
2201 2361
2202 2362 ret = mdb_call_dcmd("vdev", (uintptr_t)spa.spa_root_vdev,
2203 2363 flags, 1, v);
2204 2364 if (ret != DCMD_OK)
2205 2365 return (ret);
2206 2366
2207 2367 if (spa_print_aux(&spa.spa_l2cache, flags, v, "cache") != 0 ||
2208 2368 spa_print_aux(&spa.spa_spares, flags, v, "spares") != 0)
2209 2369 return (DCMD_ERR);
2210 2370
2211 2371 return (DCMD_OK);
2212 2372 }
2213 2373
2214 2374 /*
2215 2375 * ::zio
2216 2376 *
2217 2377 * Print a summary of zio_t and all its children. This is intended to display a
2218 2378 * zio tree, and hence we only pick the most important pieces of information for
2219 2379 * the main summary. More detailed information can always be found by doing a
2220 2380 * '::print zio' on the underlying zio_t. The columns we display are:
2221 2381 *
2222 2382 * ADDRESS TYPE STAGE WAITER TIME_ELAPSED
2223 2383 *
2224 2384 * The 'address' column is indented by one space for each depth level as we
2225 2385 * descend down the tree.
2226 2386 */
2227 2387
2228 2388 #define ZIO_MAXINDENT 7
2229 2389 #define ZIO_MAXWIDTH (sizeof (uintptr_t) * 2 + ZIO_MAXINDENT)
2230 2390 #define ZIO_WALK_SELF 0
2231 2391 #define ZIO_WALK_CHILD 1
2232 2392 #define ZIO_WALK_PARENT 2
2233 2393
2234 2394 typedef struct zio_print_args {
2235 2395 int zpa_current_depth;
2236 2396 int zpa_min_depth;
2237 2397 int zpa_max_depth;
2238 2398 int zpa_type;
2239 2399 uint_t zpa_flags;
2240 2400 } zio_print_args_t;
2241 2401
2242 2402 typedef struct mdb_zio {
2243 2403 enum zio_type io_type;
2244 2404 enum zio_stage io_stage;
2245 2405 uintptr_t io_waiter;
2246 2406 uintptr_t io_spa;
2247 2407 struct {
2248 2408 struct {
2249 2409 uintptr_t list_next;
2250 2410 } list_head;
2251 2411 } io_parent_list;
2252 2412 int io_error;
2253 2413 } mdb_zio_t;
2254 2414
2255 2415 typedef struct mdb_zio_timestamp {
2256 2416 hrtime_t io_timestamp;
2257 2417 } mdb_zio_timestamp_t;
2258 2418
2259 2419 static int zio_child_cb(uintptr_t addr, const void *unknown, void *arg);
2260 2420
2261 2421 static int
2262 2422 zio_print_cb(uintptr_t addr, zio_print_args_t *zpa)
2263 2423 {
2264 2424 mdb_ctf_id_t type_enum, stage_enum;
2265 2425 int indent = zpa->zpa_current_depth;
2266 2426 const char *type, *stage;
2267 2427 uintptr_t laddr;
2268 2428 mdb_zio_t zio;
2269 2429 mdb_zio_timestamp_t zio_timestamp = { 0 };
2270 2430
2271 2431 if (mdb_ctf_vread(&zio, ZFS_STRUCT "zio", "mdb_zio_t", addr, 0) == -1)
2272 2432 return (WALK_ERR);
2273 2433 (void) mdb_ctf_vread(&zio_timestamp, ZFS_STRUCT "zio",
2274 2434 "mdb_zio_timestamp_t", addr, MDB_CTF_VREAD_QUIET);
2275 2435
2276 2436 if (indent > ZIO_MAXINDENT)
2277 2437 indent = ZIO_MAXINDENT;
2278 2438
2279 2439 if (mdb_ctf_lookup_by_name("enum zio_type", &type_enum) == -1 ||
2280 2440 mdb_ctf_lookup_by_name("enum zio_stage", &stage_enum) == -1) {
2281 2441 mdb_warn("failed to lookup zio enums");
2282 2442 return (WALK_ERR);
2283 2443 }
2284 2444
2285 2445 if ((type = mdb_ctf_enum_name(type_enum, zio.io_type)) != NULL)
2286 2446 type += sizeof ("ZIO_TYPE_") - 1;
2287 2447 else
2288 2448 type = "?";
2289 2449
2290 2450 if (zio.io_error == 0) {
2291 2451 stage = mdb_ctf_enum_name(stage_enum, zio.io_stage);
2292 2452 if (stage != NULL)
2293 2453 stage += sizeof ("ZIO_STAGE_") - 1;
2294 2454 else
2295 2455 stage = "?";
2296 2456 } else {
2297 2457 stage = "FAILED";
2298 2458 }
2299 2459
2300 2460 if (zpa->zpa_current_depth >= zpa->zpa_min_depth) {
2301 2461 if (zpa->zpa_flags & DCMD_PIPE_OUT) {
2302 2462 mdb_printf("%?p\n", addr);
2303 2463 } else {
2304 2464 mdb_printf("%*s%-*p %-5s %-16s ", indent, "",
2305 2465 ZIO_MAXWIDTH - indent, addr, type, stage);
2306 2466 if (zio.io_waiter != 0)
2307 2467 mdb_printf("%-16lx ", zio.io_waiter);
2308 2468 else
2309 2469 mdb_printf("%-16s ", "-");
2310 2470 #ifdef _KERNEL
2311 2471 if (zio_timestamp.io_timestamp != 0) {
2312 2472 mdb_printf("%llums", (mdb_gethrtime() -
2313 2473 zio_timestamp.io_timestamp) /
2314 2474 1000000);
2315 2475 } else {
2316 2476 mdb_printf("%-12s ", "-");
2317 2477 }
2318 2478 #else
2319 2479 mdb_printf("%-12s ", "-");
2320 2480 #endif
2321 2481 mdb_printf("\n");
2322 2482 }
2323 2483 }
2324 2484
2325 2485 if (zpa->zpa_current_depth >= zpa->zpa_max_depth)
2326 2486 return (WALK_NEXT);
2327 2487
2328 2488 if (zpa->zpa_type == ZIO_WALK_PARENT)
2329 2489 laddr = addr + mdb_ctf_offsetof_by_name(ZFS_STRUCT "zio",
2330 2490 "io_parent_list");
2331 2491 else
2332 2492 laddr = addr + mdb_ctf_offsetof_by_name(ZFS_STRUCT "zio",
2333 2493 "io_child_list");
2334 2494
2335 2495 zpa->zpa_current_depth++;
2336 2496 if (mdb_pwalk("list", zio_child_cb, zpa, laddr) != 0) {
2337 2497 mdb_warn("failed to walk zio_t children at %p\n", laddr);
2338 2498 return (WALK_ERR);
2339 2499 }
2340 2500 zpa->zpa_current_depth--;
2341 2501
2342 2502 return (WALK_NEXT);
2343 2503 }
2344 2504
2345 2505 /* ARGSUSED */
2346 2506 static int
2347 2507 zio_child_cb(uintptr_t addr, const void *unknown, void *arg)
2348 2508 {
2349 2509 zio_link_t zl;
2350 2510 uintptr_t ziop;
2351 2511 zio_print_args_t *zpa = arg;
2352 2512
2353 2513 if (mdb_vread(&zl, sizeof (zl), addr) == -1) {
2354 2514 mdb_warn("failed to read zio_link_t at %p", addr);
2355 2515 return (WALK_ERR);
2356 2516 }
2357 2517
2358 2518 if (zpa->zpa_type == ZIO_WALK_PARENT)
2359 2519 ziop = (uintptr_t)zl.zl_parent;
2360 2520 else
2361 2521 ziop = (uintptr_t)zl.zl_child;
2362 2522
2363 2523 return (zio_print_cb(ziop, zpa));
2364 2524 }
2365 2525
2366 2526 /* ARGSUSED */
2367 2527 static int
2368 2528 zio_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2369 2529 {
2370 2530 zio_print_args_t zpa = { 0 };
2371 2531
2372 2532 if (!(flags & DCMD_ADDRSPEC))
2373 2533 return (DCMD_USAGE);
2374 2534
2375 2535 if (mdb_getopts(argc, argv,
2376 2536 'r', MDB_OPT_SETBITS, INT_MAX, &zpa.zpa_max_depth,
2377 2537 'c', MDB_OPT_SETBITS, ZIO_WALK_CHILD, &zpa.zpa_type,
2378 2538 'p', MDB_OPT_SETBITS, ZIO_WALK_PARENT, &zpa.zpa_type,
2379 2539 NULL) != argc)
2380 2540 return (DCMD_USAGE);
2381 2541
2382 2542 zpa.zpa_flags = flags;
2383 2543 if (zpa.zpa_max_depth != 0) {
2384 2544 if (zpa.zpa_type == ZIO_WALK_SELF)
2385 2545 zpa.zpa_type = ZIO_WALK_CHILD;
2386 2546 } else if (zpa.zpa_type != ZIO_WALK_SELF) {
2387 2547 zpa.zpa_min_depth = 1;
2388 2548 zpa.zpa_max_depth = 1;
2389 2549 }
2390 2550
2391 2551 if (!(flags & DCMD_PIPE_OUT) && DCMD_HDRSPEC(flags)) {
2392 2552 mdb_printf("%<u>%-*s %-5s %-16s %-16s %-12s%</u>\n",
2393 2553 ZIO_MAXWIDTH, "ADDRESS", "TYPE", "STAGE", "WAITER",
2394 2554 "TIME_ELAPSED");
2395 2555 }
2396 2556
2397 2557 if (zio_print_cb(addr, &zpa) != WALK_NEXT)
2398 2558 return (DCMD_ERR);
2399 2559
2400 2560 return (DCMD_OK);
2401 2561 }
2402 2562
2403 2563 /*
2404 2564 * [addr]::zio_state
2405 2565 *
2406 2566 * Print a summary of all zio_t structures on the system, or for a particular
2407 2567 * pool. This is equivalent to '::walk zio_root | ::zio'.
2408 2568 */
2409 2569 /*ARGSUSED*/
2410 2570 static int
2411 2571 zio_state(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2412 2572 {
2413 2573 /*
2414 2574 * MDB will remember the last address of the pipeline, so if we don't
2415 2575 * zero this we'll end up trying to walk zio structures for a
2416 2576 * non-existent spa_t.
2417 2577 */
2418 2578 if (!(flags & DCMD_ADDRSPEC))
2419 2579 addr = 0;
2420 2580
2421 2581 return (mdb_pwalk_dcmd("zio_root", "zio", argc, argv, addr));
2422 2582 }
2423 2583
2424 2584 typedef struct mdb_multilist {
2425 2585 uint64_t ml_num_sublists;
2426 2586 uintptr_t ml_sublists;
2427 2587 } mdb_multilist_t;
2428 2588
2429 2589 typedef struct multilist_walk_data {
2430 2590 uint64_t mwd_idx;
2431 2591 mdb_multilist_t mwd_ml;
2432 2592 } multilist_walk_data_t;
2433 2593
2434 2594 /* ARGSUSED */
2435 2595 static int
2436 2596 multilist_print_cb(uintptr_t addr, const void *unknown, void *arg)
2437 2597 {
2438 2598 mdb_printf("%#lr\n", addr);
2439 2599 return (WALK_NEXT);
2440 2600 }
2441 2601
2442 2602 static int
2443 2603 multilist_walk_step(mdb_walk_state_t *wsp)
2444 2604 {
2445 2605 multilist_walk_data_t *mwd = wsp->walk_data;
2446 2606
2447 2607 if (mwd->mwd_idx >= mwd->mwd_ml.ml_num_sublists)
2448 2608 return (WALK_DONE);
2449 2609
2450 2610 wsp->walk_addr = mwd->mwd_ml.ml_sublists +
2451 2611 mdb_ctf_sizeof_by_name("multilist_sublist_t") * mwd->mwd_idx +
2452 2612 mdb_ctf_offsetof_by_name("multilist_sublist_t", "mls_list");
2453 2613
2454 2614 mdb_pwalk("list", multilist_print_cb, (void*)NULL, wsp->walk_addr);
2455 2615 mwd->mwd_idx++;
2456 2616
2457 2617 return (WALK_NEXT);
2458 2618 }
2459 2619
2460 2620 static int
2461 2621 multilist_walk_init(mdb_walk_state_t *wsp)
2462 2622 {
2463 2623 multilist_walk_data_t *mwd;
2464 2624
2465 2625 if (wsp->walk_addr == NULL) {
2466 2626 mdb_warn("must supply address of multilist_t\n");
2467 2627 return (WALK_ERR);
2468 2628 }
2469 2629
2470 2630 mwd = mdb_zalloc(sizeof (multilist_walk_data_t), UM_SLEEP | UM_GC);
2471 2631 if (mdb_ctf_vread(&mwd->mwd_ml, "multilist_t", "mdb_multilist_t",
2472 2632 wsp->walk_addr, 0) == -1) {
2473 2633 return (WALK_ERR);
2474 2634 }
2475 2635
2476 2636 if (mwd->mwd_ml.ml_num_sublists == 0 ||
2477 2637 mwd->mwd_ml.ml_sublists == NULL) {
2478 2638 mdb_warn("invalid or uninitialized multilist at %#lx\n",
2479 2639 wsp->walk_addr);
2480 2640 return (WALK_ERR);
2481 2641 }
2482 2642
2483 2643 wsp->walk_data = mwd;
2484 2644 return (WALK_NEXT);
2485 2645 }
2486 2646
2487 2647 typedef struct mdb_txg_list {
2488 2648 size_t tl_offset;
2489 2649 uintptr_t tl_head[TXG_SIZE];
2490 2650 } mdb_txg_list_t;
2491 2651
2492 2652 typedef struct txg_list_walk_data {
2493 2653 uintptr_t lw_head[TXG_SIZE];
2494 2654 int lw_txgoff;
2495 2655 int lw_maxoff;
2496 2656 size_t lw_offset;
2497 2657 void *lw_obj;
2498 2658 } txg_list_walk_data_t;
2499 2659
2500 2660 static int
2501 2661 txg_list_walk_init_common(mdb_walk_state_t *wsp, int txg, int maxoff)
2502 2662 {
2503 2663 txg_list_walk_data_t *lwd;
2504 2664 mdb_txg_list_t list;
2505 2665 int i;
2506 2666
2507 2667 lwd = mdb_alloc(sizeof (txg_list_walk_data_t), UM_SLEEP | UM_GC);
2508 2668 if (mdb_ctf_vread(&list, "txg_list_t", "mdb_txg_list_t", wsp->walk_addr,
2509 2669 0) == -1) {
2510 2670 mdb_warn("failed to read txg_list_t at %#lx", wsp->walk_addr);
2511 2671 return (WALK_ERR);
2512 2672 }
2513 2673
2514 2674 for (i = 0; i < TXG_SIZE; i++)
2515 2675 lwd->lw_head[i] = list.tl_head[i];
2516 2676 lwd->lw_offset = list.tl_offset;
2517 2677 lwd->lw_obj = mdb_alloc(lwd->lw_offset + sizeof (txg_node_t),
2518 2678 UM_SLEEP | UM_GC);
2519 2679 lwd->lw_txgoff = txg;
2520 2680 lwd->lw_maxoff = maxoff;
2521 2681
2522 2682 wsp->walk_addr = lwd->lw_head[lwd->lw_txgoff];
2523 2683 wsp->walk_data = lwd;
2524 2684
2525 2685 return (WALK_NEXT);
2526 2686 }
2527 2687
2528 2688 static int
2529 2689 txg_list_walk_init(mdb_walk_state_t *wsp)
2530 2690 {
2531 2691 return (txg_list_walk_init_common(wsp, 0, TXG_SIZE-1));
2532 2692 }
2533 2693
2534 2694 static int
2535 2695 txg_list0_walk_init(mdb_walk_state_t *wsp)
2536 2696 {
2537 2697 return (txg_list_walk_init_common(wsp, 0, 0));
2538 2698 }
2539 2699
2540 2700 static int
2541 2701 txg_list1_walk_init(mdb_walk_state_t *wsp)
2542 2702 {
2543 2703 return (txg_list_walk_init_common(wsp, 1, 1));
2544 2704 }
2545 2705
2546 2706 static int
2547 2707 txg_list2_walk_init(mdb_walk_state_t *wsp)
2548 2708 {
2549 2709 return (txg_list_walk_init_common(wsp, 2, 2));
2550 2710 }
2551 2711
2552 2712 static int
2553 2713 txg_list3_walk_init(mdb_walk_state_t *wsp)
2554 2714 {
2555 2715 return (txg_list_walk_init_common(wsp, 3, 3));
2556 2716 }
2557 2717
2558 2718 static int
2559 2719 txg_list_walk_step(mdb_walk_state_t *wsp)
2560 2720 {
2561 2721 txg_list_walk_data_t *lwd = wsp->walk_data;
2562 2722 uintptr_t addr;
2563 2723 txg_node_t *node;
2564 2724 int status;
2565 2725
2566 2726 while (wsp->walk_addr == NULL && lwd->lw_txgoff < lwd->lw_maxoff) {
2567 2727 lwd->lw_txgoff++;
2568 2728 wsp->walk_addr = lwd->lw_head[lwd->lw_txgoff];
2569 2729 }
2570 2730
2571 2731 if (wsp->walk_addr == NULL)
2572 2732 return (WALK_DONE);
2573 2733
2574 2734 addr = wsp->walk_addr - lwd->lw_offset;
2575 2735
2576 2736 if (mdb_vread(lwd->lw_obj,
2577 2737 lwd->lw_offset + sizeof (txg_node_t), addr) == -1) {
2578 2738 mdb_warn("failed to read list element at %#lx", addr);
2579 2739 return (WALK_ERR);
2580 2740 }
2581 2741
2582 2742 status = wsp->walk_callback(addr, lwd->lw_obj, wsp->walk_cbdata);
2583 2743 node = (txg_node_t *)((uintptr_t)lwd->lw_obj + lwd->lw_offset);
2584 2744 wsp->walk_addr = (uintptr_t)node->tn_next[lwd->lw_txgoff];
2585 2745
2586 2746 return (status);
2587 2747 }
2588 2748
2589 2749 /*
2590 2750 * ::walk spa
2591 2751 *
2592 2752 * Walk all named spa_t structures in the namespace. This is nothing more than
2593 2753 * a layered avl walk.
2594 2754 */
2595 2755 static int
2596 2756 spa_walk_init(mdb_walk_state_t *wsp)
2597 2757 {
2598 2758 GElf_Sym sym;
2599 2759
2600 2760 if (wsp->walk_addr != NULL) {
2601 2761 mdb_warn("spa walk only supports global walks\n");
2602 2762 return (WALK_ERR);
2603 2763 }
2604 2764
2605 2765 if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "spa_namespace_avl", &sym) == -1) {
2606 2766 mdb_warn("failed to find symbol 'spa_namespace_avl'");
2607 2767 return (WALK_ERR);
2608 2768 }
2609 2769
2610 2770 wsp->walk_addr = (uintptr_t)sym.st_value;
2611 2771
2612 2772 if (mdb_layered_walk("avl", wsp) == -1) {
2613 2773 mdb_warn("failed to walk 'avl'\n");
2614 2774 return (WALK_ERR);
2615 2775 }
2616 2776
2617 2777 return (WALK_NEXT);
2618 2778 }
2619 2779
2620 2780 static int
2621 2781 spa_walk_step(mdb_walk_state_t *wsp)
2622 2782 {
2623 2783 return (wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata));
2624 2784 }
2625 2785
2626 2786 /*
2627 2787 * [addr]::walk zio
2628 2788 *
2629 2789 * Walk all active zio_t structures on the system. This is simply a layered
2630 2790 * walk on top of ::walk zio_cache, with the optional ability to limit the
2631 2791 * structures to a particular pool.
2632 2792 */
2633 2793 static int
2634 2794 zio_walk_init(mdb_walk_state_t *wsp)
2635 2795 {
2636 2796 wsp->walk_data = (void *)wsp->walk_addr;
2637 2797
2638 2798 if (mdb_layered_walk("zio_cache", wsp) == -1) {
2639 2799 mdb_warn("failed to walk 'zio_cache'\n");
2640 2800 return (WALK_ERR);
2641 2801 }
2642 2802
2643 2803 return (WALK_NEXT);
2644 2804 }
2645 2805
2646 2806 static int
2647 2807 zio_walk_step(mdb_walk_state_t *wsp)
2648 2808 {
2649 2809 mdb_zio_t zio;
2650 2810 uintptr_t spa = (uintptr_t)wsp->walk_data;
2651 2811
2652 2812 if (mdb_ctf_vread(&zio, ZFS_STRUCT "zio", "mdb_zio_t",
2653 2813 wsp->walk_addr, 0) == -1)
2654 2814 return (WALK_ERR);
2655 2815
2656 2816 if (spa != 0 && spa != zio.io_spa)
2657 2817 return (WALK_NEXT);
2658 2818
2659 2819 return (wsp->walk_callback(wsp->walk_addr, &zio, wsp->walk_cbdata));
2660 2820 }
2661 2821
2662 2822 /*
2663 2823 * [addr]::walk zio_root
2664 2824 *
2665 2825 * Walk only root zio_t structures, optionally for a particular spa_t.
2666 2826 */
2667 2827 static int
2668 2828 zio_walk_root_step(mdb_walk_state_t *wsp)
2669 2829 {
2670 2830 mdb_zio_t zio;
2671 2831 uintptr_t spa = (uintptr_t)wsp->walk_data;
2672 2832
2673 2833 if (mdb_ctf_vread(&zio, ZFS_STRUCT "zio", "mdb_zio_t",
2674 2834 wsp->walk_addr, 0) == -1)
2675 2835 return (WALK_ERR);
2676 2836
2677 2837 if (spa != 0 && spa != zio.io_spa)
2678 2838 return (WALK_NEXT);
2679 2839
2680 2840 /* If the parent list is not empty, ignore */
2681 2841 if (zio.io_parent_list.list_head.list_next !=
2682 2842 wsp->walk_addr +
2683 2843 mdb_ctf_offsetof_by_name(ZFS_STRUCT "zio", "io_parent_list") +
2684 2844 mdb_ctf_offsetof_by_name("struct list", "list_head"))
2685 2845 return (WALK_NEXT);
2686 2846
2687 2847 return (wsp->walk_callback(wsp->walk_addr, &zio, wsp->walk_cbdata));
2688 2848 }
2689 2849
2690 2850 /*
2691 2851 * ::zfs_blkstats
2692 2852 *
2693 2853 * -v print verbose per-level information
2694 2854 *
2695 2855 */
2696 2856 static int
2697 2857 zfs_blkstats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2698 2858 {
2699 2859 boolean_t verbose = B_FALSE;
2700 2860 zfs_all_blkstats_t stats;
2701 2861 dmu_object_type_t t;
2702 2862 zfs_blkstat_t *tzb;
2703 2863 uint64_t ditto;
2704 2864 dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES + 10];
2705 2865 /* +10 in case it grew */
2706 2866
2707 2867 if (mdb_readvar(&dmu_ot, "dmu_ot") == -1) {
2708 2868 mdb_warn("failed to read 'dmu_ot'");
2709 2869 return (DCMD_ERR);
2710 2870 }
2711 2871
2712 2872 if (mdb_getopts(argc, argv,
2713 2873 'v', MDB_OPT_SETBITS, TRUE, &verbose,
2714 2874 NULL) != argc)
2715 2875 return (DCMD_USAGE);
2716 2876
2717 2877 if (!(flags & DCMD_ADDRSPEC))
2718 2878 return (DCMD_USAGE);
2719 2879
2720 2880 if (GETMEMB(addr, "spa", spa_dsl_pool, addr) ||
2721 2881 GETMEMB(addr, "dsl_pool", dp_blkstats, addr) ||
2722 2882 mdb_vread(&stats, sizeof (zfs_all_blkstats_t), addr) == -1) {
2723 2883 mdb_warn("failed to read data at %p;", addr);
2724 2884 mdb_printf("maybe no stats? run \"zpool scrub\" first.");
2725 2885 return (DCMD_ERR);
2726 2886 }
2727 2887
2728 2888 tzb = &stats.zab_type[DN_MAX_LEVELS][DMU_OT_TOTAL];
2729 2889 if (tzb->zb_gangs != 0) {
2730 2890 mdb_printf("Ganged blocks: %llu\n",
2731 2891 (longlong_t)tzb->zb_gangs);
2732 2892 }
2733 2893
2734 2894 ditto = tzb->zb_ditto_2_of_2_samevdev + tzb->zb_ditto_2_of_3_samevdev +
2735 2895 tzb->zb_ditto_3_of_3_samevdev;
2736 2896 if (ditto != 0) {
2737 2897 mdb_printf("Dittoed blocks on same vdev: %llu\n",
2738 2898 (longlong_t)ditto);
2739 2899 }
2740 2900
2741 2901 mdb_printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
2742 2902 "\t avg\t comp\t%%Total\tType\n");
2743 2903
2744 2904 for (t = 0; t <= DMU_OT_TOTAL; t++) {
2745 2905 char csize[NICENUM_BUFLEN], lsize[NICENUM_BUFLEN];
2746 2906 char psize[NICENUM_BUFLEN], asize[NICENUM_BUFLEN];
2747 2907 char avg[NICENUM_BUFLEN];
2748 2908 char comp[NICENUM_BUFLEN], pct[NICENUM_BUFLEN];
2749 2909 char typename[64];
2750 2910 int l;
2751 2911
2752 2912
2753 2913 if (t == DMU_OT_DEFERRED)
2754 2914 strcpy(typename, "deferred free");
2755 2915 else if (t == DMU_OT_OTHER)
2756 2916 strcpy(typename, "other");
2757 2917 else if (t == DMU_OT_TOTAL)
2758 2918 strcpy(typename, "Total");
2759 2919 else if (mdb_readstr(typename, sizeof (typename),
2760 2920 (uintptr_t)dmu_ot[t].ot_name) == -1) {
2761 2921 mdb_warn("failed to read type name");
2762 2922 return (DCMD_ERR);
2763 2923 }
2764 2924
2765 2925 if (stats.zab_type[DN_MAX_LEVELS][t].zb_asize == 0)
2766 2926 continue;
2767 2927
2768 2928 for (l = -1; l < DN_MAX_LEVELS; l++) {
2769 2929 int level = (l == -1 ? DN_MAX_LEVELS : l);
2770 2930 zfs_blkstat_t *zb = &stats.zab_type[level][t];
2771 2931
2772 2932 if (zb->zb_asize == 0)
2773 2933 continue;
2774 2934
2775 2935 /*
2776 2936 * Don't print each level unless requested.
2777 2937 */
2778 2938 if (!verbose && level != DN_MAX_LEVELS)
2779 2939 continue;
2780 2940
2781 2941 /*
2782 2942 * If all the space is level 0, don't print the
2783 2943 * level 0 separately.
2784 2944 */
2785 2945 if (level == 0 && zb->zb_asize ==
2786 2946 stats.zab_type[DN_MAX_LEVELS][t].zb_asize)
2787 2947 continue;
2788 2948
2789 2949 mdb_nicenum(zb->zb_count, csize);
2790 2950 mdb_nicenum(zb->zb_lsize, lsize);
2791 2951 mdb_nicenum(zb->zb_psize, psize);
2792 2952 mdb_nicenum(zb->zb_asize, asize);
2793 2953 mdb_nicenum(zb->zb_asize / zb->zb_count, avg);
2794 2954 (void) snprintfrac(comp, NICENUM_BUFLEN,
2795 2955 zb->zb_lsize, zb->zb_psize, 2);
2796 2956 (void) snprintfrac(pct, NICENUM_BUFLEN,
2797 2957 100 * zb->zb_asize, tzb->zb_asize, 2);
2798 2958
2799 2959 mdb_printf("%6s\t%5s\t%5s\t%5s\t%5s"
2800 2960 "\t%5s\t%6s\t",
2801 2961 csize, lsize, psize, asize, avg, comp, pct);
2802 2962
2803 2963 if (level == DN_MAX_LEVELS)
2804 2964 mdb_printf("%s\n", typename);
2805 2965 else
2806 2966 mdb_printf(" L%d %s\n",
2807 2967 level, typename);
2808 2968 }
2809 2969 }
2810 2970
2811 2971 return (DCMD_OK);
2812 2972 }
2813 2973
2814 2974 typedef struct mdb_reference {
2815 2975 uintptr_t ref_holder;
2816 2976 uintptr_t ref_removed;
2817 2977 uint64_t ref_number;
2818 2978 } mdb_reference_t;
2819 2979
2820 2980 /* ARGSUSED */
2821 2981 static int
2822 2982 reference_cb(uintptr_t addr, const void *ignored, void *arg)
2823 2983 {
2824 2984 mdb_reference_t ref;
2825 2985 boolean_t holder_is_str = B_FALSE;
2826 2986 char holder_str[128];
2827 2987 boolean_t removed = (boolean_t)arg;
2828 2988
2829 2989 if (mdb_ctf_vread(&ref, "reference_t", "mdb_reference_t", addr,
2830 2990 0) == -1)
2831 2991 return (DCMD_ERR);
2832 2992
2833 2993 if (mdb_readstr(holder_str, sizeof (holder_str),
2834 2994 ref.ref_holder) != -1)
2835 2995 holder_is_str = strisprint(holder_str);
2836 2996
2837 2997 if (removed)
2838 2998 mdb_printf("removed ");
2839 2999 mdb_printf("reference ");
2840 3000 if (ref.ref_number != 1)
2841 3001 mdb_printf("with count=%llu ", ref.ref_number);
2842 3002 mdb_printf("with tag %lx", ref.ref_holder);
2843 3003 if (holder_is_str)
2844 3004 mdb_printf(" \"%s\"", holder_str);
2845 3005 mdb_printf(", held at:\n");
2846 3006
2847 3007 (void) mdb_call_dcmd("whatis", addr, DCMD_ADDRSPEC, 0, NULL);
2848 3008
2849 3009 if (removed) {
2850 3010 mdb_printf("removed at:\n");
2851 3011 (void) mdb_call_dcmd("whatis", ref.ref_removed,
2852 3012 DCMD_ADDRSPEC, 0, NULL);
2853 3013 }
2854 3014
2855 3015 mdb_printf("\n");
2856 3016
2857 3017 return (WALK_NEXT);
2858 3018 }
2859 3019
2860 3020 typedef struct mdb_refcount {
2861 3021 uint64_t rc_count;
2862 3022 } mdb_refcount_t;
2863 3023
2864 3024 typedef struct mdb_refcount_removed {
2865 3025 uint64_t rc_removed_count;
2866 3026 } mdb_refcount_removed_t;
2867 3027
2868 3028 typedef struct mdb_refcount_tracked {
2869 3029 boolean_t rc_tracked;
2870 3030 } mdb_refcount_tracked_t;
2871 3031
2872 3032 /* ARGSUSED */
2873 3033 static int
2874 3034 refcount(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2875 3035 {
2876 3036 mdb_refcount_t rc;
2877 3037 mdb_refcount_removed_t rcr;
2878 3038 mdb_refcount_tracked_t rct;
2879 3039 int off;
2880 3040 boolean_t released = B_FALSE;
2881 3041
2882 3042 if (!(flags & DCMD_ADDRSPEC))
2883 3043 return (DCMD_USAGE);
2884 3044
2885 3045 if (mdb_getopts(argc, argv,
2886 3046 'r', MDB_OPT_SETBITS, B_TRUE, &released,
2887 3047 NULL) != argc)
2888 3048 return (DCMD_USAGE);
2889 3049
2890 3050 if (mdb_ctf_vread(&rc, "refcount_t", "mdb_refcount_t", addr,
2891 3051 0) == -1)
2892 3052 return (DCMD_ERR);
2893 3053
2894 3054 if (mdb_ctf_vread(&rcr, "refcount_t", "mdb_refcount_removed_t", addr,
2895 3055 MDB_CTF_VREAD_QUIET) == -1) {
2896 3056 mdb_printf("refcount_t at %p has %llu holds (untracked)\n",
2897 3057 addr, (longlong_t)rc.rc_count);
2898 3058 return (DCMD_OK);
2899 3059 }
2900 3060
2901 3061 if (mdb_ctf_vread(&rct, "refcount_t", "mdb_refcount_tracked_t", addr,
2902 3062 MDB_CTF_VREAD_QUIET) == -1) {
2903 3063 /* If this is an old target, it might be tracked. */
2904 3064 rct.rc_tracked = B_TRUE;
2905 3065 }
2906 3066
2907 3067 mdb_printf("refcount_t at %p has %llu current holds, "
2908 3068 "%llu recently released holds\n",
2909 3069 addr, (longlong_t)rc.rc_count, (longlong_t)rcr.rc_removed_count);
2910 3070
2911 3071 if (rct.rc_tracked && rc.rc_count > 0)
2912 3072 mdb_printf("current holds:\n");
2913 3073 off = mdb_ctf_offsetof_by_name("refcount_t", "rc_list");
2914 3074 if (off == -1)
2915 3075 return (DCMD_ERR);
2916 3076 mdb_pwalk("list", reference_cb, (void*)B_FALSE, addr + off);
2917 3077
2918 3078 if (released && rcr.rc_removed_count > 0) {
2919 3079 mdb_printf("released holds:\n");
2920 3080
2921 3081 off = mdb_ctf_offsetof_by_name("refcount_t", "rc_removed");
2922 3082 if (off == -1)
2923 3083 return (DCMD_ERR);
2924 3084 mdb_pwalk("list", reference_cb, (void*)B_TRUE, addr + off);
2925 3085 }
2926 3086
2927 3087 return (DCMD_OK);
2928 3088 }
2929 3089
2930 3090 /* ARGSUSED */
2931 3091 static int
2932 3092 sa_attr_table(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2933 3093 {
2934 3094 sa_attr_table_t *table;
2935 3095 sa_os_t sa_os;
2936 3096 char *name;
2937 3097 int i;
2938 3098
2939 3099 if (mdb_vread(&sa_os, sizeof (sa_os_t), addr) == -1) {
2940 3100 mdb_warn("failed to read sa_os at %p", addr);
2941 3101 return (DCMD_ERR);
2942 3102 }
2943 3103
2944 3104 table = mdb_alloc(sizeof (sa_attr_table_t) * sa_os.sa_num_attrs,
2945 3105 UM_SLEEP | UM_GC);
2946 3106 name = mdb_alloc(MAXPATHLEN, UM_SLEEP | UM_GC);
2947 3107
2948 3108 if (mdb_vread(table, sizeof (sa_attr_table_t) * sa_os.sa_num_attrs,
2949 3109 (uintptr_t)sa_os.sa_attr_table) == -1) {
2950 3110 mdb_warn("failed to read sa_os at %p", addr);
2951 3111 return (DCMD_ERR);
2952 3112 }
2953 3113
2954 3114 mdb_printf("%<u>%-10s %-10s %-10s %-10s %s%</u>\n",
2955 3115 "ATTR ID", "REGISTERED", "LENGTH", "BSWAP", "NAME");
2956 3116 for (i = 0; i != sa_os.sa_num_attrs; i++) {
2957 3117 mdb_readstr(name, MAXPATHLEN, (uintptr_t)table[i].sa_name);
2958 3118 mdb_printf("%5x %8x %8x %8x %-s\n",
2959 3119 (int)table[i].sa_attr, (int)table[i].sa_registered,
2960 3120 (int)table[i].sa_length, table[i].sa_byteswap, name);
2961 3121 }
2962 3122
2963 3123 return (DCMD_OK);
2964 3124 }
2965 3125
2966 3126 static int
2967 3127 sa_get_off_table(uintptr_t addr, uint32_t **off_tab, int attr_count)
2968 3128 {
2969 3129 uintptr_t idx_table;
2970 3130
2971 3131 if (GETMEMB(addr, "sa_idx_tab", sa_idx_tab, idx_table)) {
2972 3132 mdb_printf("can't find offset table in sa_idx_tab\n");
2973 3133 return (-1);
2974 3134 }
2975 3135
2976 3136 *off_tab = mdb_alloc(attr_count * sizeof (uint32_t),
2977 3137 UM_SLEEP | UM_GC);
2978 3138
2979 3139 if (mdb_vread(*off_tab,
2980 3140 attr_count * sizeof (uint32_t), idx_table) == -1) {
2981 3141 mdb_warn("failed to attribute offset table %p", idx_table);
2982 3142 return (-1);
2983 3143 }
2984 3144
2985 3145 return (DCMD_OK);
2986 3146 }
2987 3147
2988 3148 /*ARGSUSED*/
2989 3149 static int
2990 3150 sa_attr_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2991 3151 {
2992 3152 uint32_t *offset_tab;
2993 3153 int attr_count;
2994 3154 uint64_t attr_id;
2995 3155 uintptr_t attr_addr;
2996 3156 uintptr_t bonus_tab, spill_tab;
2997 3157 uintptr_t db_bonus, db_spill;
2998 3158 uintptr_t os, os_sa;
2999 3159 uintptr_t db_data;
3000 3160
3001 3161 if (argc != 1)
3002 3162 return (DCMD_USAGE);
3003 3163
3004 3164 if (argv[0].a_type == MDB_TYPE_STRING)
3005 3165 attr_id = mdb_strtoull(argv[0].a_un.a_str);
3006 3166 else
3007 3167 return (DCMD_USAGE);
3008 3168
3009 3169 if (GETMEMB(addr, "sa_handle", sa_bonus_tab, bonus_tab) ||
3010 3170 GETMEMB(addr, "sa_handle", sa_spill_tab, spill_tab) ||
3011 3171 GETMEMB(addr, "sa_handle", sa_os, os) ||
3012 3172 GETMEMB(addr, "sa_handle", sa_bonus, db_bonus) ||
3013 3173 GETMEMB(addr, "sa_handle", sa_spill, db_spill)) {
3014 3174 mdb_printf("Can't find necessary information in sa_handle "
3015 3175 "in sa_handle\n");
3016 3176 return (DCMD_ERR);
3017 3177 }
3018 3178
3019 3179 if (GETMEMB(os, "objset", os_sa, os_sa)) {
3020 3180 mdb_printf("Can't find os_sa in objset\n");
3021 3181 return (DCMD_ERR);
3022 3182 }
3023 3183
3024 3184 if (GETMEMB(os_sa, "sa_os", sa_num_attrs, attr_count)) {
3025 3185 mdb_printf("Can't find sa_num_attrs\n");
3026 3186 return (DCMD_ERR);
3027 3187 }
3028 3188
3029 3189 if (attr_id > attr_count) {
3030 3190 mdb_printf("attribute id number is out of range\n");
3031 3191 return (DCMD_ERR);
3032 3192 }
3033 3193
3034 3194 if (bonus_tab) {
3035 3195 if (sa_get_off_table(bonus_tab, &offset_tab,
3036 3196 attr_count) == -1) {
3037 3197 return (DCMD_ERR);
3038 3198 }
3039 3199
3040 3200 if (GETMEMB(db_bonus, "dmu_buf", db_data, db_data)) {
3041 3201 mdb_printf("can't find db_data in bonus dbuf\n");
3042 3202 return (DCMD_ERR);
3043 3203 }
3044 3204 }
3045 3205
3046 3206 if (bonus_tab && !TOC_ATTR_PRESENT(offset_tab[attr_id]) &&
3047 3207 spill_tab == NULL) {
3048 3208 mdb_printf("Attribute does not exist\n");
3049 3209 return (DCMD_ERR);
3050 3210 } else if (!TOC_ATTR_PRESENT(offset_tab[attr_id]) && spill_tab) {
3051 3211 if (sa_get_off_table(spill_tab, &offset_tab,
3052 3212 attr_count) == -1) {
3053 3213 return (DCMD_ERR);
3054 3214 }
3055 3215 if (GETMEMB(db_spill, "dmu_buf", db_data, db_data)) {
3056 3216 mdb_printf("can't find db_data in spill dbuf\n");
3057 3217 return (DCMD_ERR);
3058 3218 }
3059 3219 if (!TOC_ATTR_PRESENT(offset_tab[attr_id])) {
3060 3220 mdb_printf("Attribute does not exist\n");
3061 3221 return (DCMD_ERR);
3062 3222 }
3063 3223 }
3064 3224 attr_addr = db_data + TOC_OFF(offset_tab[attr_id]);
3065 3225 mdb_printf("%p\n", attr_addr);
3066 3226 return (DCMD_OK);
3067 3227 }
3068 3228
3069 3229 /* ARGSUSED */
3070 3230 static int
3071 3231 zfs_ace_print_common(uintptr_t addr, uint_t flags,
3072 3232 uint64_t id, uint32_t access_mask, uint16_t ace_flags,
3073 3233 uint16_t ace_type, int verbose)
3074 3234 {
3075 3235 if (DCMD_HDRSPEC(flags) && !verbose)
3076 3236 mdb_printf("%<u>%-?s %-8s %-8s %-8s %s%</u>\n",
3077 3237 "ADDR", "FLAGS", "MASK", "TYPE", "ID");
3078 3238
3079 3239 if (!verbose) {
3080 3240 mdb_printf("%0?p %-8x %-8x %-8x %-llx\n", addr,
3081 3241 ace_flags, access_mask, ace_type, id);
3082 3242 return (DCMD_OK);
3083 3243 }
3084 3244
3085 3245 switch (ace_flags & ACE_TYPE_FLAGS) {
3086 3246 case ACE_OWNER:
3087 3247 mdb_printf("owner@:");
3088 3248 break;
3089 3249 case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
3090 3250 mdb_printf("group@:");
3091 3251 break;
3092 3252 case ACE_EVERYONE:
3093 3253 mdb_printf("everyone@:");
3094 3254 break;
3095 3255 case ACE_IDENTIFIER_GROUP:
3096 3256 mdb_printf("group:%llx:", (u_longlong_t)id);
3097 3257 break;
3098 3258 case 0: /* User entry */
3099 3259 mdb_printf("user:%llx:", (u_longlong_t)id);
3100 3260 break;
3101 3261 }
3102 3262
3103 3263 /* print out permission mask */
3104 3264 if (access_mask & ACE_READ_DATA)
3105 3265 mdb_printf("r");
3106 3266 else
3107 3267 mdb_printf("-");
3108 3268 if (access_mask & ACE_WRITE_DATA)
3109 3269 mdb_printf("w");
3110 3270 else
3111 3271 mdb_printf("-");
3112 3272 if (access_mask & ACE_EXECUTE)
3113 3273 mdb_printf("x");
3114 3274 else
3115 3275 mdb_printf("-");
3116 3276 if (access_mask & ACE_APPEND_DATA)
3117 3277 mdb_printf("p");
3118 3278 else
3119 3279 mdb_printf("-");
3120 3280 if (access_mask & ACE_DELETE)
3121 3281 mdb_printf("d");
3122 3282 else
3123 3283 mdb_printf("-");
3124 3284 if (access_mask & ACE_DELETE_CHILD)
3125 3285 mdb_printf("D");
3126 3286 else
3127 3287 mdb_printf("-");
3128 3288 if (access_mask & ACE_READ_ATTRIBUTES)
3129 3289 mdb_printf("a");
3130 3290 else
3131 3291 mdb_printf("-");
3132 3292 if (access_mask & ACE_WRITE_ATTRIBUTES)
3133 3293 mdb_printf("A");
3134 3294 else
3135 3295 mdb_printf("-");
3136 3296 if (access_mask & ACE_READ_NAMED_ATTRS)
3137 3297 mdb_printf("R");
3138 3298 else
3139 3299 mdb_printf("-");
3140 3300 if (access_mask & ACE_WRITE_NAMED_ATTRS)
3141 3301 mdb_printf("W");
3142 3302 else
3143 3303 mdb_printf("-");
3144 3304 if (access_mask & ACE_READ_ACL)
3145 3305 mdb_printf("c");
3146 3306 else
3147 3307 mdb_printf("-");
3148 3308 if (access_mask & ACE_WRITE_ACL)
3149 3309 mdb_printf("C");
3150 3310 else
3151 3311 mdb_printf("-");
3152 3312 if (access_mask & ACE_WRITE_OWNER)
3153 3313 mdb_printf("o");
3154 3314 else
3155 3315 mdb_printf("-");
3156 3316 if (access_mask & ACE_SYNCHRONIZE)
3157 3317 mdb_printf("s");
3158 3318 else
3159 3319 mdb_printf("-");
3160 3320
3161 3321 mdb_printf(":");
3162 3322
3163 3323 /* Print out inheritance flags */
3164 3324 if (ace_flags & ACE_FILE_INHERIT_ACE)
3165 3325 mdb_printf("f");
3166 3326 else
3167 3327 mdb_printf("-");
3168 3328 if (ace_flags & ACE_DIRECTORY_INHERIT_ACE)
3169 3329 mdb_printf("d");
3170 3330 else
3171 3331 mdb_printf("-");
3172 3332 if (ace_flags & ACE_INHERIT_ONLY_ACE)
3173 3333 mdb_printf("i");
3174 3334 else
3175 3335 mdb_printf("-");
3176 3336 if (ace_flags & ACE_NO_PROPAGATE_INHERIT_ACE)
3177 3337 mdb_printf("n");
3178 3338 else
3179 3339 mdb_printf("-");
3180 3340 if (ace_flags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)
3181 3341 mdb_printf("S");
3182 3342 else
3183 3343 mdb_printf("-");
3184 3344 if (ace_flags & ACE_FAILED_ACCESS_ACE_FLAG)
3185 3345 mdb_printf("F");
3186 3346 else
3187 3347 mdb_printf("-");
3188 3348 if (ace_flags & ACE_INHERITED_ACE)
3189 3349 mdb_printf("I");
3190 3350 else
3191 3351 mdb_printf("-");
3192 3352
3193 3353 switch (ace_type) {
3194 3354 case ACE_ACCESS_ALLOWED_ACE_TYPE:
3195 3355 mdb_printf(":allow\n");
3196 3356 break;
3197 3357 case ACE_ACCESS_DENIED_ACE_TYPE:
3198 3358 mdb_printf(":deny\n");
3199 3359 break;
3200 3360 case ACE_SYSTEM_AUDIT_ACE_TYPE:
3201 3361 mdb_printf(":audit\n");
3202 3362 break;
3203 3363 case ACE_SYSTEM_ALARM_ACE_TYPE:
3204 3364 mdb_printf(":alarm\n");
3205 3365 break;
3206 3366 default:
3207 3367 mdb_printf(":?\n");
3208 3368 }
3209 3369 return (DCMD_OK);
3210 3370 }
3211 3371
3212 3372 /* ARGSUSED */
3213 3373 static int
3214 3374 zfs_ace_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3215 3375 {
3216 3376 zfs_ace_t zace;
3217 3377 int verbose = FALSE;
3218 3378 uint64_t id;
3219 3379
3220 3380 if (!(flags & DCMD_ADDRSPEC))
3221 3381 return (DCMD_USAGE);
3222 3382
3223 3383 if (mdb_getopts(argc, argv,
3224 3384 'v', MDB_OPT_SETBITS, TRUE, &verbose, TRUE, NULL) != argc)
3225 3385 return (DCMD_USAGE);
3226 3386
3227 3387 if (mdb_vread(&zace, sizeof (zfs_ace_t), addr) == -1) {
3228 3388 mdb_warn("failed to read zfs_ace_t");
3229 3389 return (DCMD_ERR);
3230 3390 }
3231 3391
3232 3392 if ((zace.z_hdr.z_flags & ACE_TYPE_FLAGS) == 0 ||
3233 3393 (zace.z_hdr.z_flags & ACE_TYPE_FLAGS) == ACE_IDENTIFIER_GROUP)
3234 3394 id = zace.z_fuid;
3235 3395 else
3236 3396 id = -1;
3237 3397
3238 3398 return (zfs_ace_print_common(addr, flags, id, zace.z_hdr.z_access_mask,
3239 3399 zace.z_hdr.z_flags, zace.z_hdr.z_type, verbose));
3240 3400 }
3241 3401
3242 3402 /* ARGSUSED */
3243 3403 static int
3244 3404 zfs_ace0_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3245 3405 {
3246 3406 ace_t ace;
3247 3407 uint64_t id;
3248 3408 int verbose = FALSE;
3249 3409
3250 3410 if (!(flags & DCMD_ADDRSPEC))
3251 3411 return (DCMD_USAGE);
3252 3412
3253 3413 if (mdb_getopts(argc, argv,
3254 3414 'v', MDB_OPT_SETBITS, TRUE, &verbose, TRUE, NULL) != argc)
3255 3415 return (DCMD_USAGE);
3256 3416
3257 3417 if (mdb_vread(&ace, sizeof (ace_t), addr) == -1) {
3258 3418 mdb_warn("failed to read ace_t");
3259 3419 return (DCMD_ERR);
3260 3420 }
3261 3421
3262 3422 if ((ace.a_flags & ACE_TYPE_FLAGS) == 0 ||
3263 3423 (ace.a_flags & ACE_TYPE_FLAGS) == ACE_IDENTIFIER_GROUP)
3264 3424 id = ace.a_who;
3265 3425 else
3266 3426 id = -1;
3267 3427
3268 3428 return (zfs_ace_print_common(addr, flags, id, ace.a_access_mask,
3269 3429 ace.a_flags, ace.a_type, verbose));
3270 3430 }
3271 3431
3272 3432 typedef struct acl_dump_args {
3273 3433 int a_argc;
3274 3434 const mdb_arg_t *a_argv;
3275 3435 uint16_t a_version;
3276 3436 int a_flags;
3277 3437 } acl_dump_args_t;
3278 3438
3279 3439 /* ARGSUSED */
3280 3440 static int
3281 3441 acl_aces_cb(uintptr_t addr, const void *unknown, void *arg)
3282 3442 {
3283 3443 acl_dump_args_t *acl_args = (acl_dump_args_t *)arg;
3284 3444
3285 3445 if (acl_args->a_version == 1) {
3286 3446 if (mdb_call_dcmd("zfs_ace", addr,
3287 3447 DCMD_ADDRSPEC|acl_args->a_flags, acl_args->a_argc,
3288 3448 acl_args->a_argv) != DCMD_OK) {
3289 3449 return (WALK_ERR);
3290 3450 }
3291 3451 } else {
3292 3452 if (mdb_call_dcmd("zfs_ace0", addr,
3293 3453 DCMD_ADDRSPEC|acl_args->a_flags, acl_args->a_argc,
3294 3454 acl_args->a_argv) != DCMD_OK) {
3295 3455 return (WALK_ERR);
3296 3456 }
3297 3457 }
3298 3458 acl_args->a_flags = DCMD_LOOP;
3299 3459 return (WALK_NEXT);
3300 3460 }
3301 3461
3302 3462 /* ARGSUSED */
3303 3463 static int
3304 3464 acl_cb(uintptr_t addr, const void *unknown, void *arg)
3305 3465 {
3306 3466 acl_dump_args_t *acl_args = (acl_dump_args_t *)arg;
3307 3467
3308 3468 if (acl_args->a_version == 1) {
3309 3469 if (mdb_pwalk("zfs_acl_node_aces", acl_aces_cb,
3310 3470 arg, addr) != 0) {
3311 3471 mdb_warn("can't walk ACEs");
3312 3472 return (DCMD_ERR);
3313 3473 }
3314 3474 } else {
3315 3475 if (mdb_pwalk("zfs_acl_node_aces0", acl_aces_cb,
3316 3476 arg, addr) != 0) {
3317 3477 mdb_warn("can't walk ACEs");
3318 3478 return (DCMD_ERR);
3319 3479 }
3320 3480 }
3321 3481 return (WALK_NEXT);
3322 3482 }
3323 3483
3324 3484 /* ARGSUSED */
3325 3485 static int
3326 3486 zfs_acl_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3327 3487 {
3328 3488 zfs_acl_t zacl;
3329 3489 int verbose = FALSE;
3330 3490 acl_dump_args_t acl_args;
3331 3491
3332 3492 if (!(flags & DCMD_ADDRSPEC))
3333 3493 return (DCMD_USAGE);
3334 3494
3335 3495 if (mdb_getopts(argc, argv,
3336 3496 'v', MDB_OPT_SETBITS, TRUE, &verbose, TRUE, NULL) != argc)
3337 3497 return (DCMD_USAGE);
3338 3498
3339 3499 if (mdb_vread(&zacl, sizeof (zfs_acl_t), addr) == -1) {
3340 3500 mdb_warn("failed to read zfs_acl_t");
3341 3501 return (DCMD_ERR);
3342 3502 }
3343 3503
3344 3504 acl_args.a_argc = argc;
3345 3505 acl_args.a_argv = argv;
3346 3506 acl_args.a_version = zacl.z_version;
3347 3507 acl_args.a_flags = DCMD_LOOPFIRST;
3348 3508
3349 3509 if (mdb_pwalk("zfs_acl_node", acl_cb, &acl_args, addr) != 0) {
3350 3510 mdb_warn("can't walk ACL");
3351 3511 return (DCMD_ERR);
3352 3512 }
3353 3513
3354 3514 return (DCMD_OK);
3355 3515 }
3356 3516
3357 3517 /* ARGSUSED */
3358 3518 static int
3359 3519 zfs_acl_node_walk_init(mdb_walk_state_t *wsp)
3360 3520 {
3361 3521 if (wsp->walk_addr == NULL) {
3362 3522 mdb_warn("must supply address of zfs_acl_node_t\n");
3363 3523 return (WALK_ERR);
3364 3524 }
3365 3525
3366 3526 wsp->walk_addr +=
3367 3527 mdb_ctf_offsetof_by_name(ZFS_STRUCT "zfs_acl", "z_acl");
3368 3528
3369 3529 if (mdb_layered_walk("list", wsp) == -1) {
3370 3530 mdb_warn("failed to walk 'list'\n");
3371 3531 return (WALK_ERR);
3372 3532 }
3373 3533
3374 3534 return (WALK_NEXT);
3375 3535 }
3376 3536
3377 3537 static int
3378 3538 zfs_acl_node_walk_step(mdb_walk_state_t *wsp)
3379 3539 {
3380 3540 zfs_acl_node_t aclnode;
3381 3541
3382 3542 if (mdb_vread(&aclnode, sizeof (zfs_acl_node_t),
3383 3543 wsp->walk_addr) == -1) {
3384 3544 mdb_warn("failed to read zfs_acl_node at %p", wsp->walk_addr);
3385 3545 return (WALK_ERR);
3386 3546 }
3387 3547
3388 3548 return (wsp->walk_callback(wsp->walk_addr, &aclnode, wsp->walk_cbdata));
3389 3549 }
3390 3550
3391 3551 typedef struct ace_walk_data {
3392 3552 int ace_count;
3393 3553 int ace_version;
3394 3554 } ace_walk_data_t;
3395 3555
3396 3556 static int
3397 3557 zfs_aces_walk_init_common(mdb_walk_state_t *wsp, int version,
3398 3558 int ace_count, uintptr_t ace_data)
3399 3559 {
3400 3560 ace_walk_data_t *ace_walk_data;
3401 3561
3402 3562 if (wsp->walk_addr == NULL) {
3403 3563 mdb_warn("must supply address of zfs_acl_node_t\n");
3404 3564 return (WALK_ERR);
3405 3565 }
3406 3566
3407 3567 ace_walk_data = mdb_alloc(sizeof (ace_walk_data_t), UM_SLEEP | UM_GC);
3408 3568
3409 3569 ace_walk_data->ace_count = ace_count;
3410 3570 ace_walk_data->ace_version = version;
3411 3571
3412 3572 wsp->walk_addr = ace_data;
3413 3573 wsp->walk_data = ace_walk_data;
3414 3574
3415 3575 return (WALK_NEXT);
3416 3576 }
3417 3577
3418 3578 static int
3419 3579 zfs_acl_node_aces_walk_init_common(mdb_walk_state_t *wsp, int version)
3420 3580 {
3421 3581 static int gotid;
3422 3582 static mdb_ctf_id_t acl_id;
3423 3583 int z_ace_count;
3424 3584 uintptr_t z_acldata;
3425 3585
3426 3586 if (!gotid) {
3427 3587 if (mdb_ctf_lookup_by_name("struct zfs_acl_node",
3428 3588 &acl_id) == -1) {
3429 3589 mdb_warn("couldn't find struct zfs_acl_node");
3430 3590 return (DCMD_ERR);
3431 3591 }
3432 3592 gotid = TRUE;
3433 3593 }
3434 3594
3435 3595 if (GETMEMBID(wsp->walk_addr, &acl_id, z_ace_count, z_ace_count)) {
3436 3596 return (DCMD_ERR);
3437 3597 }
3438 3598 if (GETMEMBID(wsp->walk_addr, &acl_id, z_acldata, z_acldata)) {
3439 3599 return (DCMD_ERR);
3440 3600 }
3441 3601
3442 3602 return (zfs_aces_walk_init_common(wsp, version,
3443 3603 z_ace_count, z_acldata));
3444 3604 }
3445 3605
3446 3606 /* ARGSUSED */
3447 3607 static int
3448 3608 zfs_acl_node_aces_walk_init(mdb_walk_state_t *wsp)
3449 3609 {
3450 3610 return (zfs_acl_node_aces_walk_init_common(wsp, 1));
3451 3611 }
3452 3612
3453 3613 /* ARGSUSED */
3454 3614 static int
3455 3615 zfs_acl_node_aces0_walk_init(mdb_walk_state_t *wsp)
3456 3616 {
3457 3617 return (zfs_acl_node_aces_walk_init_common(wsp, 0));
3458 3618 }
3459 3619
3460 3620 static int
3461 3621 zfs_aces_walk_step(mdb_walk_state_t *wsp)
3462 3622 {
3463 3623 ace_walk_data_t *ace_data = wsp->walk_data;
3464 3624 zfs_ace_t zace;
3465 3625 ace_t *acep;
3466 3626 int status;
3467 3627 int entry_type;
3468 3628 int allow_type;
3469 3629 uintptr_t ptr;
3470 3630
3471 3631 if (ace_data->ace_count == 0)
3472 3632 return (WALK_DONE);
3473 3633
3474 3634 if (mdb_vread(&zace, sizeof (zfs_ace_t), wsp->walk_addr) == -1) {
3475 3635 mdb_warn("failed to read zfs_ace_t at %#lx",
3476 3636 wsp->walk_addr);
3477 3637 return (WALK_ERR);
3478 3638 }
3479 3639
3480 3640 switch (ace_data->ace_version) {
3481 3641 case 0:
3482 3642 acep = (ace_t *)&zace;
3483 3643 entry_type = acep->a_flags & ACE_TYPE_FLAGS;
3484 3644 allow_type = acep->a_type;
3485 3645 break;
3486 3646 case 1:
3487 3647 entry_type = zace.z_hdr.z_flags & ACE_TYPE_FLAGS;
3488 3648 allow_type = zace.z_hdr.z_type;
3489 3649 break;
3490 3650 default:
3491 3651 return (WALK_ERR);
3492 3652 }
3493 3653
3494 3654 ptr = (uintptr_t)wsp->walk_addr;
3495 3655 switch (entry_type) {
3496 3656 case ACE_OWNER:
3497 3657 case ACE_EVERYONE:
3498 3658 case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
3499 3659 ptr += ace_data->ace_version == 0 ?
3500 3660 sizeof (ace_t) : sizeof (zfs_ace_hdr_t);
3501 3661 break;
3502 3662 case ACE_IDENTIFIER_GROUP:
3503 3663 default:
3504 3664 switch (allow_type) {
3505 3665 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3506 3666 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3507 3667 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3508 3668 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3509 3669 ptr += ace_data->ace_version == 0 ?
3510 3670 sizeof (ace_t) : sizeof (zfs_object_ace_t);
3511 3671 break;
3512 3672 default:
3513 3673 ptr += ace_data->ace_version == 0 ?
3514 3674 sizeof (ace_t) : sizeof (zfs_ace_t);
3515 3675 break;
3516 3676 }
3517 3677 }
3518 3678
3519 3679 ace_data->ace_count--;
3520 3680 status = wsp->walk_callback(wsp->walk_addr,
3521 3681 (void *)(uintptr_t)&zace, wsp->walk_cbdata);
3522 3682
3523 3683 wsp->walk_addr = ptr;
3524 3684 return (status);
3525 3685 }
3526 3686
3527 3687 typedef struct mdb_zfs_rrwlock {
3528 3688 uintptr_t rr_writer;
3529 3689 boolean_t rr_writer_wanted;
3530 3690 } mdb_zfs_rrwlock_t;
3531 3691
3532 3692 static uint_t rrw_key;
3533 3693
3534 3694 /* ARGSUSED */
3535 3695 static int
3536 3696 rrwlock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3537 3697 {
3538 3698 mdb_zfs_rrwlock_t rrw;
3539 3699
3540 3700 if (rrw_key == 0) {
3541 3701 if (mdb_ctf_readsym(&rrw_key, "uint_t", "rrw_tsd_key", 0) == -1)
3542 3702 return (DCMD_ERR);
3543 3703 }
3544 3704
3545 3705 if (mdb_ctf_vread(&rrw, "rrwlock_t", "mdb_zfs_rrwlock_t", addr,
3546 3706 0) == -1)
3547 3707 return (DCMD_ERR);
3548 3708
3549 3709 if (rrw.rr_writer != 0) {
3550 3710 mdb_printf("write lock held by thread %lx\n", rrw.rr_writer);
3551 3711 return (DCMD_OK);
3552 3712 }
3553 3713
3554 3714 if (rrw.rr_writer_wanted) {
3555 3715 mdb_printf("writer wanted\n");
3556 3716 }
3557 3717
3558 3718 mdb_printf("anonymous references:\n");
3559 3719 (void) mdb_call_dcmd("refcount", addr +
3560 3720 mdb_ctf_offsetof_by_name(ZFS_STRUCT "rrwlock", "rr_anon_rcount"),
3561 3721 DCMD_ADDRSPEC, 0, NULL);
3562 3722
3563 3723 mdb_printf("linked references:\n");
3564 3724 (void) mdb_call_dcmd("refcount", addr +
3565 3725 mdb_ctf_offsetof_by_name(ZFS_STRUCT "rrwlock", "rr_linked_rcount"),
3566 3726 DCMD_ADDRSPEC, 0, NULL);
3567 3727
3568 3728 /*
3569 3729 * XXX This should find references from
3570 3730 * "::walk thread | ::tsd -v <rrw_key>", but there is no support
3571 3731 * for programmatic consumption of dcmds, so this would be
3572 3732 * difficult, potentially requiring reimplementing ::tsd (both
3573 3733 * user and kernel versions) in this MDB module.
3574 3734 */
3575 3735
3576 3736 return (DCMD_OK);
3577 3737 }
3578 3738
3579 3739 typedef struct mdb_arc_buf_hdr_t {
3580 3740 uint16_t b_psize;
3581 3741 uint16_t b_lsize;
3582 3742 struct {
3583 3743 uint32_t b_bufcnt;
3584 3744 uintptr_t b_state;
3585 3745 } b_l1hdr;
3586 3746 } mdb_arc_buf_hdr_t;
3587 3747
3588 3748 enum arc_cflags {
3589 3749 ARC_CFLAG_VERBOSE = 1 << 0,
3590 3750 ARC_CFLAG_ANON = 1 << 1,
3591 3751 ARC_CFLAG_MRU = 1 << 2,
3592 3752 ARC_CFLAG_MFU = 1 << 3,
3593 3753 ARC_CFLAG_BUFS = 1 << 4,
3594 3754 };
3595 3755
3596 3756 typedef struct arc_compression_stats_data {
3597 3757 GElf_Sym anon_sym; /* ARC_anon symbol */
3598 3758 GElf_Sym mru_sym; /* ARC_mru symbol */
3599 3759 GElf_Sym mrug_sym; /* ARC_mru_ghost symbol */
3600 3760 GElf_Sym mfu_sym; /* ARC_mfu symbol */
3601 3761 GElf_Sym mfug_sym; /* ARC_mfu_ghost symbol */
3602 3762 GElf_Sym l2c_sym; /* ARC_l2c_only symbol */
3603 3763 uint64_t *anon_c_hist; /* histogram of compressed sizes in anon */
3604 3764 uint64_t *anon_u_hist; /* histogram of uncompressed sizes in anon */
3605 3765 uint64_t *anon_bufs; /* histogram of buffer counts in anon state */
3606 3766 uint64_t *mru_c_hist; /* histogram of compressed sizes in mru */
3607 3767 uint64_t *mru_u_hist; /* histogram of uncompressed sizes in mru */
3608 3768 uint64_t *mru_bufs; /* histogram of buffer counts in mru */
3609 3769 uint64_t *mfu_c_hist; /* histogram of compressed sizes in mfu */
3610 3770 uint64_t *mfu_u_hist; /* histogram of uncompressed sizes in mfu */
3611 3771 uint64_t *mfu_bufs; /* histogram of buffer counts in mfu */
3612 3772 uint64_t *all_c_hist; /* histogram of compressed anon + mru + mfu */
3613 3773 uint64_t *all_u_hist; /* histogram of uncompressed anon + mru + mfu */
3614 3774 uint64_t *all_bufs; /* histogram of buffer counts in all states */
3615 3775 int arc_cflags; /* arc compression flags, specified by user */
3616 3776 int hist_nbuckets; /* number of buckets in each histogram */
3617 3777 } arc_compression_stats_data_t;
3618 3778
3619 3779 int
3620 3780 highbit64(uint64_t i)
3621 3781 {
3622 3782 int h = 1;
3623 3783
3624 3784 if (i == 0)
3625 3785 return (0);
3626 3786 if (i & 0xffffffff00000000ULL) {
3627 3787 h += 32; i >>= 32;
3628 3788 }
3629 3789 if (i & 0xffff0000) {
3630 3790 h += 16; i >>= 16;
3631 3791 }
3632 3792 if (i & 0xff00) {
3633 3793 h += 8; i >>= 8;
3634 3794 }
3635 3795 if (i & 0xf0) {
3636 3796 h += 4; i >>= 4;
3637 3797 }
3638 3798 if (i & 0xc) {
3639 3799 h += 2; i >>= 2;
3640 3800 }
3641 3801 if (i & 0x2) {
3642 3802 h += 1;
3643 3803 }
3644 3804 return (h);
3645 3805 }
3646 3806
3647 3807 /* ARGSUSED */
3648 3808 static int
3649 3809 arc_compression_stats_cb(uintptr_t addr, const void *unknown, void *arg)
3650 3810 {
3651 3811 arc_compression_stats_data_t *data = arg;
3652 3812 mdb_arc_buf_hdr_t hdr;
3653 3813 int cbucket, ubucket, bufcnt;
3654 3814
3655 3815 if (mdb_ctf_vread(&hdr, "arc_buf_hdr_t", "mdb_arc_buf_hdr_t",
3656 3816 addr, 0) == -1) {
3657 3817 return (WALK_ERR);
3658 3818 }
3659 3819
3660 3820 /*
3661 3821 * Headers in the ghost states, or the l2c_only state don't have
3662 3822 * arc buffers linked off of them. Thus, their compressed size
3663 3823 * is meaningless, so we skip these from the stats.
3664 3824 */
3665 3825 if (hdr.b_l1hdr.b_state == data->mrug_sym.st_value ||
3666 3826 hdr.b_l1hdr.b_state == data->mfug_sym.st_value ||
3667 3827 hdr.b_l1hdr.b_state == data->l2c_sym.st_value) {
3668 3828 return (WALK_NEXT);
3669 3829 }
3670 3830
3671 3831 /*
3672 3832 * The physical size (compressed) and logical size
3673 3833 * (uncompressed) are in units of SPA_MINBLOCKSIZE. By default,
3674 3834 * we use the log2 of this value (rounded down to the nearest
3675 3835 * integer) to determine the bucket to assign this header to.
3676 3836 * Thus, the histogram is logarithmic with respect to the size
3677 3837 * of the header. For example, the following is a mapping of the
3678 3838 * bucket numbers and the range of header sizes they correspond to:
3679 3839 *
3680 3840 * 0: 0 byte headers
3681 3841 * 1: 512 byte headers
3682 3842 * 2: [1024 - 2048) byte headers
3683 3843 * 3: [2048 - 4096) byte headers
3684 3844 * 4: [4096 - 8192) byte headers
3685 3845 * 5: [8192 - 16394) byte headers
3686 3846 * 6: [16384 - 32768) byte headers
3687 3847 * 7: [32768 - 65536) byte headers
3688 3848 * 8: [65536 - 131072) byte headers
3689 3849 * 9: 131072 byte headers
3690 3850 *
3691 3851 * If the ARC_CFLAG_VERBOSE flag was specified, we use the
3692 3852 * physical and logical sizes directly. Thus, the histogram will
3693 3853 * no longer be logarithmic; instead it will be linear with
3694 3854 * respect to the size of the header. The following is a mapping
3695 3855 * of the first many bucket numbers and the header size they
3696 3856 * correspond to:
3697 3857 *
3698 3858 * 0: 0 byte headers
3699 3859 * 1: 512 byte headers
3700 3860 * 2: 1024 byte headers
3701 3861 * 3: 1536 byte headers
3702 3862 * 4: 2048 byte headers
3703 3863 * 5: 2560 byte headers
3704 3864 * 6: 3072 byte headers
3705 3865 *
3706 3866 * And so on. Keep in mind that a range of sizes isn't used in
3707 3867 * the case of linear scale because the headers can only
3708 3868 * increment or decrement in sizes of 512 bytes. So, it's not
3709 3869 * possible for a header to be sized in between whats listed
3710 3870 * above.
3711 3871 *
3712 3872 * Also, the above mapping values were calculated assuming a
3713 3873 * SPA_MINBLOCKSHIFT of 512 bytes and a SPA_MAXBLOCKSIZE of 128K.
3714 3874 */
3715 3875
3716 3876 if (data->arc_cflags & ARC_CFLAG_VERBOSE) {
3717 3877 cbucket = hdr.b_psize;
3718 3878 ubucket = hdr.b_lsize;
3719 3879 } else {
3720 3880 cbucket = highbit64(hdr.b_psize);
3721 3881 ubucket = highbit64(hdr.b_lsize);
3722 3882 }
3723 3883
3724 3884 bufcnt = hdr.b_l1hdr.b_bufcnt;
3725 3885 if (bufcnt >= data->hist_nbuckets)
3726 3886 bufcnt = data->hist_nbuckets - 1;
3727 3887
3728 3888 /* Ensure we stay within the bounds of the histogram array */
3729 3889 ASSERT3U(cbucket, <, data->hist_nbuckets);
3730 3890 ASSERT3U(ubucket, <, data->hist_nbuckets);
3731 3891
3732 3892 if (hdr.b_l1hdr.b_state == data->anon_sym.st_value) {
3733 3893 data->anon_c_hist[cbucket]++;
3734 3894 data->anon_u_hist[ubucket]++;
3735 3895 data->anon_bufs[bufcnt]++;
3736 3896 } else if (hdr.b_l1hdr.b_state == data->mru_sym.st_value) {
3737 3897 data->mru_c_hist[cbucket]++;
3738 3898 data->mru_u_hist[ubucket]++;
3739 3899 data->mru_bufs[bufcnt]++;
3740 3900 } else if (hdr.b_l1hdr.b_state == data->mfu_sym.st_value) {
3741 3901 data->mfu_c_hist[cbucket]++;
3742 3902 data->mfu_u_hist[ubucket]++;
3743 3903 data->mfu_bufs[bufcnt]++;
3744 3904 }
3745 3905
3746 3906 data->all_c_hist[cbucket]++;
3747 3907 data->all_u_hist[ubucket]++;
3748 3908 data->all_bufs[bufcnt]++;
3749 3909
3750 3910 return (WALK_NEXT);
3751 3911 }
3752 3912
3753 3913 /* ARGSUSED */
3754 3914 static int
3755 3915 arc_compression_stats(uintptr_t addr, uint_t flags, int argc,
3756 3916 const mdb_arg_t *argv)
3757 3917 {
3758 3918 arc_compression_stats_data_t data = { 0 };
3759 3919 unsigned int max_shifted = SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT;
3760 3920 unsigned int hist_size;
3761 3921 char range[32];
3762 3922 int rc = DCMD_OK;
3763 3923
3764 3924 if (mdb_getopts(argc, argv,
3765 3925 'v', MDB_OPT_SETBITS, ARC_CFLAG_VERBOSE, &data.arc_cflags,
3766 3926 'a', MDB_OPT_SETBITS, ARC_CFLAG_ANON, &data.arc_cflags,
3767 3927 'b', MDB_OPT_SETBITS, ARC_CFLAG_BUFS, &data.arc_cflags,
3768 3928 'r', MDB_OPT_SETBITS, ARC_CFLAG_MRU, &data.arc_cflags,
3769 3929 'f', MDB_OPT_SETBITS, ARC_CFLAG_MFU, &data.arc_cflags) != argc)
3770 3930 return (DCMD_USAGE);
3771 3931
3772 3932 if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_anon", &data.anon_sym) ||
3773 3933 mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mru", &data.mru_sym) ||
3774 3934 mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mru_ghost", &data.mrug_sym) ||
3775 3935 mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mfu", &data.mfu_sym) ||
3776 3936 mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mfu_ghost", &data.mfug_sym) ||
3777 3937 mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_l2c_only", &data.l2c_sym)) {
3778 3938 mdb_warn("can't find arc state symbol");
3779 3939 return (DCMD_ERR);
3780 3940 }
3781 3941
3782 3942 /*
3783 3943 * Determine the maximum expected size for any header, and use
3784 3944 * this to determine the number of buckets needed for each
3785 3945 * histogram. If ARC_CFLAG_VERBOSE is specified, this value is
3786 3946 * used directly; otherwise the log2 of the maximum size is
3787 3947 * used. Thus, if using a log2 scale there's a maximum of 10
3788 3948 * possible buckets, while the linear scale (when using
3789 3949 * ARC_CFLAG_VERBOSE) has a maximum of 257 buckets.
3790 3950 */
3791 3951 if (data.arc_cflags & ARC_CFLAG_VERBOSE)
3792 3952 data.hist_nbuckets = max_shifted + 1;
3793 3953 else
3794 3954 data.hist_nbuckets = highbit64(max_shifted) + 1;
3795 3955
3796 3956 hist_size = sizeof (uint64_t) * data.hist_nbuckets;
3797 3957
3798 3958 data.anon_c_hist = mdb_zalloc(hist_size, UM_SLEEP);
3799 3959 data.anon_u_hist = mdb_zalloc(hist_size, UM_SLEEP);
3800 3960 data.anon_bufs = mdb_zalloc(hist_size, UM_SLEEP);
3801 3961
3802 3962 data.mru_c_hist = mdb_zalloc(hist_size, UM_SLEEP);
3803 3963 data.mru_u_hist = mdb_zalloc(hist_size, UM_SLEEP);
3804 3964 data.mru_bufs = mdb_zalloc(hist_size, UM_SLEEP);
3805 3965
3806 3966 data.mfu_c_hist = mdb_zalloc(hist_size, UM_SLEEP);
3807 3967 data.mfu_u_hist = mdb_zalloc(hist_size, UM_SLEEP);
3808 3968 data.mfu_bufs = mdb_zalloc(hist_size, UM_SLEEP);
3809 3969
3810 3970 data.all_c_hist = mdb_zalloc(hist_size, UM_SLEEP);
3811 3971 data.all_u_hist = mdb_zalloc(hist_size, UM_SLEEP);
3812 3972 data.all_bufs = mdb_zalloc(hist_size, UM_SLEEP);
3813 3973
3814 3974 if (mdb_walk("arc_buf_hdr_t_full", arc_compression_stats_cb,
3815 3975 &data) != 0) {
3816 3976 mdb_warn("can't walk arc_buf_hdr's");
3817 3977 rc = DCMD_ERR;
3818 3978 goto out;
3819 3979 }
3820 3980
3821 3981 if (data.arc_cflags & ARC_CFLAG_VERBOSE) {
3822 3982 rc = mdb_snprintf(range, sizeof (range),
3823 3983 "[n*%llu, (n+1)*%llu)", SPA_MINBLOCKSIZE,
3824 3984 SPA_MINBLOCKSIZE);
3825 3985 } else {
3826 3986 rc = mdb_snprintf(range, sizeof (range),
3827 3987 "[2^(n-1)*%llu, 2^n*%llu)", SPA_MINBLOCKSIZE,
3828 3988 SPA_MINBLOCKSIZE);
3829 3989 }
3830 3990
3831 3991 if (rc < 0) {
3832 3992 /* snprintf failed, abort the dcmd */
3833 3993 rc = DCMD_ERR;
3834 3994 goto out;
3835 3995 } else {
3836 3996 /* snprintf succeeded above, reset return code */
3837 3997 rc = DCMD_OK;
3838 3998 }
3839 3999
3840 4000 if (data.arc_cflags & ARC_CFLAG_ANON) {
3841 4001 if (data.arc_cflags & ARC_CFLAG_BUFS) {
3842 4002 mdb_printf("Histogram of the number of anon buffers "
3843 4003 "that are associated with an arc hdr.\n");
3844 4004 dump_histogram(data.anon_bufs, data.hist_nbuckets, 0);
3845 4005 mdb_printf("\n");
3846 4006 }
3847 4007 mdb_printf("Histogram of compressed anon buffers.\n"
3848 4008 "Each bucket represents buffers of size: %s.\n", range);
3849 4009 dump_histogram(data.anon_c_hist, data.hist_nbuckets, 0);
3850 4010 mdb_printf("\n");
3851 4011
3852 4012 mdb_printf("Histogram of uncompressed anon buffers.\n"
3853 4013 "Each bucket represents buffers of size: %s.\n", range);
3854 4014 dump_histogram(data.anon_u_hist, data.hist_nbuckets, 0);
3855 4015 mdb_printf("\n");
3856 4016 }
3857 4017
3858 4018 if (data.arc_cflags & ARC_CFLAG_MRU) {
3859 4019 if (data.arc_cflags & ARC_CFLAG_BUFS) {
3860 4020 mdb_printf("Histogram of the number of mru buffers "
3861 4021 "that are associated with an arc hdr.\n");
3862 4022 dump_histogram(data.mru_bufs, data.hist_nbuckets, 0);
3863 4023 mdb_printf("\n");
3864 4024 }
3865 4025 mdb_printf("Histogram of compressed mru buffers.\n"
3866 4026 "Each bucket represents buffers of size: %s.\n", range);
3867 4027 dump_histogram(data.mru_c_hist, data.hist_nbuckets, 0);
3868 4028 mdb_printf("\n");
3869 4029
3870 4030 mdb_printf("Histogram of uncompressed mru buffers.\n"
3871 4031 "Each bucket represents buffers of size: %s.\n", range);
3872 4032 dump_histogram(data.mru_u_hist, data.hist_nbuckets, 0);
3873 4033 mdb_printf("\n");
3874 4034 }
3875 4035
3876 4036 if (data.arc_cflags & ARC_CFLAG_MFU) {
3877 4037 if (data.arc_cflags & ARC_CFLAG_BUFS) {
3878 4038 mdb_printf("Histogram of the number of mfu buffers "
3879 4039 "that are associated with an arc hdr.\n");
3880 4040 dump_histogram(data.mfu_bufs, data.hist_nbuckets, 0);
3881 4041 mdb_printf("\n");
3882 4042 }
3883 4043
3884 4044 mdb_printf("Histogram of compressed mfu buffers.\n"
3885 4045 "Each bucket represents buffers of size: %s.\n", range);
3886 4046 dump_histogram(data.mfu_c_hist, data.hist_nbuckets, 0);
3887 4047 mdb_printf("\n");
3888 4048
3889 4049 mdb_printf("Histogram of uncompressed mfu buffers.\n"
3890 4050 "Each bucket represents buffers of size: %s.\n", range);
3891 4051 dump_histogram(data.mfu_u_hist, data.hist_nbuckets, 0);
3892 4052 mdb_printf("\n");
3893 4053 }
3894 4054
3895 4055 if (data.arc_cflags & ARC_CFLAG_BUFS) {
3896 4056 mdb_printf("Histogram of all buffers that "
3897 4057 "are associated with an arc hdr.\n");
3898 4058 dump_histogram(data.all_bufs, data.hist_nbuckets, 0);
3899 4059 mdb_printf("\n");
3900 4060 }
3901 4061
3902 4062 mdb_printf("Histogram of all compressed buffers.\n"
3903 4063 "Each bucket represents buffers of size: %s.\n", range);
3904 4064 dump_histogram(data.all_c_hist, data.hist_nbuckets, 0);
3905 4065 mdb_printf("\n");
3906 4066
3907 4067 mdb_printf("Histogram of all uncompressed buffers.\n"
3908 4068 "Each bucket represents buffers of size: %s.\n", range);
3909 4069 dump_histogram(data.all_u_hist, data.hist_nbuckets, 0);
3910 4070
3911 4071 out:
3912 4072 mdb_free(data.anon_c_hist, hist_size);
3913 4073 mdb_free(data.anon_u_hist, hist_size);
3914 4074 mdb_free(data.anon_bufs, hist_size);
3915 4075
3916 4076 mdb_free(data.mru_c_hist, hist_size);
3917 4077 mdb_free(data.mru_u_hist, hist_size);
3918 4078 mdb_free(data.mru_bufs, hist_size);
3919 4079
3920 4080 mdb_free(data.mfu_c_hist, hist_size);
3921 4081 mdb_free(data.mfu_u_hist, hist_size);
3922 4082 mdb_free(data.mfu_bufs, hist_size);
3923 4083
3924 4084 mdb_free(data.all_c_hist, hist_size);
3925 4085 mdb_free(data.all_u_hist, hist_size);
3926 4086 mdb_free(data.all_bufs, hist_size);
3927 4087
3928 4088 return (rc);
3929 4089 }
3930 4090
|
↓ open down ↓ |
1837 lines elided |
↑ open up ↑ |
3931 4091 /*
3932 4092 * MDB module linkage information:
3933 4093 *
3934 4094 * We declare a list of structures describing our dcmds, and a function
3935 4095 * named _mdb_init to return a pointer to our module information.
3936 4096 */
3937 4097
3938 4098 static const mdb_dcmd_t dcmds[] = {
3939 4099 { "arc", "[-bkmg]", "print ARC variables", arc_print },
3940 4100 { "blkptr", ":", "print blkptr_t", blkptr },
3941 - { "dva", ":", "print dva_t", dva },
3942 4101 { "dbuf", ":", "print dmu_buf_impl_t", dbuf },
3943 4102 { "dbuf_stats", ":", "dbuf stats", dbuf_stats },
3944 4103 { "dbufs",
3945 4104 "\t[-O objset_t*] [-n objset_name | \"mos\"] "
3946 4105 "[-o object | \"mdn\"] \n"
3947 4106 "\t[-l level] [-b blkid | \"bonus\"]",
3948 4107 "find dmu_buf_impl_t's that match specified criteria", dbufs },
3949 4108 { "abuf_find", "dva_word[0] dva_word[1]",
3950 4109 "find arc_buf_hdr_t of a specified DVA",
3951 4110 abuf_find },
3952 4111 { "spa", "?[-cevmMh]\n"
3953 4112 "\t-c display spa config\n"
3954 4113 "\t-e display vdev statistics\n"
3955 4114 "\t-v display vdev information\n"
3956 4115 "\t-m display metaslab statistics\n"
3957 4116 "\t-M display metaslab group statistics\n"
3958 4117 "\t-h display histogram (requires -m or -M)\n",
3959 4118 "spa_t summary", spa_print },
3960 4119 { "spa_config", ":", "print spa_t configuration", spa_print_config },
3961 4120 { "spa_space", ":[-b]", "print spa_t on-disk space usage", spa_space },
3962 4121 { "spa_vdevs", ":[-emMh]\n"
3963 4122 "\t-e display vdev statistics\n"
3964 4123 "\t-m dispaly metaslab statistics\n"
3965 4124 "\t-M display metaslab group statistic\n"
3966 4125 "\t-h display histogram (requires -m or -M)\n",
3967 4126 "given a spa_t, print vdev summary", spa_vdevs },
3968 4127 { "vdev", ":[-remMh]\n"
3969 4128 "\t-r display recursively\n"
3970 4129 "\t-e display statistics\n"
3971 4130 "\t-m display metaslab statistics (top level vdev only)\n"
3972 4131 "\t-M display metaslab group statistics (top level vdev only)\n"
3973 4132 "\t-h display histogram (requires -m or -M)\n",
3974 4133 "vdev_t summary", vdev_print },
3975 4134 { "zio", ":[-cpr]\n"
3976 4135 "\t-c display children\n"
3977 4136 "\t-p display parents\n"
3978 4137 "\t-r display recursively",
3979 4138 "zio_t summary", zio_print },
3980 4139 { "zio_state", "?", "print out all zio_t structures on system or "
3981 4140 "for a particular pool", zio_state },
3982 4141 { "zfs_blkstats", ":[-v]",
3983 4142 "given a spa_t, print block type stats from last scrub",
3984 4143 zfs_blkstats },
3985 4144 { "zfs_params", "", "print zfs tunable parameters", zfs_params },
3986 4145 { "refcount", ":[-r]\n"
3987 4146 "\t-r display recently removed references",
3988 4147 "print refcount_t holders", refcount },
3989 4148 { "zap_leaf", "", "print zap_leaf_phys_t", zap_leaf },
3990 4149 { "zfs_aces", ":[-v]", "print all ACEs from a zfs_acl_t",
3991 4150 zfs_acl_dump },
3992 4151 { "zfs_ace", ":[-v]", "print zfs_ace", zfs_ace_print },
3993 4152 { "zfs_ace0", ":[-v]", "print zfs_ace0", zfs_ace0_print },
3994 4153 { "sa_attr_table", ":", "print SA attribute table from sa_os_t",
3995 4154 sa_attr_table},
3996 4155 { "sa_attr", ": attr_id",
3997 4156 "print SA attribute address when given sa_handle_t", sa_attr_print},
3998 4157 { "zfs_dbgmsg", ":[-va]",
3999 4158 "print zfs debug log", dbgmsg},
4000 4159 { "rrwlock", ":",
4001 4160 "print rrwlock_t, including readers", rrwlock},
4002 4161 { "metaslab_weight", "weight",
4003 4162 "print metaslab weight", metaslab_weight},
4004 4163 { "metaslab_trace", ":",
4005 4164 "print metaslab allocation trace records", metaslab_trace},
4006 4165 { "arc_compression_stats", ":[-vabrf]\n"
4007 4166 "\t-v verbose, display a linearly scaled histogram\n"
4008 4167 "\t-a display ARC_anon state statistics individually\n"
4009 4168 "\t-r display ARC_mru state statistics individually\n"
4010 4169 "\t-f display ARC_mfu state statistics individually\n"
4011 4170 "\t-b display histogram of buffer counts\n",
4012 4171 "print a histogram of compressed arc buffer sizes",
4013 4172 arc_compression_stats},
4014 4173 { NULL }
4015 4174 };
4016 4175
4017 4176 static const mdb_walker_t walkers[] = {
4018 4177 { "zms_freelist", "walk ZFS metaslab freelist",
4019 4178 freelist_walk_init, freelist_walk_step, NULL },
4020 4179 { "txg_list", "given any txg_list_t *, walk all entries in all txgs",
4021 4180 txg_list_walk_init, txg_list_walk_step, NULL },
4022 4181 { "txg_list0", "given any txg_list_t *, walk all entries in txg 0",
4023 4182 txg_list0_walk_init, txg_list_walk_step, NULL },
4024 4183 { "txg_list1", "given any txg_list_t *, walk all entries in txg 1",
4025 4184 txg_list1_walk_init, txg_list_walk_step, NULL },
4026 4185 { "txg_list2", "given any txg_list_t *, walk all entries in txg 2",
4027 4186 txg_list2_walk_init, txg_list_walk_step, NULL },
4028 4187 { "txg_list3", "given any txg_list_t *, walk all entries in txg 3",
4029 4188 txg_list3_walk_init, txg_list_walk_step, NULL },
4030 4189 { "zio", "walk all zio structures, optionally for a particular spa_t",
4031 4190 zio_walk_init, zio_walk_step, NULL },
4032 4191 { "zio_root",
4033 4192 "walk all root zio_t structures, optionally for a particular spa_t",
4034 4193 zio_walk_init, zio_walk_root_step, NULL },
4035 4194 { "spa", "walk all spa_t entries in the namespace",
4036 4195 spa_walk_init, spa_walk_step, NULL },
4037 4196 { "metaslab", "given a spa_t *, walk all metaslab_t structures",
4038 4197 metaslab_walk_init, metaslab_walk_step, NULL },
4039 4198 { "multilist", "given a multilist_t *, walk all list_t structures",
4040 4199 multilist_walk_init, multilist_walk_step, NULL },
4041 4200 { "zfs_acl_node", "given a zfs_acl_t, walk all zfs_acl_nodes",
4042 4201 zfs_acl_node_walk_init, zfs_acl_node_walk_step, NULL },
4043 4202 { "zfs_acl_node_aces", "given a zfs_acl_node_t, walk all ACEs",
4044 4203 zfs_acl_node_aces_walk_init, zfs_aces_walk_step, NULL },
4045 4204 { "zfs_acl_node_aces0",
4046 4205 "given a zfs_acl_node_t, walk all ACEs as ace_t",
4047 4206 zfs_acl_node_aces0_walk_init, zfs_aces_walk_step, NULL },
4048 4207 { NULL }
4049 4208 };
4050 4209
4051 4210 static const mdb_modinfo_t modinfo = {
4052 4211 MDB_API_VERSION, dcmds, walkers
4053 4212 };
4054 4213
4055 4214 const mdb_modinfo_t *
4056 4215 _mdb_init(void)
4057 4216 {
4058 4217 return (&modinfo);
4059 4218 }
|
↓ open down ↓ |
108 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX