From b481a8bbbf32c26b014518d7c72979c557205918 Mon Sep 17 00:00:00 2001 From: Aditya Gollamudi Date: Fri, 13 Mar 2026 09:53:56 -0700 Subject: [PATCH] Make zpool status dedup table support raw bytes -p output Check if -p flag is enabled, and if so print dedup table with raw bytes. Restructure the logic in zutil_pool to check if -p flag is enabled before printing either the bytes or raw numbers. Calls to print the data for DDT now all use zfs_nicenum_format(). Increased DDT histogram column buffers to 32 bytes to prevent truncation when -p is enabled. Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Signed-off-by: Adi Gollamudi Closes #11626 Closes #17926 --- cmd/zdb/zdb.c | 7 +++--- cmd/zpool/zpool_main.c | 2 +- include/libzutil.h | 3 ++- lib/libzfs/libzfs.abi | 1 + lib/libzutil/zutil_pool.c | 48 ++++++++++++++++++++++++++------------- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 607b83a28..68c9696a8 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -2144,7 +2144,8 @@ dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class) (void) printf("%s: object=%llu\n", name, (u_longlong_t)ddt->ddt_object[type][class]); - zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]); + zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class], + dump_opt['P'] > 0); if (dump_opt['D'] < 4) return; @@ -2221,7 +2222,7 @@ dump_all_ddts(spa_t *spa) if (dump_opt['D'] > 1) { (void) printf("DDT histogram (aggregated over all DDTs):\n"); ddt_get_dedup_histogram(spa, &ddh_total); - zpool_dump_ddt(&dds_total, &ddh_total); + zpool_dump_ddt(&dds_total, &ddh_total, dump_opt['P'] > 0); } dump_dedup_ratio(&dds_total); @@ -8118,7 +8119,7 @@ dump_simulated_ddt(spa_t *spa) (void) printf("Simulated DDT histogram:\n"); - zpool_dump_ddt(&dds_total, &ddh_total); + zpool_dump_ddt(&dds_total, &ddh_total, dump_opt['P'] > 0); dump_dedup_ratio(&dds_total); } diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index abbdc4896..eb76a2135 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -10495,7 +10495,7 @@ print_dedup_stats(zpool_handle_t *zhp, nvlist_t *config, boolean_t literal) (uint64_t **)&dds, &c) == 0); verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, (uint64_t **)&ddh, &c) == 0); - zpool_dump_ddt(dds, ddh); + zpool_dump_ddt(dds, ddh, literal); } #define ST_SIZE 4096 diff --git a/include/libzutil.h b/include/libzutil.h index 59599b0f6..2061a8454 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -167,7 +167,8 @@ _LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t); #define nicenum(num, buf, size) zfs_nicenum(num, buf, size) #define NN_NUMBUF_SZ (6) -_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *); +_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *, + boolean_t parsable); _LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***, uint_t *); _LIBZUTIL_H void fsleep(float sec); diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index 4e3baee52..bed2c7979 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -9871,6 +9871,7 @@ + diff --git a/lib/libzutil/zutil_pool.c b/lib/libzutil/zutil_pool.c index 2aacfa53b..4d52be7ce 100644 --- a/lib/libzutil/zutil_pool.c +++ b/lib/libzutil/zutil_pool.c @@ -34,11 +34,16 @@ #include static void -dump_ddt_stat(const ddt_stat_t *dds, int h) +dump_ddt_stat(const ddt_stat_t *dds, int h, boolean_t parsable) { - char refcnt[6]; - char blocks[6], lsize[6], psize[6], dsize[6]; - char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6]; + char refcnt[32]; + char blocks[32], lsize[32], psize[32], dsize[32]; + char ref_blocks[32], ref_lsize[32], ref_psize[32], ref_dsize[32]; + + enum zfs_nicenum_format count_format = parsable ? + ZFS_NICENUM_RAW : ZFS_NICENUM_1024; + enum zfs_nicenum_format byte_format = parsable ? + ZFS_NICENUM_RAW : ZFS_NICENUM_BYTES; if (dds == NULL || dds->dds_blocks == 0) return; @@ -46,16 +51,26 @@ dump_ddt_stat(const ddt_stat_t *dds, int h) if (h == -1) (void) strcpy(refcnt, "Total"); else - zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt)); + zfs_nicenum_format(1ULL << h, refcnt, sizeof (refcnt), + count_format); - zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks)); - zfs_nicebytes(dds->dds_lsize, lsize, sizeof (lsize)); - zfs_nicebytes(dds->dds_psize, psize, sizeof (psize)); - zfs_nicebytes(dds->dds_dsize, dsize, sizeof (dsize)); - zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks)); - zfs_nicebytes(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize)); - zfs_nicebytes(dds->dds_ref_psize, ref_psize, sizeof (ref_psize)); - zfs_nicebytes(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize)); + + zfs_nicenum_format(dds->dds_blocks, blocks, sizeof (blocks), + count_format); + zfs_nicenum_format(dds->dds_lsize, lsize, sizeof (lsize), + byte_format); + zfs_nicenum_format(dds->dds_psize, psize, sizeof (psize), + byte_format); + zfs_nicenum_format(dds->dds_dsize, dsize, sizeof (dsize), + byte_format); + zfs_nicenum_format(dds->dds_ref_blocks, ref_blocks, + sizeof (ref_blocks), count_format); + zfs_nicenum_format(dds->dds_ref_lsize, ref_lsize, + sizeof (ref_lsize), byte_format); + zfs_nicenum_format(dds->dds_ref_psize, ref_psize, + sizeof (ref_psize), byte_format); + zfs_nicenum_format(dds->dds_ref_dsize, ref_dsize, + sizeof (ref_dsize), byte_format); (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n", refcnt, @@ -67,7 +82,8 @@ dump_ddt_stat(const ddt_stat_t *dds, int h) * Print the DDT histogram and the column totals. */ void -zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh) +zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh, + boolean_t parsable) { int h; @@ -91,9 +107,9 @@ zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh) "------", "-----", "-----", "-----"); for (h = 0; h < 64; h++) - dump_ddt_stat(&ddh->ddh_stat[h], h); + dump_ddt_stat(&ddh->ddh_stat[h], h, parsable); - dump_ddt_stat(dds_total, -1); + dump_ddt_stat(dds_total, -1, parsable); (void) printf("\n"); }