Print this page
4101 metaslab_debug should allow for fine-grained control
4102 space_maps should store more information about themselves
4103 space map object blocksize should be increased
4104 ::spa_space no longer works
4105 removing a mirrored log device results in a leaked object
4106 asynchronously load metaslab
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Sebastien Roy <seb@delphix.com>


1438 } mdb_spa_t;
1439 
1440 typedef struct mdb_dsl_dir {
1441         uintptr_t dd_phys;
1442         int64_t dd_space_towrite[TXG_SIZE];
1443 } mdb_dsl_dir_t;
1444 
1445 typedef struct mdb_dsl_dir_phys {
1446         uint64_t dd_used_bytes;
1447         uint64_t dd_compressed_bytes;
1448         uint64_t dd_uncompressed_bytes;
1449 } mdb_dsl_dir_phys_t;
1450 
1451 typedef struct mdb_vdev {
1452         uintptr_t vdev_parent;
1453         uintptr_t vdev_ms;
1454         uint64_t vdev_ms_count;
1455         vdev_stat_t vdev_stat;
1456 } mdb_vdev_t;
1457 














1458 typedef struct mdb_metaslab {
1459         space_map_t ms_allocmap[TXG_SIZE];
1460         space_map_t ms_freemap[TXG_SIZE];
1461         space_map_t ms_map;
1462         space_map_obj_t ms_smo;
1463         space_map_obj_t ms_smo_syncing;
1464 } mdb_metaslab_t;
1465 
1466 typedef struct space_data {
1467         uint64_t ms_allocmap[TXG_SIZE];
1468         uint64_t ms_freemap[TXG_SIZE];
1469         uint64_t ms_map;
1470         uint64_t avail;
1471         uint64_t nowavail;
1472 } space_data_t;
1473 
1474 /* ARGSUSED */
1475 static int
1476 space_cb(uintptr_t addr, const void *unknown, void *arg)
1477 {
1478         space_data_t *sd = arg;
1479         mdb_metaslab_t ms;




1480 
1481         if (GETMEMB(addr, "metaslab", ms_allocmap, ms.ms_allocmap) ||
1482             GETMEMB(addr, "metaslab", ms_freemap, ms.ms_freemap) ||
1483             GETMEMB(addr, "metaslab", ms_map, ms.ms_map) ||
1484             GETMEMB(addr, "metaslab", ms_smo, ms.ms_smo) ||
1485             GETMEMB(addr, "metaslab", ms_smo_syncing, ms.ms_smo_syncing)) {
1486                 return (WALK_ERR);










1487         }
1488 
1489         sd->ms_allocmap[0] += ms.ms_allocmap[0].sm_space;
1490         sd->ms_allocmap[1] += ms.ms_allocmap[1].sm_space;
1491         sd->ms_allocmap[2] += ms.ms_allocmap[2].sm_space;
1492         sd->ms_allocmap[3] += ms.ms_allocmap[3].sm_space;
1493         sd->ms_freemap[0] += ms.ms_freemap[0].sm_space;
1494         sd->ms_freemap[1] += ms.ms_freemap[1].sm_space;
1495         sd->ms_freemap[2] += ms.ms_freemap[2].sm_space;
1496         sd->ms_freemap[3] += ms.ms_freemap[3].sm_space;
1497         sd->ms_map += ms.ms_map.sm_space;
1498         sd->avail += ms.ms_map.sm_size - ms.ms_smo.smo_alloc;
1499         sd->nowavail += ms.ms_map.sm_size - ms.ms_smo_syncing.smo_alloc;
1500 









1501         return (WALK_NEXT);
1502 }
1503 
1504 /*
1505  * ::spa_space [-b]
1506  *
1507  * Given a spa_t, print out it's on-disk space usage and in-core
1508  * estimates of future usage.  If -b is given, print space in bytes.
1509  * Otherwise print in megabytes.
1510  */
1511 /* ARGSUSED */
1512 static int
1513 spa_space(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1514 {
1515         mdb_spa_t spa;
1516         uintptr_t dp_root_dir;
1517         mdb_dsl_dir_t dd;
1518         mdb_dsl_dir_phys_t dsp;
1519         uint64_t children;
1520         uintptr_t childaddr;


1555         mdb_printf("dd_space_towrite = %llu%s %llu%s %llu%s %llu%s\n",
1556             dd.dd_space_towrite[0] >> shift, suffix,
1557             dd.dd_space_towrite[1] >> shift, suffix,
1558             dd.dd_space_towrite[2] >> shift, suffix,
1559             dd.dd_space_towrite[3] >> shift, suffix);
1560 
1561         mdb_printf("dd_phys.dd_used_bytes = %llu%s\n",
1562             dsp.dd_used_bytes >> shift, suffix);
1563         mdb_printf("dd_phys.dd_compressed_bytes = %llu%s\n",
1564             dsp.dd_compressed_bytes >> shift, suffix);
1565         mdb_printf("dd_phys.dd_uncompressed_bytes = %llu%s\n",
1566             dsp.dd_uncompressed_bytes >> shift, suffix);
1567 
1568         bzero(&sd, sizeof (sd));
1569         if (mdb_pwalk("metaslab", space_cb, &sd, addr) != 0) {
1570                 mdb_warn("can't walk metaslabs");
1571                 return (DCMD_ERR);
1572         }
1573 
1574         mdb_printf("ms_allocmap = %llu%s %llu%s %llu%s %llu%s\n",
1575             sd.ms_allocmap[0] >> shift, suffix,
1576             sd.ms_allocmap[1] >> shift, suffix,
1577             sd.ms_allocmap[2] >> shift, suffix,
1578             sd.ms_allocmap[3] >> shift, suffix);
1579         mdb_printf("ms_freemap = %llu%s %llu%s %llu%s %llu%s\n",
1580             sd.ms_freemap[0] >> shift, suffix,
1581             sd.ms_freemap[1] >> shift, suffix,
1582             sd.ms_freemap[2] >> shift, suffix,
1583             sd.ms_freemap[3] >> shift, suffix);
1584         mdb_printf("ms_map = %llu%s\n", sd.ms_map >> shift, suffix);
1585         mdb_printf("last synced avail = %llu%s\n", sd.avail >> shift, suffix);
1586         mdb_printf("current syncing avail = %llu%s\n",
1587             sd.nowavail >> shift, suffix);
1588 
1589         return (DCMD_OK);
1590 }
1591 
1592 typedef struct mdb_spa_aux_vdev {
1593         int sav_count;
1594         uintptr_t sav_vdevs;
1595 } mdb_spa_aux_vdev_t;
1596 
1597 typedef struct mdb_spa_vdevs {
1598         uintptr_t spa_root_vdev;
1599         mdb_spa_aux_vdev_t spa_l2cache;
1600         mdb_spa_aux_vdev_t spa_spares;
1601 } mdb_spa_vdevs_t;
1602 
1603 static int
1604 spa_print_aux(mdb_spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,




1438 } mdb_spa_t;
1439 
1440 typedef struct mdb_dsl_dir {
1441         uintptr_t dd_phys;
1442         int64_t dd_space_towrite[TXG_SIZE];
1443 } mdb_dsl_dir_t;
1444 
1445 typedef struct mdb_dsl_dir_phys {
1446         uint64_t dd_used_bytes;
1447         uint64_t dd_compressed_bytes;
1448         uint64_t dd_uncompressed_bytes;
1449 } mdb_dsl_dir_phys_t;
1450 
1451 typedef struct mdb_vdev {
1452         uintptr_t vdev_parent;
1453         uintptr_t vdev_ms;
1454         uint64_t vdev_ms_count;
1455         vdev_stat_t vdev_stat;
1456 } mdb_vdev_t;
1457 
1458 typedef struct mdb_space_map_phys_t {
1459         uint64_t smp_alloc;
1460 } mdb_space_map_phys_t;
1461 
1462 typedef struct mdb_space_map {
1463         uint64_t sm_size;
1464         uint64_t sm_alloc;
1465         uintptr_t sm_phys;
1466 } mdb_space_map_t;
1467 
1468 typedef struct mdb_range_tree {
1469         uint64_t rt_space;
1470 } mdb_range_tree_t;
1471 
1472 typedef struct mdb_metaslab {
1473         uintptr_t ms_alloctree[TXG_SIZE];
1474         uintptr_t ms_freetree[TXG_SIZE];
1475         uintptr_t ms_tree;
1476         uintptr_t ms_sm;

1477 } mdb_metaslab_t;
1478 
1479 typedef struct space_data {
1480         uint64_t ms_alloctree[TXG_SIZE];
1481         uint64_t ms_freetree[TXG_SIZE];
1482         uint64_t ms_tree;
1483         uint64_t avail;
1484         uint64_t nowavail;
1485 } space_data_t;
1486 
1487 /* ARGSUSED */
1488 static int
1489 space_cb(uintptr_t addr, const void *unknown, void *arg)
1490 {
1491         space_data_t *sd = arg;
1492         mdb_metaslab_t ms;
1493         mdb_range_tree_t rt;
1494         mdb_space_map_t sm;
1495         mdb_space_map_phys_t smp = { 0 };
1496         int i;
1497 
1498         if (mdb_ctf_vread(&ms, "metaslab_t", "mdb_metaslab_t",
1499             addr, 0) == -1)



1500                 return (WALK_ERR);
1501 
1502         for (i = 0; i < TXG_SIZE; i++) {
1503 
1504                 if (mdb_ctf_vread(&rt, "range_tree_t",
1505                     "mdb_range_tree_t", ms.ms_alloctree[i], 0) == -1)
1506                 sd->ms_alloctree[i] += rt.rt_space;
1507 
1508                 if (mdb_ctf_vread(&rt, "range_tree_t",
1509                     "mdb_range_tree_t", ms.ms_freetree[i], 0) == -1)
1510                 sd->ms_freetree[i] += rt.rt_space;
1511         }
1512 
1513         if (mdb_ctf_vread(&rt, "range_tree_t",
1514             "mdb_range_tree_t", ms.ms_tree, 0) == -1 ||
1515             mdb_ctf_vread(&sm, "space_map_t",
1516             "mdb_space_map_t", ms.ms_sm, 0) == -1)
1517                 return (WALK_ERR);






1518 
1519         if (sm.sm_phys != NULL) {
1520                 (void) mdb_ctf_vread(&smp, "space_map_phys_t",
1521                     "mdb_space_map_phys_t", sm.sm_phys, 0);
1522         }
1523 
1524         sd->ms_tree += rt.rt_space;
1525         sd->avail += sm.sm_size - sm.sm_alloc;
1526         sd->nowavail += sm.sm_size - smp.smp_alloc;
1527 
1528         return (WALK_NEXT);
1529 }
1530 
1531 /*
1532  * ::spa_space [-b]
1533  *
1534  * Given a spa_t, print out it's on-disk space usage and in-core
1535  * estimates of future usage.  If -b is given, print space in bytes.
1536  * Otherwise print in megabytes.
1537  */
1538 /* ARGSUSED */
1539 static int
1540 spa_space(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1541 {
1542         mdb_spa_t spa;
1543         uintptr_t dp_root_dir;
1544         mdb_dsl_dir_t dd;
1545         mdb_dsl_dir_phys_t dsp;
1546         uint64_t children;
1547         uintptr_t childaddr;


1582         mdb_printf("dd_space_towrite = %llu%s %llu%s %llu%s %llu%s\n",
1583             dd.dd_space_towrite[0] >> shift, suffix,
1584             dd.dd_space_towrite[1] >> shift, suffix,
1585             dd.dd_space_towrite[2] >> shift, suffix,
1586             dd.dd_space_towrite[3] >> shift, suffix);
1587 
1588         mdb_printf("dd_phys.dd_used_bytes = %llu%s\n",
1589             dsp.dd_used_bytes >> shift, suffix);
1590         mdb_printf("dd_phys.dd_compressed_bytes = %llu%s\n",
1591             dsp.dd_compressed_bytes >> shift, suffix);
1592         mdb_printf("dd_phys.dd_uncompressed_bytes = %llu%s\n",
1593             dsp.dd_uncompressed_bytes >> shift, suffix);
1594 
1595         bzero(&sd, sizeof (sd));
1596         if (mdb_pwalk("metaslab", space_cb, &sd, addr) != 0) {
1597                 mdb_warn("can't walk metaslabs");
1598                 return (DCMD_ERR);
1599         }
1600 
1601         mdb_printf("ms_allocmap = %llu%s %llu%s %llu%s %llu%s\n",
1602             sd.ms_alloctree[0] >> shift, suffix,
1603             sd.ms_alloctree[1] >> shift, suffix,
1604             sd.ms_alloctree[2] >> shift, suffix,
1605             sd.ms_alloctree[3] >> shift, suffix);
1606         mdb_printf("ms_freemap = %llu%s %llu%s %llu%s %llu%s\n",
1607             sd.ms_freetree[0] >> shift, suffix,
1608             sd.ms_freetree[1] >> shift, suffix,
1609             sd.ms_freetree[2] >> shift, suffix,
1610             sd.ms_freetree[3] >> shift, suffix);
1611         mdb_printf("ms_tree = %llu%s\n", sd.ms_tree >> shift, suffix);
1612         mdb_printf("last synced avail = %llu%s\n", sd.avail >> shift, suffix);
1613         mdb_printf("current syncing avail = %llu%s\n",
1614             sd.nowavail >> shift, suffix);
1615 
1616         return (DCMD_OK);
1617 }
1618 
1619 typedef struct mdb_spa_aux_vdev {
1620         int sav_count;
1621         uintptr_t sav_vdevs;
1622 } mdb_spa_aux_vdev_t;
1623 
1624 typedef struct mdb_spa_vdevs {
1625         uintptr_t spa_root_vdev;
1626         mdb_spa_aux_vdev_t spa_l2cache;
1627         mdb_spa_aux_vdev_t spa_spares;
1628 } mdb_spa_vdevs_t;
1629 
1630 static int
1631 spa_print_aux(mdb_spa_aux_vdev_t *sav, uint_t flags, mdb_arg_t *v,