usr/src/cmd/zdb/zdb.c
changeset 8121 7fd09d4ebd9c
parent 7837 001de5627df3
child 8188 fd00c0a81e80
equal deleted inserted replaced
8120:fe3876cb24f1 8121:7fd09d4ebd9c
    85 
    85 
    86 static void
    86 static void
    87 usage(void)
    87 usage(void)
    88 {
    88 {
    89 	(void) fprintf(stderr,
    89 	(void) fprintf(stderr,
    90 	    "Usage: %s [-udibcsv] [-U cachefile_path] "
    90 	    "Usage: %s [-udibcsvL] [-U cachefile_path] "
    91 	    "[-S user:cksumalg] "
    91 	    "[-S user:cksumalg] "
    92 	    "dataset [object...]\n"
    92 	    "dataset [object...]\n"
    93 	    "       %s -C [pool]\n"
    93 	    "       %s -C [pool]\n"
    94 	    "       %s -l dev\n"
    94 	    "       %s -l dev\n"
    95 	    "       %s -R pool:vdev:offset:size:flags\n"
    95 	    "       %s -R pool:vdev:offset:size:flags\n"
   106 	(void) fprintf(stderr, "	-s report stats on zdb's I/O\n");
   106 	(void) fprintf(stderr, "	-s report stats on zdb's I/O\n");
   107 	(void) fprintf(stderr, "	-S <user|all>:<cksum_alg|all> -- "
   107 	(void) fprintf(stderr, "	-S <user|all>:<cksum_alg|all> -- "
   108 	    "dump blkptr signatures\n");
   108 	    "dump blkptr signatures\n");
   109 	(void) fprintf(stderr, "	-v verbose (applies to all others)\n");
   109 	(void) fprintf(stderr, "	-v verbose (applies to all others)\n");
   110 	(void) fprintf(stderr, "        -l dump label contents\n");
   110 	(void) fprintf(stderr, "        -l dump label contents\n");
       
   111 	(void) fprintf(stderr, "        -L disable leak tracking (do not "
       
   112 	    "load spacemaps)\n");
   111 	(void) fprintf(stderr, "	-U cachefile_path -- use alternate "
   113 	(void) fprintf(stderr, "	-U cachefile_path -- use alternate "
   112 	    "cachefile\n");
   114 	    "cachefile\n");
   113 	(void) fprintf(stderr, "        -R read and display block from a "
   115 	(void) fprintf(stderr, "        -R read and display block from a "
   114 	    "device\n");
   116 	    "device\n");
   115 	(void) fprintf(stderr, "        -e Pool is exported/destroyed/"
   117 	(void) fprintf(stderr, "        -e Pool is exported/destroyed/"
  1479 			    (u_longlong_t)bp->blk_cksum.zc_word[2],
  1481 			    (u_longlong_t)bp->blk_cksum.zc_word[2],
  1480 			    (u_longlong_t)bp->blk_cksum.zc_word[3]);
  1482 			    (u_longlong_t)bp->blk_cksum.zc_word[3]);
  1481 		}
  1483 		}
  1482 	}
  1484 	}
  1483 
  1485 
  1484 	VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
  1486 	if (!dump_opt['L'])
  1485 	    NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
  1487 		VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
       
  1488 		    NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
  1486 }
  1489 }
  1487 
  1490 
  1488 static int
  1491 static int
  1489 zdb_blkptr_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb,
  1492 zdb_blkptr_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb,
  1490     const dnode_phys_t *dnp, void *arg)
  1493     const dnode_phys_t *dnp, void *arg)
  1555 	vdev_t *rvd = spa->spa_root_vdev;
  1558 	vdev_t *rvd = spa->spa_root_vdev;
  1556 	int leaks = 0;
  1559 	int leaks = 0;
  1557 	int c, e;
  1560 	int c, e;
  1558 
  1561 
  1559 	if (!dump_opt['S']) {
  1562 	if (!dump_opt['S']) {
  1560 		(void) printf("\nTraversing all blocks to %sverify"
  1563 		(void) printf("\nTraversing all blocks %s%s%s%s...\n",
  1561 		    " nothing leaked ...\n",
  1564 		    (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
  1562 		    dump_opt['c'] ? "verify checksums and " : "");
  1565 		    dump_opt['c'] ? "checksums " : "",
       
  1566 		    (dump_opt['c'] && !dump_opt['L']) ? "and verify " : "",
       
  1567 		    !dump_opt['L'] ? "nothing leaked " : "");
  1563 	}
  1568 	}
  1564 
  1569 
  1565 	/*
  1570 	/*
  1566 	 * Load all space maps as SM_ALLOC maps, then traverse the pool
  1571 	 * Load all space maps as SM_ALLOC maps, then traverse the pool
  1567 	 * claiming each block we discover.  If the pool is perfectly
  1572 	 * claiming each block we discover.  If the pool is perfectly
  1568 	 * consistent, the space maps will be empty when we're done.
  1573 	 * consistent, the space maps will be empty when we're done.
  1569 	 * Anything left over is a leak; any block we can't claim (because
  1574 	 * Anything left over is a leak; any block we can't claim (because
  1570 	 * it's not part of any space map) is a double allocation,
  1575 	 * it's not part of any space map) is a double allocation,
  1571 	 * reference to a freed block, or an unclaimed log block.
  1576 	 * reference to a freed block, or an unclaimed log block.
  1572 	 */
  1577 	 */
  1573 	zdb_leak_init(spa);
  1578 	if (!dump_opt['L'])
       
  1579 		zdb_leak_init(spa);
  1574 
  1580 
  1575 	/*
  1581 	/*
  1576 	 * If there's a deferred-free bplist, process that first.
  1582 	 * If there's a deferred-free bplist, process that first.
  1577 	 */
  1583 	 */
  1578 	if (spa->spa_sync_bplist_obj != 0) {
  1584 	if (spa->spa_sync_bplist_obj != 0) {
  1610 	}
  1616 	}
  1611 
  1617 
  1612 	/*
  1618 	/*
  1613 	 * Report any leaked segments.
  1619 	 * Report any leaked segments.
  1614 	 */
  1620 	 */
  1615 	zdb_leak_fini(spa);
  1621 	if (!dump_opt['L'])
       
  1622 		zdb_leak_fini(spa);
  1616 
  1623 
  1617 	/*
  1624 	/*
  1618 	 * If we're interested in printing out the blkptr signatures,
  1625 	 * If we're interested in printing out the blkptr signatures,
  1619 	 * return now as we don't print out anything else (including
  1626 	 * return now as we don't print out anything else (including
  1620 	 * errors and leaks).
  1627 	 * errors and leaks).
  1636 			logalloc += rvd->vdev_child[c]->vdev_stat.vs_alloc;
  1643 			logalloc += rvd->vdev_child[c]->vdev_stat.vs_alloc;
  1637 
  1644 
  1638 	tzb = &zcb.zcb_type[ZB_TOTAL][DMU_OT_TOTAL];
  1645 	tzb = &zcb.zcb_type[ZB_TOTAL][DMU_OT_TOTAL];
  1639 
  1646 
  1640 	if (tzb->zb_asize == alloc + logalloc) {
  1647 	if (tzb->zb_asize == alloc + logalloc) {
  1641 		(void) printf("\n\tNo leaks (block sum matches space"
  1648 		if (!dump_opt['L'])
  1642 		    " maps exactly)\n");
  1649 			(void) printf("\n\tNo leaks (block sum matches space"
       
  1650 			    " maps exactly)\n");
  1643 	} else {
  1651 	} else {
  1644 		(void) printf("block traversal size %llu != alloc %llu "
  1652 		(void) printf("block traversal size %llu != alloc %llu "
  1645 		    "(leaked %lld)\n",
  1653 		    "(%s %lld)\n",
  1646 		    (u_longlong_t)tzb->zb_asize,
  1654 		    (u_longlong_t)tzb->zb_asize,
  1647 		    (u_longlong_t)alloc + logalloc,
  1655 		    (u_longlong_t)alloc + logalloc,
  1648 		    (u_longlong_t)(alloc + logalloc - tzb->zb_asize));
  1656 		    (dump_opt['L']) ? "unreachable" : "leaked",
       
  1657 		    (longlong_t)(alloc + logalloc - tzb->zb_asize));
  1649 		leaks = 1;
  1658 		leaks = 1;
  1650 	}
  1659 	}
  1651 
  1660 
  1652 	if (tzb->zb_count == 0)
  1661 	if (tzb->zb_count == 0)
  1653 		return (2);
  1662 		return (2);
  2233 	(void) setrlimit(RLIMIT_NOFILE, &rl);
  2242 	(void) setrlimit(RLIMIT_NOFILE, &rl);
  2234 	(void) enable_extended_FILE_stdio(-1, -1);
  2243 	(void) enable_extended_FILE_stdio(-1, -1);
  2235 
  2244 
  2236 	dprintf_setup(&argc, argv);
  2245 	dprintf_setup(&argc, argv);
  2237 
  2246 
  2238 	while ((c = getopt(argc, argv, "udibcsvCS:U:lRep:")) != -1) {
  2247 	while ((c = getopt(argc, argv, "udibcsvCLS:U:lRep:")) != -1) {
  2239 		switch (c) {
  2248 		switch (c) {
  2240 		case 'u':
  2249 		case 'u':
  2241 		case 'd':
  2250 		case 'd':
  2242 		case 'i':
  2251 		case 'i':
  2243 		case 'b':
  2252 		case 'b':
  2246 		case 'C':
  2255 		case 'C':
  2247 		case 'l':
  2256 		case 'l':
  2248 		case 'R':
  2257 		case 'R':
  2249 			dump_opt[c]++;
  2258 			dump_opt[c]++;
  2250 			dump_all = 0;
  2259 			dump_all = 0;
       
  2260 			break;
       
  2261 		case 'L':
       
  2262 			dump_opt[c]++;
  2251 			break;
  2263 			break;
  2252 		case 'v':
  2264 		case 'v':
  2253 			verbose++;
  2265 			verbose++;
  2254 			break;
  2266 			break;
  2255 		case 'U':
  2267 		case 'U':