229 (u_longlong_t)shp->sh_bof);
230 (void) printf("\t\teof = %llu\n",
231 (u_longlong_t)shp->sh_eof);
232 (void) printf("\t\trecords_lost = %llu\n",
233 (u_longlong_t)shp->sh_records_lost);
234 }
235
236 static void
237 zdb_nicenum(uint64_t num, char *buf)
238 {
239 if (dump_opt['P'])
240 (void) sprintf(buf, "%llu", (longlong_t)num);
241 else
242 nicenum(num, buf);
243 }
244
245 const char histo_stars[] = "****************************************";
246 const int histo_width = sizeof (histo_stars) - 1;
247
248 static void
249 dump_histogram(const uint64_t *histo, int size)
250 {
251 int i;
252 int minidx = size - 1;
253 int maxidx = 0;
254 uint64_t max = 0;
255
256 for (i = 0; i < size; i++) {
257 if (histo[i] > max)
258 max = histo[i];
259 if (histo[i] > 0 && i > maxidx)
260 maxidx = i;
261 if (histo[i] > 0 && i < minidx)
262 minidx = i;
263 }
264
265 if (max < histo_width)
266 max = histo_width;
267
268 for (i = minidx; i <= maxidx; i++) {
269 (void) printf("\t\t\t%3u: %6llu %s\n",
270 i, (u_longlong_t)histo[i],
271 &histo_stars[(max - histo[i]) * histo_width / max]);
272 }
273 }
274
275 static void
276 dump_zap_stats(objset_t *os, uint64_t object)
277 {
278 int error;
279 zap_stats_t zs;
280
281 error = zap_get_stats(os, object, &zs);
282 if (error)
283 return;
284
285 if (zs.zs_ptrtbl_len == 0) {
286 ASSERT(zs.zs_num_blocks == 1);
287 (void) printf("\tmicrozap: %llu bytes, %llu entries\n",
288 (u_longlong_t)zs.zs_blocksize,
289 (u_longlong_t)zs.zs_num_entries);
290 return;
303 (u_longlong_t)zs.zs_ptrtbl_zt_shift);
304 (void) printf("\t\t\tzt_blks_copied: %llu\n",
305 (u_longlong_t)zs.zs_ptrtbl_blks_copied);
306 (void) printf("\t\t\tzt_nextblk: %llu\n",
307 (u_longlong_t)zs.zs_ptrtbl_nextblk);
308
309 (void) printf("\t\tZAP entries: %llu\n",
310 (u_longlong_t)zs.zs_num_entries);
311 (void) printf("\t\tLeaf blocks: %llu\n",
312 (u_longlong_t)zs.zs_num_leafs);
313 (void) printf("\t\tTotal blocks: %llu\n",
314 (u_longlong_t)zs.zs_num_blocks);
315 (void) printf("\t\tzap_block_type: 0x%llx\n",
316 (u_longlong_t)zs.zs_block_type);
317 (void) printf("\t\tzap_magic: 0x%llx\n",
318 (u_longlong_t)zs.zs_magic);
319 (void) printf("\t\tzap_salt: 0x%llx\n",
320 (u_longlong_t)zs.zs_salt);
321
322 (void) printf("\t\tLeafs with 2^n pointers:\n");
323 dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE);
324
325 (void) printf("\t\tBlocks with n*5 entries:\n");
326 dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE);
327
328 (void) printf("\t\tBlocks n/10 full:\n");
329 dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE);
330
331 (void) printf("\t\tEntries with n chunks:\n");
332 dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE);
333
334 (void) printf("\t\tBuckets with n entries:\n");
335 dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE);
336 }
337
338 /*ARGSUSED*/
339 static void
340 dump_none(objset_t *os, uint64_t object, void *data, size_t size)
341 {
342 }
343
344 /*ARGSUSED*/
345 static void
346 dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
347 {
348 (void) printf("\tUNKNOWN OBJECT TYPE\n");
349 }
350
351 /*ARGSUSED*/
352 void
353 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
354 {
355 }
504 /* 11 */ "11 (invalid)",
505 /* 12 */ "Socket",
506 /* 13 */ "Door",
507 /* 14 */ "Event Port",
508 /* 15 */ "15 (invalid)",
509 };
510
511 dump_zap_stats(os, object);
512 (void) printf("\n");
513
514 for (zap_cursor_init(&zc, os, object);
515 zap_cursor_retrieve(&zc, &attr) == 0;
516 zap_cursor_advance(&zc)) {
517 (void) printf("\t\t%s = %lld (type: %s)\n",
518 attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
519 typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
520 }
521 zap_cursor_fini(&zc);
522 }
523
524 static void
525 dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
526 {
527 uint64_t alloc, offset, entry;
528 uint8_t mapshift = sm->sm_shift;
529 uint64_t mapstart = sm->sm_start;
530 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
531 "INVALID", "INVALID", "INVALID", "INVALID" };
532
533 if (smo->smo_object == 0)
534 return;
535
536 /*
537 * Print out the freelist entries in both encoded and decoded form.
538 */
539 alloc = 0;
540 for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
541 VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
542 sizeof (entry), &entry, DMU_READ_PREFETCH));
543 if (SM_DEBUG_DECODE(entry)) {
544 (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
545 (u_longlong_t)(offset / sizeof (entry)),
546 ddata[SM_DEBUG_ACTION_DECODE(entry)],
547 (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
548 (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
549 } else {
550 (void) printf("\t [%6llu] %c range:"
551 " %010llx-%010llx size: %06llx\n",
552 (u_longlong_t)(offset / sizeof (entry)),
553 SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
554 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
555 mapshift) + mapstart),
556 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
557 mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
558 mapshift)),
559 (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
560 if (SM_TYPE_DECODE(entry) == SM_ALLOC)
561 alloc += SM_RUN_DECODE(entry) << mapshift;
562 else
563 alloc -= SM_RUN_DECODE(entry) << mapshift;
564 }
565 }
566 if (alloc != smo->smo_alloc) {
567 (void) printf("space_map_object alloc (%llu) INCONSISTENT "
568 "with space map summary (%llu)\n",
569 (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
570 }
571 }
572
573 static void
574 dump_metaslab_stats(metaslab_t *msp)
575 {
576 char maxbuf[32];
577 space_map_t *sm = msp->ms_map;
578 avl_tree_t *t = sm->sm_pp_root;
579 int free_pct = sm->sm_space * 100 / sm->sm_size;
580
581 zdb_nicenum(space_map_maxsize(sm), maxbuf);
582
583 (void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n",
584 "segments", avl_numnodes(t), "maxsize", maxbuf,
585 "freepct", free_pct);
586 }
587
588 static void
589 dump_metaslab(metaslab_t *msp)
590 {
591 vdev_t *vd = msp->ms_group->mg_vd;
592 spa_t *spa = vd->vdev_spa;
593 space_map_t *sm = msp->ms_map;
594 space_map_obj_t *smo = &msp->ms_smo;
595 char freebuf[32];
596
597 zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf);
598
599 (void) printf(
600 "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
601 (u_longlong_t)(sm->sm_start / sm->sm_size),
602 (u_longlong_t)sm->sm_start, (u_longlong_t)smo->smo_object, freebuf);
603
604 if (dump_opt['m'] > 1 && !dump_opt['L']) {
605 mutex_enter(&msp->ms_lock);
606 space_map_load_wait(sm);
607 if (!sm->sm_loaded)
608 VERIFY(space_map_load(sm, zfs_metaslab_ops,
609 SM_FREE, smo, spa->spa_meta_objset) == 0);
610 dump_metaslab_stats(msp);
611 space_map_unload(sm);
612 mutex_exit(&msp->ms_lock);
613 }
614
615 if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
616 ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift));
617
618 mutex_enter(&msp->ms_lock);
619 dump_spacemap(spa->spa_meta_objset, smo, sm);
620 mutex_exit(&msp->ms_lock);
621 }
622 }
623
624 static void
625 print_vdev_metaslab_header(vdev_t *vd)
626 {
627 (void) printf("\tvdev %10llu\n\t%-10s%5llu %-19s %-15s %-10s\n",
628 (u_longlong_t)vd->vdev_id,
629 "metaslabs", (u_longlong_t)vd->vdev_ms_count,
630 "offset", "spacemap", "free");
631 (void) printf("\t%15s %19s %15s %10s\n",
632 "---------------", "-------------------",
633 "---------------", "-------------");
634 }
635
636 static void
637 dump_metaslabs(spa_t *spa)
638 {
639 vdev_t *vd, *rvd = spa->spa_root_vdev;
786
787 ddt_get_dedup_stats(spa, &dds_total);
788
789 if (dds_total.dds_blocks == 0) {
790 (void) printf("All DDTs are empty\n");
791 return;
792 }
793
794 (void) printf("\n");
795
796 if (dump_opt['D'] > 1) {
797 (void) printf("DDT histogram (aggregated over all DDTs):\n");
798 ddt_get_dedup_histogram(spa, &ddh_total);
799 zpool_dump_ddt(&dds_total, &ddh_total);
800 }
801
802 dump_dedup_ratio(&dds_total);
803 }
804
805 static void
806 dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
807 {
808 char *prefix = (void *)sm;
809
810 (void) printf("%s [%llu,%llu) length %llu\n",
811 prefix,
812 (u_longlong_t)start,
813 (u_longlong_t)(start + size),
814 (u_longlong_t)(size));
815 }
816
817 static void
818 dump_dtl(vdev_t *vd, int indent)
819 {
820 spa_t *spa = vd->vdev_spa;
821 boolean_t required;
822 char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
823 char prefix[256];
824
825 spa_vdev_state_enter(spa, SCL_NONE);
826 required = vdev_dtl_required(vd);
827 (void) spa_vdev_state_exit(spa, NULL, 0);
828
829 if (indent == 0)
830 (void) printf("\nDirty time logs:\n\n");
831
832 (void) printf("\t%*s%s [%s]\n", indent, "",
833 vd->vdev_path ? vd->vdev_path :
834 vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
835 required ? "DTL-required" : "DTL-expendable");
836
837 for (int t = 0; t < DTL_TYPES; t++) {
838 space_map_t *sm = &vd->vdev_dtl[t];
839 if (sm->sm_space == 0)
840 continue;
841 (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
842 indent + 2, "", name[t]);
843 mutex_enter(sm->sm_lock);
844 space_map_walk(sm, dump_dtl_seg, (void *)prefix);
845 mutex_exit(sm->sm_lock);
846 if (dump_opt['d'] > 5 && vd->vdev_children == 0)
847 dump_spacemap(spa->spa_meta_objset,
848 &vd->vdev_dtl_smo, sm);
849 }
850
851 for (int c = 0; c < vd->vdev_children; c++)
852 dump_dtl(vd->vdev_child[c], indent + 4);
853 }
854
855 static void
856 dump_history(spa_t *spa)
857 {
858 nvlist_t **events = NULL;
859 char buf[SPA_MAXBLOCKSIZE];
860 uint64_t resid, len, off = 0;
861 uint_t num = 0;
862 int error;
863 time_t tsec;
864 struct tm t;
865 char tbuf[30];
866 char internalstr[MAXPATHLEN];
867
868 do {
2204 1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000));
2205 int sec_remaining =
2206 (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec;
2207
2208 zfs_nicenum(bytes, buf, sizeof (buf));
2209 (void) fprintf(stderr,
2210 "\r%5s completed (%4dMB/s) "
2211 "estimated time remaining: %uhr %02umin %02usec ",
2212 buf, kb_per_sec / 1024,
2213 sec_remaining / 60 / 60,
2214 sec_remaining / 60 % 60,
2215 sec_remaining % 60);
2216
2217 zcb->zcb_lastprint = now;
2218 }
2219
2220 return (0);
2221 }
2222
2223 static void
2224 zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
2225 {
2226 vdev_t *vd = sm->sm_ppd;
2227
2228 (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
2229 (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
2230 }
2231
2232 /* ARGSUSED */
2233 static void
2234 zdb_space_map_load(space_map_t *sm)
2235 {
2236 }
2237
2238 static void
2239 zdb_space_map_unload(space_map_t *sm)
2240 {
2241 space_map_vacate(sm, zdb_leak, sm);
2242 }
2243
2244 /* ARGSUSED */
2245 static void
2246 zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
2247 {
2248 }
2249
2250 static space_map_ops_t zdb_space_map_ops = {
2251 zdb_space_map_load,
2252 zdb_space_map_unload,
2253 NULL, /* alloc */
2254 zdb_space_map_claim,
2255 NULL, /* free */
2256 NULL /* maxsize */
2257 };
2258
2259 static void
2260 zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
2261 {
2262 ddt_bookmark_t ddb = { 0 };
2263 ddt_entry_t dde;
2264 int error;
2265
2266 while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
2267 blkptr_t blk;
2268 ddt_phys_t *ddp = dde.dde_phys;
2269
2270 if (ddb.ddb_class == DDT_CLASS_UNIQUE)
2271 return;
2272
2273 ASSERT(ddt_phys_total_refcnt(&dde) > 1);
2274
2275 for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
2276 if (ddp->ddp_phys_birth == 0)
2291 VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
2292 ddt_exit(ddt);
2293 }
2294 }
2295
2296 ASSERT(error == ENOENT);
2297 }
2298
2299 static void
2300 zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
2301 {
2302 zcb->zcb_spa = spa;
2303
2304 if (!dump_opt['L']) {
2305 vdev_t *rvd = spa->spa_root_vdev;
2306 for (int c = 0; c < rvd->vdev_children; c++) {
2307 vdev_t *vd = rvd->vdev_child[c];
2308 for (int m = 0; m < vd->vdev_ms_count; m++) {
2309 metaslab_t *msp = vd->vdev_ms[m];
2310 mutex_enter(&msp->ms_lock);
2311 space_map_unload(msp->ms_map);
2312 VERIFY(space_map_load(msp->ms_map,
2313 &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
2314 spa->spa_meta_objset) == 0);
2315 msp->ms_map->sm_ppd = vd;
2316 mutex_exit(&msp->ms_lock);
2317 }
2318 }
2319 }
2320
2321 spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2322
2323 zdb_ddt_leak_init(spa, zcb);
2324
2325 spa_config_exit(spa, SCL_CONFIG, FTAG);
2326 }
2327
2328 static void
2329 zdb_leak_fini(spa_t *spa)
2330 {
2331 if (!dump_opt['L']) {
2332 vdev_t *rvd = spa->spa_root_vdev;
2333 for (int c = 0; c < rvd->vdev_children; c++) {
2334 vdev_t *vd = rvd->vdev_child[c];
2335 for (int m = 0; m < vd->vdev_ms_count; m++) {
2336 metaslab_t *msp = vd->vdev_ms[m];
2337 mutex_enter(&msp->ms_lock);
2338 space_map_unload(msp->ms_map);
2339 mutex_exit(&msp->ms_lock);
2340 }
2341 }
2342 }
2343 }
2344
2345 /* ARGSUSED */
2346 static int
2347 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
2348 {
2349 zdb_cb_t *zcb = arg;
2350
2351 if (dump_opt['b'] >= 5) {
2352 char blkbuf[BP_SPRINTF_LEN];
2353 sprintf_blkptr(blkbuf, bp);
2354 (void) printf("[%s] %s\n",
2355 "deferred free", blkbuf);
2356 }
2357 zdb_count_block(zcb, NULL, bp, ZDB_OT_DEFERRED);
2358 return (0);
2546 csize, lsize, psize, asize, avg,
2547 (double)zb->zb_lsize / zb->zb_psize,
2548 100.0 * zb->zb_asize / tzb->zb_asize);
2549
2550 if (level == ZB_TOTAL)
2551 (void) printf("%s\n", typename);
2552 else
2553 (void) printf(" L%d %s\n",
2554 level, typename);
2555
2556 if (dump_opt['b'] >= 3 && zb->zb_gangs > 0) {
2557 (void) printf("\t number of ganged "
2558 "blocks: %s\n", gang);
2559 }
2560
2561 if (dump_opt['b'] >= 4) {
2562 (void) printf("psize "
2563 "(in 512-byte sectors): "
2564 "number of blocks\n");
2565 dump_histogram(zb->zb_psize_histogram,
2566 PSIZE_HISTO_SIZE);
2567 }
2568 }
2569 }
2570 }
2571
2572 (void) printf("\n");
2573
2574 if (leaks)
2575 return (2);
2576
2577 if (zcb.zcb_haderrors)
2578 return (3);
2579
2580 return (0);
2581 }
2582
2583 typedef struct zdb_ddt_entry {
2584 ddt_key_t zdde_key;
2585 uint64_t zdde_ref_blocks;
2586 uint64_t zdde_ref_lsize;
2716 "Deferred frees", 0);
2717 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2718 dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2719 "Pool snapshot frees", 0);
2720 }
2721
2722 if (spa_feature_is_active(spa,
2723 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2724 dump_bptree(spa->spa_meta_objset,
2725 spa->spa_dsl_pool->dp_bptree_obj,
2726 "Pool dataset frees");
2727 }
2728 dump_dtl(spa->spa_root_vdev, 0);
2729 }
2730 (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2731 NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2732 }
2733 if (dump_opt['b'] || dump_opt['c'])
2734 rc = dump_block_stats(spa);
2735
2736 if (dump_opt['s'])
2737 show_pool_stats(spa);
2738
2739 if (dump_opt['h'])
2740 dump_history(spa);
2741
2742 if (rc != 0)
2743 exit(rc);
2744 }
2745
2746 #define ZDB_FLAG_CHECKSUM 0x0001
2747 #define ZDB_FLAG_DECOMPRESS 0x0002
2748 #define ZDB_FLAG_BSWAP 0x0004
2749 #define ZDB_FLAG_GBH 0x0008
2750 #define ZDB_FLAG_INDIRECT 0x0010
2751 #define ZDB_FLAG_PHYS 0x0020
2752 #define ZDB_FLAG_RAW 0x0040
2753 #define ZDB_FLAG_PRINT_BLKPTR 0x0080
2754
2755 int flagbits[256];
|
229 (u_longlong_t)shp->sh_bof);
230 (void) printf("\t\teof = %llu\n",
231 (u_longlong_t)shp->sh_eof);
232 (void) printf("\t\trecords_lost = %llu\n",
233 (u_longlong_t)shp->sh_records_lost);
234 }
235
236 static void
237 zdb_nicenum(uint64_t num, char *buf)
238 {
239 if (dump_opt['P'])
240 (void) sprintf(buf, "%llu", (longlong_t)num);
241 else
242 nicenum(num, buf);
243 }
244
245 const char histo_stars[] = "****************************************";
246 const int histo_width = sizeof (histo_stars) - 1;
247
248 static void
249 dump_histogram(const uint64_t *histo, int size, int offset)
250 {
251 int i;
252 int minidx = size - 1;
253 int maxidx = 0;
254 uint64_t max = 0;
255
256 for (i = 0; i < size; i++) {
257 if (histo[i] > max)
258 max = histo[i];
259 if (histo[i] > 0 && i > maxidx)
260 maxidx = i;
261 if (histo[i] > 0 && i < minidx)
262 minidx = i;
263 }
264
265 if (max < histo_width)
266 max = histo_width;
267
268 for (i = minidx; i <= maxidx; i++) {
269 (void) printf("\t\t\t%3u: %6llu %s\n",
270 i + offset, (u_longlong_t)histo[i],
271 &histo_stars[(max - histo[i]) * histo_width / max]);
272 }
273 }
274
275 static void
276 dump_zap_stats(objset_t *os, uint64_t object)
277 {
278 int error;
279 zap_stats_t zs;
280
281 error = zap_get_stats(os, object, &zs);
282 if (error)
283 return;
284
285 if (zs.zs_ptrtbl_len == 0) {
286 ASSERT(zs.zs_num_blocks == 1);
287 (void) printf("\tmicrozap: %llu bytes, %llu entries\n",
288 (u_longlong_t)zs.zs_blocksize,
289 (u_longlong_t)zs.zs_num_entries);
290 return;
303 (u_longlong_t)zs.zs_ptrtbl_zt_shift);
304 (void) printf("\t\t\tzt_blks_copied: %llu\n",
305 (u_longlong_t)zs.zs_ptrtbl_blks_copied);
306 (void) printf("\t\t\tzt_nextblk: %llu\n",
307 (u_longlong_t)zs.zs_ptrtbl_nextblk);
308
309 (void) printf("\t\tZAP entries: %llu\n",
310 (u_longlong_t)zs.zs_num_entries);
311 (void) printf("\t\tLeaf blocks: %llu\n",
312 (u_longlong_t)zs.zs_num_leafs);
313 (void) printf("\t\tTotal blocks: %llu\n",
314 (u_longlong_t)zs.zs_num_blocks);
315 (void) printf("\t\tzap_block_type: 0x%llx\n",
316 (u_longlong_t)zs.zs_block_type);
317 (void) printf("\t\tzap_magic: 0x%llx\n",
318 (u_longlong_t)zs.zs_magic);
319 (void) printf("\t\tzap_salt: 0x%llx\n",
320 (u_longlong_t)zs.zs_salt);
321
322 (void) printf("\t\tLeafs with 2^n pointers:\n");
323 dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
324
325 (void) printf("\t\tBlocks with n*5 entries:\n");
326 dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
327
328 (void) printf("\t\tBlocks n/10 full:\n");
329 dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
330
331 (void) printf("\t\tEntries with n chunks:\n");
332 dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
333
334 (void) printf("\t\tBuckets with n entries:\n");
335 dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
336 }
337
338 /*ARGSUSED*/
339 static void
340 dump_none(objset_t *os, uint64_t object, void *data, size_t size)
341 {
342 }
343
344 /*ARGSUSED*/
345 static void
346 dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
347 {
348 (void) printf("\tUNKNOWN OBJECT TYPE\n");
349 }
350
351 /*ARGSUSED*/
352 void
353 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
354 {
355 }
504 /* 11 */ "11 (invalid)",
505 /* 12 */ "Socket",
506 /* 13 */ "Door",
507 /* 14 */ "Event Port",
508 /* 15 */ "15 (invalid)",
509 };
510
511 dump_zap_stats(os, object);
512 (void) printf("\n");
513
514 for (zap_cursor_init(&zc, os, object);
515 zap_cursor_retrieve(&zc, &attr) == 0;
516 zap_cursor_advance(&zc)) {
517 (void) printf("\t\t%s = %lld (type: %s)\n",
518 attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
519 typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
520 }
521 zap_cursor_fini(&zc);
522 }
523
524 int
525 get_dtl_refcount(vdev_t *vd)
526 {
527 int refcount = 0;
528
529 if (vd->vdev_ops->vdev_op_leaf) {
530 space_map_t *sm = vd->vdev_dtl_sm;
531
532 if (sm != NULL &&
533 sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
534 return (1);
535 return (0);
536 }
537
538 for (int c = 0; c < vd->vdev_children; c++)
539 refcount += get_dtl_refcount(vd->vdev_child[c]);
540 return (refcount);
541 }
542
543 int
544 get_metaslab_refcount(vdev_t *vd)
545 {
546 int refcount = 0;
547
548 if (vd->vdev_top == vd) {
549 for (int m = 0; m < vd->vdev_ms_count; m++) {
550 space_map_t *sm = vd->vdev_ms[m]->ms_sm;
551
552 if (sm != NULL &&
553 sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
554 refcount++;
555 }
556 }
557 for (int c = 0; c < vd->vdev_children; c++)
558 refcount += get_metaslab_refcount(vd->vdev_child[c]);
559
560 return (refcount);
561 }
562
563 static int
564 verify_spacemap_refcounts(spa_t *spa)
565 {
566 int expected_refcount, actual_refcount;
567
568 expected_refcount = spa_feature_get_refcount(spa,
569 &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM]);
570 actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
571 actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
572
573 if (expected_refcount != actual_refcount) {
574 (void) printf("space map refcount mismatch: expected %d != "
575 "actual %d\n", expected_refcount, actual_refcount);
576 return (2);
577 }
578 return (0);
579 }
580
581 static void
582 dump_spacemap(objset_t *os, space_map_t *sm)
583 {
584 uint64_t alloc, offset, entry;
585 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
586 "INVALID", "INVALID", "INVALID", "INVALID" };
587
588 if (sm == NULL)
589 return;
590
591 /*
592 * Print out the freelist entries in both encoded and decoded form.
593 */
594 alloc = 0;
595 for (offset = 0; offset < space_map_length(sm);
596 offset += sizeof (entry)) {
597 uint8_t mapshift = sm->sm_shift;
598
599 VERIFY0(dmu_read(os, space_map_object(sm), offset,
600 sizeof (entry), &entry, DMU_READ_PREFETCH));
601 if (SM_DEBUG_DECODE(entry)) {
602
603 (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
604 (u_longlong_t)(offset / sizeof (entry)),
605 ddata[SM_DEBUG_ACTION_DECODE(entry)],
606 (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
607 (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
608 } else {
609 (void) printf("\t [%6llu] %c range:"
610 " %010llx-%010llx size: %06llx\n",
611 (u_longlong_t)(offset / sizeof (entry)),
612 SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
613 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
614 mapshift) + sm->sm_start),
615 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
616 mapshift) + sm->sm_start +
617 (SM_RUN_DECODE(entry) << mapshift)),
618 (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
619 if (SM_TYPE_DECODE(entry) == SM_ALLOC)
620 alloc += SM_RUN_DECODE(entry) << mapshift;
621 else
622 alloc -= SM_RUN_DECODE(entry) << mapshift;
623 }
624 }
625 if (alloc != space_map_allocated(sm)) {
626 (void) printf("space_map_object alloc (%llu) INCONSISTENT "
627 "with space map summary (%llu)\n",
628 (u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc);
629 }
630 }
631
632 static void
633 dump_metaslab_stats(metaslab_t *msp)
634 {
635 char maxbuf[32];
636 range_tree_t *rt = msp->ms_tree;
637 avl_tree_t *t = &msp->ms_size_tree;
638 int free_pct = range_tree_space(rt) * 100 / msp->ms_size;
639
640 zdb_nicenum(metaslab_block_maxsize(msp), maxbuf);
641
642 (void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n",
643 "segments", avl_numnodes(t), "maxsize", maxbuf,
644 "freepct", free_pct);
645 (void) printf("\tIn-memory histogram:\n");
646 dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
647 }
648
649 static void
650 dump_metaslab(metaslab_t *msp)
651 {
652 vdev_t *vd = msp->ms_group->mg_vd;
653 spa_t *spa = vd->vdev_spa;
654 space_map_t *sm = msp->ms_sm;
655 char freebuf[32];
656
657 zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf);
658
659 (void) printf(
660 "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
661 (u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
662 (u_longlong_t)space_map_object(sm), freebuf);
663
664 if (dump_opt['m'] > 2 && !dump_opt['L']) {
665 mutex_enter(&msp->ms_lock);
666 metaslab_load_wait(msp);
667 if (!msp->ms_loaded) {
668 VERIFY0(metaslab_load(msp));
669 range_tree_stat_verify(msp->ms_tree);
670 }
671 dump_metaslab_stats(msp);
672 metaslab_unload(msp);
673 mutex_exit(&msp->ms_lock);
674 }
675
676 if (dump_opt['m'] > 1 && sm != NULL &&
677 spa_feature_is_active(spa,
678 &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM])) {
679 /*
680 * The space map histogram represents free space in chunks
681 * of sm_shift (i.e. bucket 0 refers to 2^sm_shift).
682 */
683 (void) printf("\tOn-disk histogram:\n");
684 dump_histogram(sm->sm_phys->smp_histogram,
685 SPACE_MAP_HISTOGRAM_SIZE(sm), sm->sm_shift);
686 }
687
688 if (dump_opt['d'] > 5 || dump_opt['m'] > 3) {
689 ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift));
690
691 mutex_enter(&msp->ms_lock);
692 dump_spacemap(spa->spa_meta_objset, msp->ms_sm);
693 mutex_exit(&msp->ms_lock);
694 }
695 }
696
697 static void
698 print_vdev_metaslab_header(vdev_t *vd)
699 {
700 (void) printf("\tvdev %10llu\n\t%-10s%5llu %-19s %-15s %-10s\n",
701 (u_longlong_t)vd->vdev_id,
702 "metaslabs", (u_longlong_t)vd->vdev_ms_count,
703 "offset", "spacemap", "free");
704 (void) printf("\t%15s %19s %15s %10s\n",
705 "---------------", "-------------------",
706 "---------------", "-------------");
707 }
708
709 static void
710 dump_metaslabs(spa_t *spa)
711 {
712 vdev_t *vd, *rvd = spa->spa_root_vdev;
859
860 ddt_get_dedup_stats(spa, &dds_total);
861
862 if (dds_total.dds_blocks == 0) {
863 (void) printf("All DDTs are empty\n");
864 return;
865 }
866
867 (void) printf("\n");
868
869 if (dump_opt['D'] > 1) {
870 (void) printf("DDT histogram (aggregated over all DDTs):\n");
871 ddt_get_dedup_histogram(spa, &ddh_total);
872 zpool_dump_ddt(&dds_total, &ddh_total);
873 }
874
875 dump_dedup_ratio(&dds_total);
876 }
877
878 static void
879 dump_dtl_seg(void *arg, uint64_t start, uint64_t size)
880 {
881 char *prefix = arg;
882
883 (void) printf("%s [%llu,%llu) length %llu\n",
884 prefix,
885 (u_longlong_t)start,
886 (u_longlong_t)(start + size),
887 (u_longlong_t)(size));
888 }
889
890 static void
891 dump_dtl(vdev_t *vd, int indent)
892 {
893 spa_t *spa = vd->vdev_spa;
894 boolean_t required;
895 char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
896 char prefix[256];
897
898 spa_vdev_state_enter(spa, SCL_NONE);
899 required = vdev_dtl_required(vd);
900 (void) spa_vdev_state_exit(spa, NULL, 0);
901
902 if (indent == 0)
903 (void) printf("\nDirty time logs:\n\n");
904
905 (void) printf("\t%*s%s [%s]\n", indent, "",
906 vd->vdev_path ? vd->vdev_path :
907 vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
908 required ? "DTL-required" : "DTL-expendable");
909
910 for (int t = 0; t < DTL_TYPES; t++) {
911 range_tree_t *rt = vd->vdev_dtl[t];
912 if (range_tree_space(rt) == 0)
913 continue;
914 (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
915 indent + 2, "", name[t]);
916 mutex_enter(rt->rt_lock);
917 range_tree_walk(rt, dump_dtl_seg, prefix);
918 mutex_exit(rt->rt_lock);
919 if (dump_opt['d'] > 5 && vd->vdev_children == 0)
920 dump_spacemap(spa->spa_meta_objset, vd->vdev_dtl_sm);
921 }
922
923 for (int c = 0; c < vd->vdev_children; c++)
924 dump_dtl(vd->vdev_child[c], indent + 4);
925 }
926
927 static void
928 dump_history(spa_t *spa)
929 {
930 nvlist_t **events = NULL;
931 char buf[SPA_MAXBLOCKSIZE];
932 uint64_t resid, len, off = 0;
933 uint_t num = 0;
934 int error;
935 time_t tsec;
936 struct tm t;
937 char tbuf[30];
938 char internalstr[MAXPATHLEN];
939
940 do {
2276 1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000));
2277 int sec_remaining =
2278 (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec;
2279
2280 zfs_nicenum(bytes, buf, sizeof (buf));
2281 (void) fprintf(stderr,
2282 "\r%5s completed (%4dMB/s) "
2283 "estimated time remaining: %uhr %02umin %02usec ",
2284 buf, kb_per_sec / 1024,
2285 sec_remaining / 60 / 60,
2286 sec_remaining / 60 % 60,
2287 sec_remaining % 60);
2288
2289 zcb->zcb_lastprint = now;
2290 }
2291
2292 return (0);
2293 }
2294
2295 static void
2296 zdb_leak(void *arg, uint64_t start, uint64_t size)
2297 {
2298 vdev_t *vd = arg;
2299
2300 (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
2301 (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
2302 }
2303
2304 static metaslab_ops_t zdb_metaslab_ops = {
2305 NULL, /* alloc */
2306 NULL /* fragmented */
2307 };
2308
2309 static void
2310 zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
2311 {
2312 ddt_bookmark_t ddb = { 0 };
2313 ddt_entry_t dde;
2314 int error;
2315
2316 while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
2317 blkptr_t blk;
2318 ddt_phys_t *ddp = dde.dde_phys;
2319
2320 if (ddb.ddb_class == DDT_CLASS_UNIQUE)
2321 return;
2322
2323 ASSERT(ddt_phys_total_refcnt(&dde) > 1);
2324
2325 for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
2326 if (ddp->ddp_phys_birth == 0)
2341 VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
2342 ddt_exit(ddt);
2343 }
2344 }
2345
2346 ASSERT(error == ENOENT);
2347 }
2348
2349 static void
2350 zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
2351 {
2352 zcb->zcb_spa = spa;
2353
2354 if (!dump_opt['L']) {
2355 vdev_t *rvd = spa->spa_root_vdev;
2356 for (int c = 0; c < rvd->vdev_children; c++) {
2357 vdev_t *vd = rvd->vdev_child[c];
2358 for (int m = 0; m < vd->vdev_ms_count; m++) {
2359 metaslab_t *msp = vd->vdev_ms[m];
2360 mutex_enter(&msp->ms_lock);
2361 metaslab_unload(msp);
2362
2363 /*
2364 * For leak detection, we overload the metaslab
2365 * ms_tree to contain allocated segments
2366 * instead of free segments. As a result,
2367 * we can't use the normal metaslab_load/unload
2368 * interfaces.
2369 */
2370 if (msp->ms_sm != NULL) {
2371 msp->ms_ops = &zdb_metaslab_ops;
2372 VERIFY0(space_map_load(msp->ms_sm,
2373 msp->ms_tree, SM_ALLOC));
2374 msp->ms_loaded = B_TRUE;
2375 }
2376 mutex_exit(&msp->ms_lock);
2377 }
2378 }
2379 }
2380
2381 spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2382
2383 zdb_ddt_leak_init(spa, zcb);
2384
2385 spa_config_exit(spa, SCL_CONFIG, FTAG);
2386 }
2387
2388 static void
2389 zdb_leak_fini(spa_t *spa)
2390 {
2391 if (!dump_opt['L']) {
2392 vdev_t *rvd = spa->spa_root_vdev;
2393 for (int c = 0; c < rvd->vdev_children; c++) {
2394 vdev_t *vd = rvd->vdev_child[c];
2395 for (int m = 0; m < vd->vdev_ms_count; m++) {
2396 metaslab_t *msp = vd->vdev_ms[m];
2397 mutex_enter(&msp->ms_lock);
2398
2399 /*
2400 * The ms_tree has been overloaded to
2401 * contain allocated segments. Now that we
2402 * finished traversing all blocks, any
2403 * block that remains in the ms_tree
2404 * represents an allocated block that we
2405 * did not claim during the traversal.
2406 * Claimed blocks would have been removed
2407 * from the ms_tree.
2408 */
2409 range_tree_vacate(msp->ms_tree, zdb_leak, vd);
2410 msp->ms_loaded = B_FALSE;
2411
2412 mutex_exit(&msp->ms_lock);
2413 }
2414 }
2415 }
2416 }
2417
2418 /* ARGSUSED */
2419 static int
2420 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
2421 {
2422 zdb_cb_t *zcb = arg;
2423
2424 if (dump_opt['b'] >= 5) {
2425 char blkbuf[BP_SPRINTF_LEN];
2426 sprintf_blkptr(blkbuf, bp);
2427 (void) printf("[%s] %s\n",
2428 "deferred free", blkbuf);
2429 }
2430 zdb_count_block(zcb, NULL, bp, ZDB_OT_DEFERRED);
2431 return (0);
2619 csize, lsize, psize, asize, avg,
2620 (double)zb->zb_lsize / zb->zb_psize,
2621 100.0 * zb->zb_asize / tzb->zb_asize);
2622
2623 if (level == ZB_TOTAL)
2624 (void) printf("%s\n", typename);
2625 else
2626 (void) printf(" L%d %s\n",
2627 level, typename);
2628
2629 if (dump_opt['b'] >= 3 && zb->zb_gangs > 0) {
2630 (void) printf("\t number of ganged "
2631 "blocks: %s\n", gang);
2632 }
2633
2634 if (dump_opt['b'] >= 4) {
2635 (void) printf("psize "
2636 "(in 512-byte sectors): "
2637 "number of blocks\n");
2638 dump_histogram(zb->zb_psize_histogram,
2639 PSIZE_HISTO_SIZE, 0);
2640 }
2641 }
2642 }
2643 }
2644
2645 (void) printf("\n");
2646
2647 if (leaks)
2648 return (2);
2649
2650 if (zcb.zcb_haderrors)
2651 return (3);
2652
2653 return (0);
2654 }
2655
2656 typedef struct zdb_ddt_entry {
2657 ddt_key_t zdde_key;
2658 uint64_t zdde_ref_blocks;
2659 uint64_t zdde_ref_lsize;
2789 "Deferred frees", 0);
2790 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2791 dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2792 "Pool snapshot frees", 0);
2793 }
2794
2795 if (spa_feature_is_active(spa,
2796 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2797 dump_bptree(spa->spa_meta_objset,
2798 spa->spa_dsl_pool->dp_bptree_obj,
2799 "Pool dataset frees");
2800 }
2801 dump_dtl(spa->spa_root_vdev, 0);
2802 }
2803 (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2804 NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2805 }
2806 if (dump_opt['b'] || dump_opt['c'])
2807 rc = dump_block_stats(spa);
2808
2809 if (rc == 0)
2810 rc = verify_spacemap_refcounts(spa);
2811
2812 if (dump_opt['s'])
2813 show_pool_stats(spa);
2814
2815 if (dump_opt['h'])
2816 dump_history(spa);
2817
2818 if (rc != 0)
2819 exit(rc);
2820 }
2821
2822 #define ZDB_FLAG_CHECKSUM 0x0001
2823 #define ZDB_FLAG_DECOMPRESS 0x0002
2824 #define ZDB_FLAG_BSWAP 0x0004
2825 #define ZDB_FLAG_GBH 0x0008
2826 #define ZDB_FLAG_INDIRECT 0x0010
2827 #define ZDB_FLAG_PHYS 0x0020
2828 #define ZDB_FLAG_RAW 0x0040
2829 #define ZDB_FLAG_PRINT_BLKPTR 0x0080
2830
2831 int flagbits[256];
|